drive_mirror.py 8.2 KB
Newer Older
1
import os
L
Lucas Meneghel Rodrigues 已提交
2
import logging
3

4
from autotest.client.shared import error, utils
5 6 7 8 9 10

from virttest import utils_misc
from virttest import storage
from virttest import qemu_storage
from virttest import nfs

X
Xu Tian 已提交
11 12
from qemu.tests import block_copy

L
Lucas Meneghel Rodrigues 已提交
13

X
Xu Tian 已提交
14
class DriveMirror(block_copy.BlockCopy):
L
Lucas Meneghel Rodrigues 已提交
15

X
Xu Tian 已提交
16 17 18 19 20 21
    """
    base class for block mirror tests;
    """

    def __init__(self, test, params, env, tag):
        super(DriveMirror, self).__init__(test, params, env, tag)
22
        self.target_image = self.get_target_image()
X
Xu Tian 已提交
23 24 25 26 27

    def parser_test_args(self):
        """
        paraser test args and set default value;
        """
28 29 30 31 32
        default_params = {"create_mode": "absolute-path",
                          "reopen_timeout": 60,
                          "full_copy": "full",
                          "check_event": "no"}
        self.default_params.update(default_params)
X
Xu Tian 已提交
33
        params = super(DriveMirror, self).parser_test_args()
34
        if params["block_mirror_cmd"].startswith("__"):
X
Xu Tian 已提交
35
            params["full_copy"] = (params["full_copy"] == "full")
36 37 38 39
        params = params.object_params(params["target_image"])
        if params.get("image_type") == "iscsi":
            params.setdefault("host_setup_flag", 2)
            params["host_setup_flag"] = int(params["host_setup_flag"])
X
Xu Tian 已提交
40 41
        return params

42 43
    def get_target_image(self):
        params = self.parser_test_args()
44 45
        target_image = storage.get_image_filename(params, self.data_dir)
        if params.get("image_type") == "nfs":
46 47
            image = nfs.Nfs(params)
            image.setup()
48 49 50 51 52 53 54
            utils_misc.wait_for(lambda: os.path.ismount(image.mount_dir),
                                timeout=30)
        elif params.get("image_type") == "iscsi":
            image = qemu_storage.Iscsidev(params, self.data_dir,
                                          params["target_image"])
            return image.setup()

55 56
        if (params["create_mode"] == "existing" and
                not os.path.exists(target_image)):
57 58 59 60
            image = qemu_storage.QemuImg(params, self.data_dir,
                                         params["target_image"])
            image.create(params)

61 62
        return target_image

63 64 65 66 67
    def get_device(self):
        params = super(DriveMirror, self).parser_test_args()
        image_file = storage.get_image_filename(params, self.data_dir)
        return self.vm.get_block({"file": image_file})

V
vivianQizhu 已提交
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
    @error.context_aware
    def check_granularity(self):
        """
        Check granularity value as set.
        """
        device_id = self.get_device()
        info = self.vm.monitor.info_block().get(device_id)
        if "granularity" in self.params:
            target_gran = int(self.params["granularity"])
            dirty_bitmap = info.get("dirty-bitmaps", "0")
            granularity = int(dirty_bitmap[0].get("granularity", "0"))
            if granularity != target_gran:
                raise error.TestFail(
                    "Granularity unmatched. Target is %d, result is %d" %
                    (target_gran, granularity))

    @error.context_aware
    def check_node_name(self):
        """
        Check node name as set, after block job complete.
        """
        device_id = self.vm.get_block({"file": self.target_image})
        info = self.vm.monitor.info_block().get(device_id)
        if "node_name" in self.params:
            node_name_exp = self.params["node_name"]
            node_name = info.get("node-name", "")
            if node_name != node_name_exp:
                raise error.TestFail(
                    "node-name is: %s, while set value is: %s" %
                    (node_name, node_name_exp))

X
Xu Tian 已提交
99 100 101 102 103 104
    @error.context_aware
    def start(self):
        """
        start block device mirroring job;
        """
        params = self.parser_test_args()
105 106 107
        target_image = self.target_image
        device = self.device
        default_speed = params["default_speed"]
108
        target_format = params["image_format"]
109 110
        create_mode = params["create_mode"]
        full_copy = params["full_copy"]
V
vivianQizhu 已提交
111 112 113 114 115 116 117 118 119
        args = {"mode": create_mode, "speed": default_speed,
                "format": target_format}
        if 'granularity' and 'buf_count' in params:
            granularity = int(params["granularity"])
            buf_size = granularity * int(params["buf_count"])
            args.update({"granularity": granularity,
                         "buf-size": buf_size})
        if 'node_name' in params:
            args.update({"node-name": params.get("node_name")})
120
        error.context("Start to mirror block device", logging.info)
V
vivianQizhu 已提交
121 122
        self.vm.block_mirror(device, target_image, full_copy,
                             **args)
123
        if not self.get_status():
124
            raise error.TestFail("No active mirroring job found")
125 126
        if params.get("image_type") != "iscsi":
            self.trash_files.append(target_image)
X
Xu Tian 已提交
127 128 129 130 131 132 133 134

    @error.context_aware
    def reopen(self):
        """
        reopen target image, then check if image file of the device is
        target images;
        """
        params = self.parser_test_args()
135
        target_format = params["image_format"]
136
        timeout = params["reopen_timeout"]
X
Xu Tian 已提交
137 138

        def is_opened():
139
            device = self.vm.get_block({"file": self.target_image})
X
Xu Tian 已提交
140 141 142
            ret = (device == self.device)
            if self.vm.monitor.protocol == "qmp":
                ret &= bool(self.vm.monitor.get_event("BLOCK_JOB_COMPLETED"))
L
Lucas Meneghel Rodrigues 已提交
143
            return ret
X
Xu Tian 已提交
144 145 146

        error.context("reopen new target image", logging.info)
        if self.vm.monitor.protocol == "qmp":
147 148 149
            self.vm.monitor.clear_event("BLOCK_JOB_COMPLETED")
        self.vm.block_reopen(self.device, self.target_image, target_format)
        opened = utils_misc.wait_for(is_opened, first=3.0, timeout=timeout)
X
Xu Tian 已提交
150
        if not opened:
151
            msg = "Target image not used,wait timeout in %ss" % timeout
X
Xu Tian 已提交
152 153 154 155 156 157 158 159
            raise error.TestFail(msg)

    def is_steady(self):
        """
        check block device mirroring job is steady status or not;
        """
        params = self.parser_test_args()
        info = self.get_status()
160
        ret = bool(info and info["len"] == info["offset"])
X
Xu Tian 已提交
161
        if self.vm.monitor.protocol == "qmp":
X
Xu Tian 已提交
162
            if params.get("check_event", "no") == "yes":
X
Xu Tian 已提交
163 164 165 166 167 168 169 170 171 172
                ret &= bool(self.vm.monitor.get_event("BLOCK_JOB_READY"))
        return ret

    def wait_for_steady(self):
        """
        check block device mirroring status, utils timeout; if still not go
        into steady status, raise TestFail exception;
        """
        params = self.parser_test_args()
        timeout = params.get("wait_timeout")
173 174
        if self.vm.monitor.protocol == "qmp":
            self.vm.monitor.clear_event("BLOCK_JOB_READY")
175 176
        steady = utils_misc.wait_for(self.is_steady, first=3.0,
                                     step=3.0, timeout=timeout)
X
Xu Tian 已提交
177
        if not steady:
178
            raise error.TestFail("Wait mirroring job ready "
X
Xu Tian 已提交
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
                                 "timeout in %ss" % timeout)

    def action_before_steady(self):
        """
        run steps before job in steady status;
        """
        return self.do_steps("before_steady")

    def action_when_steady(self):
        """
        run steps when job in steady status;
        """
        self.wait_for_steady()
        return self.do_steps("when_steady")

    def action_after_reopen(self):
        """
        run steps after reopened new target image;
        """
        return self.do_steps("after_reopen")

200
    def clean(self):
201
        super(DriveMirror, self).clean()
202
        params = self.parser_test_args()
203 204 205 206 207 208 209 210 211 212 213
        if params.get("image_type") == "iscsi":
            params["host_setup_flag"] = int(params["host_setup_flag"])
            qemu_img = utils_misc.get_qemu_img_binary(self.params)
            # Reformat it to avoid impact other test
            cmd = "%s create -f %s %s %s" % (qemu_img,
                                             params["image_format"],
                                             self.target_image,
                                             params["image_size"])
            utils.system(cmd)
            image = qemu_storage.Iscsidev(params, self.data_dir,
                                          params["target_image"])
214
            image.cleanup()
215
        elif params.get("image_type") == "nfs":
216 217 218
            image = nfs.Nfs(params)
            image.cleanup()

L
Lucas Meneghel Rodrigues 已提交
219

220
def run(test, params, env):
X
Xu Tian 已提交
221
    pass