def run(test, params, env): """ 1. convert image with both default cache mode. 2. check strace output that `O_DIRECT` is off for `open`. 3. convert image with cache mode `none` for both source and dest images. 4. check strace output that `O_DIRECT` is on for `open`. """ find_strace() root_dir = data_dir.get_data_dir() strace_events = params["strace_event"].split() image = params["images"] image_params = params.object_params(image) image = qemu_storage.QemuImg(image_params, root_dir, image) convert_target1, convert_target2 = params["convert_target"].split() strace_output_file = os.path.join(test.debugdir, "convert_to_%s.log" % convert_target1) image_params["convert_target"] = convert_target1 logging.debug("Convert image from %s to %s, strace log: %s", image.tag, convert_target1, strace_output_file) with strace(image, strace_events, strace_output_file): fail_on((process.CmdError, ))(image.convert)(image_params, root_dir) convert_target1_filename = storage.get_image_filename( params.object_params(convert_target1), root_dir) fail_msg = "'O_DIRECT' is presented in system calls %s" % strace_events if check_flag(strace_output_file, image.image_filename, "O_DIRECT"): test.fail(fail_msg) if check_flag(strace_output_file, convert_target1_filename, "O_DIRECT"): test.fail(fail_msg) strace_output_file = os.path.join(test.debugdir, "convert_to_%s.log" % convert_target2) image_params["convert_target"] = convert_target2 logging.debug(("Convert image from %s to %s with cache mode " "'none', strace log: %s"), image.tag, convert_target2, strace_output_file) with strace(image, strace_events, strace_output_file): fail_on((process.CmdError, ))(image.convert)(image_params, root_dir, cache_mode="none", source_cache_mode="none") convert_target2_filename = storage.get_image_filename( params.object_params(convert_target2), root_dir) fail_msg = "'O_DIRECT' is not presented in system calls %s" % strace_events if not check_flag(strace_output_file, image.image_filename, "O_DIRECT"): test.fail(fail_msg) if not check_flag(strace_output_file, convert_target2_filename, "O_DIRECT"): test.fail(fail_msg) params["images"] += params["convert_target"]
def _action_after_fsfreeze(self, *args): error.context("Run live snapshot for guest.", logging.info) image1 = self.params.get("image", "image1") image_params = self.params.object_params(image1) sn_params = image_params.copy() sn_params["image_name"] += "-snapshot" sn_file = storage.get_image_filename(sn_params, data_dir.get_data_dir()) base_file = storage.get_image_filename(image_params, data_dir.get_data_dir()) snapshot_format = image_params["image_format"] self.vm.live_snapshot(base_file, sn_file, snapshot_format)
def get_target_image(self): params = self.parser_test_args() t_params = {} t_params["image_name"] = params["target_image"] t_params["image_format"] = params["target_format"] target_image = storage.get_image_filename(t_params, self.data_dir) return target_image
def _get_image_meta(image, params, root_dir): """Retrieve image meta dict.""" meta = collections.OrderedDict() meta["file"] = collections.OrderedDict() filename = storage.get_image_filename(params, root_dir) meta_file = filename_to_file_opts(filename) meta["file"].update(meta_file) image_format = params.get("image_format", "qcow2") meta["driver"] = image_format secret = storage.ImageSecret.image_secret_define_by_params(image, params) if image_format == "luks": meta["key-secret"] = secret.aid image_encryption = params.get("image_encryption", "off") if image_format == "qcow2" and image_encryption == "luks": meta["encrypt.key-secret"] = secret.aid image_access = storage.ImageAccessInfo.access_info_define_by_params( image, params) if image_access is not None: if image_access.auth is not None: if image_access.storage_type == 'ceph': # qemu-img needs secret object only for ceph access meta['file']['password-secret'] = image_access.auth.aid return meta
def find_image(image_name): """ Find the path of the iamge. """ image_params = params.object_params(image_name) o = storage.get_image_filename(image_params, data_dir.get_data_dir()) return o
def run_qemu_img(test, params, env): """ 'qemu-img' functions test: 1) Judge what subcommand is going to be tested 2) Run subcommand test @param test: kvm test object @param params: Dictionary with the test parameters @param env: Dictionary with test environment. """ cmd = utils_misc.get_path(test.bindir, params.get("qemu_img_binary")) if not os.path.exists(cmd): raise error.TestError("Binary of 'qemu-img' not found") image_format = params.get("image_format") image_size = params.get("image_size", "10G") image_name = storage.get_image_filename(params, test.bindir) def _check(cmd, img): """ Simple 'qemu-img check' function implementation. @param cmd: qemu-img base command. @param img: image to be checked """ cmd += " check %s" % img logging.info("Checking image '%s'...", img) try: output = utils.system_output(cmd) except error.CmdError, e: if "does not support checks" in str(e): return (True, "") else: return (False, str(e)) return (True, output)
def verify_info(self, params=None): """ verify option is applied to image file correctly """ error_context.context("verify option of converted image", logging.info) image_filename = storage.get_image_filename(params, self.data_dir) info = utils_test.get_image_info(image_filename) avalue = evalue = "" for option in params.objects("option_verified"): avalue = info.get(option) if option == "format": evalue = params.get("image_format") elif option == "lcounts": if params.get("lazy_refcounts") == "on": evalue = "true" elif params.get("lazy_refcounts") == "off": evalue = "false" elif option == "csize": csize = params.get("image_cluster_size") evalue = int(float(utils_misc.normalize_data_size(csize, "B"))) elif option == "sparse_size": if info.get("dsize") < info.get("vsize"): avalue = info.get("dsize") evalue = info.get("vsize") elif option == "compat": evalue = params.get("qcow2_compatible") else: evalue = params.get(option) if avalue is not None and avalue != evalue: msg = "Get wrong %s from image %s!" % (option, image_filename) msg += "Expect: %s, actual: %s" % (evalue, avalue) self.test.fail(msg)
def verify_info(self, params=None): """ verify option is applied to image file correctly """ error_context.context("verify option of converted image", logging.info) image_filename = storage.get_image_filename(params, self.data_dir) info = utils_test.get_image_info(image_filename) avalue = evalue = "" for option in params.objects("option_verified"): avalue = info.get(option) if option == "format": evalue = params.get("image_format") elif option == "lcounts": if params.get("lazy_refcounts") == "on": evalue = "true" elif params.get("lazy_refcounts") == "off": evalue = "false" elif option == "csize": csize = params.get("cluster_size") evalue = int(float(utils_misc.normalize_data_size(csize, "B"))) elif option == "sparse_size": if info.get("dsize") < info.get("vsize"): avalue = info.get("dsize") evalue = info.get("vsize") else: evalue = params.get(option) if avalue is not None and avalue != evalue: msg = "Get wrong %s from image %s!" % (option, image_filename) msg += "Expect: %s, actual: %s" % (evalue, avalue) self.test.fail(msg)
def get_base_image(self): """ Get base image. """ base_file = storage.get_image_filename(self.params, data_dir.get_data_dir()) return self.vm.get_block({"file": base_file})
def run_qemu_img(test, params, env): """ 'qemu-img' functions test: 1) Judge what subcommand is going to be tested 2) Run subcommand test @param test: kvm test object @param params: Dictionary with the test parameters @param env: Dictionary with test environment. """ cmd = utils_misc.get_path(test.bindir, params.get("qemu_img_binary")) if not os.path.exists(cmd): raise error.TestError("Binary of 'qemu-img' not found") image_format = params.get("image_format") image_size = params.get("image_size", "10G") image_name = storage.get_image_filename(params, data_dir.get_data_dir()) def _check(cmd, img): """ Simple 'qemu-img check' function implementation. @param cmd: qemu-img base command. @param img: image to be checked """ cmd += " check %s" % img logging.info("Checking image '%s'...", img) try: output = utils.system_output(cmd) except error.CmdError, e: if "does not support checks" in str(e): return (True, "") else: return (False, str(e)) return (True, output)
def get_node_name(image_tag): """ Get the node name. """ img_params = params.object_params(image_tag) file = storage.get_image_filename(img_params, data_dir.get_data_dir()) for block in vm.monitor.info("block"): if file == block['inserted']['file']: return block['inserted']['node-name']
def rebase_test(cmd): """ Subcommand 'qemu-img rebase' test Change the backing file of a snapshot image in "unsafe mode": Assume the previous backing file had missed and we just have to change reference of snapshot to new one. After change the backing file of a snapshot image in unsafe mode, the snapshot should work still. :param cmd: qemu-img base command. """ if 'rebase' not in process.system_output(cmd + ' --help', ignore_status=True).decode(): test.cancel("Current kvm user space version does not" " support 'rebase' subcommand") sn_fmt = params.get("snapshot_format", "qcow2") sn1 = params["image_name_snapshot1"] sn1 = _get_image_filename(sn1, enable_gluster, img_fmt=sn_fmt) base_img = storage.get_image_filename(params, data_dir.get_data_dir()) _create(cmd, sn1, sn_fmt, base_img=base_img, base_img_fmt=image_format) rebase_mode = params.get("rebase_mode", "safe") if rebase_mode == "safe": # Boot snapshot1 image before create snapshot2 img_format = sn1.split('.')[-1] img_name = ".".join(sn1.split('.')[:-1]) _boot(img_name, img_format) # Create snapshot2 based on snapshot1 sn2 = params["image_name_snapshot2"] sn2 = _get_image_filename(sn2, enable_gluster, img_fmt=sn_fmt) _create(cmd, sn2, sn_fmt, base_img=sn1, base_img_fmt=sn_fmt) # Boot snapshot2 image before rebase img_format = sn2.split('.')[-1] img_name = ".".join(sn2.split('.')[:-1]) _boot(img_name, img_format) if rebase_mode == "unsafe": remove(sn1) _rebase(cmd, sn2, base_img, image_format, mode=rebase_mode) # Boot snapshot image after rebase img_format = sn2.split('.')[-1] img_name = ".".join(sn2.split('.')[:-1]) _boot(img_name, img_format) # Check sn2's format and backing_file actual_base_img = _info(cmd, sn2, "backing file") base_img_name = os.path.basename(base_img) if base_img_name not in actual_base_img: test.fail("After rebase the backing_file of 'sn2' is " "'%s' which is not expected as '%s'" % (actual_base_img, base_img_name)) status, output = _check(cmd, sn2) if not status: test.fail("Check image '%s' failed after rebase;" "got error: %s" % (sn2, output)) remove(sn2) remove(sn1)
def run_block_stream_with_stress(test, params, env): """ block_stream_with_stress test: 1). boot guest 2). make guest under heavyload status 3). create live snpshot file and start block stream job 4). wait for it done correctly @param test: Kvm test object @param params: Dictionary with the test parameters @param env: Dictionary with test environment. """ vm = env.get_vm(params["main_vm"]) vm.verify_alive() timeout = int(params.get("login_timeout", 360)) session = vm.wait_for_login(timeout=timeout) image_filename = storage.get_image_filename(params, data_dir.get_data_dir()) device_id = vm.get_block({"file": image_filename}) snapshot_file = os.path.splitext(image_filename)[0] + "-snp" sub_test = params.get("pre_test") start_cmd = params.get("start_cmd") def is_job_done(): """ Query block job status to check is job finished """ job = vm.monitor.query_block_job(device_id) if job: processed = float(job["offset"]) / job["len"] * 100 logging.debug("%s, rocessed: %.2f" % (job["type"], processed)) return False logging.info("block stream job done") return True try: utils_test.run_virt_sub_test(test, params, env, sub_type=sub_test) error.context("Heavy load in guest ...", logging.info) if start_cmd.startswith("stress"): cpu = int(params.get("smp", 1)) mem = int(params.get("mem", 1024)) start_cmd = start_cmd.format(cpu=cpu, vm=cpu * 2, mem=(mem - 512) / cpu) session.sendline(start_cmd) error.context("Creating live snapshot", logging.info) if vm.monitor.live_snapshot(device_id, snapshot_file): raise error.TestFail("Fail to create live snapshot") error.context("Start block device stream job", logging.info) if vm.monitor.block_stream(device_id): raise error.TestFail("Fail to start block stream job") if not utils_misc.wait_for(is_job_done, timeout=int(params.get("job_timeout", 2400)), text="wait job done, it will take long time"): raise error.TestFail("Wait job finish timeout") finally: if session: session.close() if os.path.isfile(snapshot_file): os.remove(snapshot_file)
def get_device(self): """ according configuration get target device ID; """ image_file = storage.get_image_filename(self.parser_test_args(), self.data_dir) logging.info("image filename: %s" % image_file) return self.vm.get_block({"file": image_file})
def get_device(self): """ according configuration get target device ID; """ root_dir = self.data_dir params = self.parser_test_args() image_file = storage.get_image_filename(params, root_dir) device = self.vm.get_block({"file": image_file}) return device
def run(test, params, env): """ live_snapshot_base test: 1). Boot up guest 2). Create a file on host and record md5 3). Copy the file to guest 3). Create live snapshot 4). Copy the file from guest,then check md5 :param test: Kvm test object :param params: Dictionary with the test parameters :param env: Dictionary with test environment. """ vm = env.get_vm(params["main_vm"]) vm.verify_alive() timeout = int(params.get("login_timeout", 3600)) session = vm.wait_for_login(timeout=timeout) dd_timeout = params.get("dd_timeoout", 600) copy_timeout = params.get("copy_timeoout", 600) base_file = storage.get_image_filename(params, data_dir.get_data_dir()) device = vm.get_block({"file": base_file}) snapshot_file = "images/%s" % params.get("snapshot_name") snapshot_file = utils_misc.get_path(data_dir.get_data_dir(), snapshot_file) snapshot_format = params.get("snapshot_format", "qcow2") tmp_name = utils_misc.generate_random_string(5) src = dst = "/tmp/%s" % tmp_name if params.get("os_type") != "linux": dst = "c:\\users\\public\\%s" % tmp_name try: error_context.context("create file on host, copy it to guest", logging.info) cmd = params.get("dd_cmd") % src process.system(cmd, timeout=dd_timeout, shell=True) md5 = crypto.hash_file(src, algorithm="md5") vm.copy_files_to(src, dst, timeout=copy_timeout) process.system("rm -f %s" % src) error_context.context("create live snapshot", logging.info) if vm.live_snapshot(base_file, snapshot_file, snapshot_format) != device: test.fail("Fail to create snapshot") backing_file = vm.monitor.get_backingfile(device) if backing_file != base_file: logging.error( "backing file: %s, base file: %s", backing_file, base_file) test.fail("Got incorrect backing file") error_context.context("copy file to host, check content not changed", logging.info) vm.copy_files_from(dst, src, timeout=copy_timeout) if md5 and (md5 != crypto.hash_file(src, algorithm="md5")): test.fail("diff md5 before/after create snapshot") session.cmd(params.get("alive_check_cmd", "dir")) finally: if session: session.close() process.system("rm -f %s %s" % (snapshot_file, src))
def run(test, params, env): """ live_snapshot_base test: 1). Boot up guest 2). Create a file on host and record md5 3). Copy the file to guest 3). Create live snapshot 4). Copy the file from guest,then check md5 :param test: Kvm test object :param params: Dictionary with the test parameters :param env: Dictionary with test environment. """ vm = env.get_vm(params["main_vm"]) vm.verify_alive() timeout = int(params.get("login_timeout", 3600)) session = vm.wait_for_login(timeout=timeout) dd_timeout = params.get("dd_timeoout", 600) copy_timeout = params.get("copy_timeoout", 600) base_file = storage.get_image_filename(params, data_dir.get_data_dir()) device = vm.get_block({"file": base_file}) snapshot_file = "images/%s" % params.get("snapshot_file") snapshot_file = utils_misc.get_path(data_dir.get_data_dir(), snapshot_file) snapshot_format = params.get("snapshot_format", "qcow2") tmp_name = utils_misc.generate_random_string(5) src = dst = "/tmp/%s" % tmp_name if params.get("os_type") != "linux": dst = "c:\\users\\public\\%s" % tmp_name try: error_context.context("create file on host, copy it to guest", logging.info) cmd = params.get("dd_cmd") % src process.system(cmd, timeout=dd_timeout, shell=True) md5 = crypto.hash_file(src, algorithm="md5") vm.copy_files_to(src, dst, timeout=copy_timeout) process.system("rm -f %s" % src) error_context.context("create live snapshot", logging.info) if vm.live_snapshot(base_file, snapshot_file, snapshot_format) != device: test.fail("Fail to create snapshot") backing_file = vm.monitor.get_backingfile(device) if backing_file != base_file: logging.error("backing file: %s, base file: %s", backing_file, base_file) test.fail("Got incorrect backing file") error_context.context("copy file to host, check content not changed", logging.info) vm.copy_files_from(dst, src, timeout=copy_timeout) if md5 and (md5 != crypto.hash_file(src, algorithm="md5")): test.fail("diff md5 before/after create snapshot") session.cmd(params.get("alive_check_cmd", "dir")) finally: if session: session.close() process.system("rm -f %s %s" % (snapshot_file, src))
def qemu_img_check(): """ Check guest disk image, and backup image when error occured """ params["backup_image_on_check_error"] = 'yes' base_dir = data_dir.get_data_dir() image_name = storage.get_image_filename(params, base_dir) image = qemu_storage.QemuImg(params, base_dir, image_name) image.check_image(params, base_dir)
def find_image(image_name): """ Find the path of the iamge. :param image_name: name of image. :return mage_filename: filename of image. """ image_params = params.object_params(image_name) image_filename = storage.get_image_filename(image_params, data_dir.get_data_dir()) return image_filename
def _prepare(): logging.info("Clone system image with qemu-img") result = qemu_storage.QemuImg( params, None, params['images'].split()[0]).dd(output=storage.get_image_filename( params.object_params(params["local_image_tag"]), data_dir.get_data_dir()), bs=1024 * 1024) if result.exit_status != 0: test.fail('Failed to clone the system image, error: %s' % result.stderr.decode())
def get_image_repr(image, params, root_dir, representation=None): """Get image representation.""" mapping = {"filename": lambda i, p, r: storage.get_image_filename(p, r), "json": get_image_json, "opts": get_image_opts} func = mapping.get(representation, None) if func is None: if storage.ImageSecret.image_secret_define_by_params(image, params): func = mapping["json"] else: func = mapping["filename"] return func(image, params, root_dir)
def rebase_test(cmd): """ Subcommand 'qemu-img rebase' test Change the backing file of a snapshot image in "unsafe mode": Assume the previous backing file had missed and we just have to change reference of snapshot to new one. After change the backing file of a snapshot image in unsafe mode, the snapshot should work still. :param cmd: qemu-img base command. """ if not 'rebase' in utils.system_output(cmd + ' --help', ignore_status=True): raise error.TestNAError("Current kvm user space version does not" " support 'rebase' subcommand") sn_fmt = params.get("snapshot_format", "qcow2") sn1 = params["image_name_snapshot1"] sn1 = utils_misc.get_path(data_dir.get_data_dir(), sn1) + ".%s" % sn_fmt base_img = storage.get_image_filename(params, data_dir.get_data_dir()) _create(cmd, sn1, sn_fmt, base_img=base_img, base_img_fmt=image_format) # Create snapshot2 based on snapshot1 sn2 = params["image_name_snapshot2"] sn2 = utils_misc.get_path(data_dir.get_data_dir(), sn2) + ".%s" % sn_fmt _create(cmd, sn2, sn_fmt, base_img=sn1, base_img_fmt=sn_fmt) rebase_mode = params.get("rebase_mode") if rebase_mode == "unsafe": os.remove(sn1) _rebase(cmd, sn2, base_img, image_format, mode=rebase_mode) # Boot snapshot image after rebase img_name, img_format = sn2.split('.') _boot(img_name, img_format) # Check sn2's format and backing_file actual_base_img = _info(cmd, sn2, "backing file") base_img_name = os.path.basename(base_img) if not base_img_name in actual_base_img: raise error.TestFail("After rebase the backing_file of 'sn2' is " "'%s' which is not expected as '%s'" % (actual_base_img, base_img_name)) status, output = _check(cmd, sn2) if not status: raise error.TestFail("Check image '%s' failed after rebase;" "got error: %s" % (sn2, output)) try: os.remove(sn2) os.remove(sn1) except Exception: pass
def rebase_test(cmd): """ Subcommand 'qemu-img rebase' test Change the backing file of a snapshot image in "unsafe mode": Assume the previous backing file had missed and we just have to change reference of snapshot to new one. After change the backing file of a snapshot image in unsafe mode, the snapshot should work still. :param cmd: qemu-img base command. """ if not 'rebase' in utils.system_output(cmd + ' --help', ignore_status=True): raise error.TestNAError("Current kvm user space version does not" " support 'rebase' subcommand") sn_fmt = params.get("snapshot_format", "qcow2") sn1 = params["image_name_snapshot1"] sn1 = utils_misc.get_path( data_dir.get_data_dir(), sn1) + ".%s" % sn_fmt base_img = storage.get_image_filename(params, data_dir.get_data_dir()) _create(cmd, sn1, sn_fmt, base_img=base_img, base_img_fmt=image_format) # Create snapshot2 based on snapshot1 sn2 = params["image_name_snapshot2"] sn2 = utils_misc.get_path( data_dir.get_data_dir(), sn2) + ".%s" % sn_fmt _create(cmd, sn2, sn_fmt, base_img=sn1, base_img_fmt=sn_fmt) rebase_mode = params.get("rebase_mode") if rebase_mode == "unsafe": os.remove(sn1) _rebase(cmd, sn2, base_img, image_format, mode=rebase_mode) # Boot snapshot image after rebase img_name, img_format = sn2.split('.') _boot(img_name, img_format) # Check sn2's format and backing_file actual_base_img = _info(cmd, sn2, "backing file") base_img_name = os.path.basename(base_img) if not base_img_name in actual_base_img: raise error.TestFail("After rebase the backing_file of 'sn2' is " "'%s' which is not expected as '%s'" % (actual_base_img, base_img_name)) status, output = _check(cmd, sn2) if not status: raise error.TestFail("Check image '%s' failed after rebase;" "got error: %s" % (sn2, output)) try: os.remove(sn2) os.remove(sn1) except Exception: pass
def run_image_copy(test, params, env): """ Copy guest images from nfs server. 1) Mount the NFS share directory 2) Check the existence of source image 3) If it exists, copy the image from NFS :param test: kvm test object :param params: Dictionary with the test parameters :param env: Dictionary with test environment. """ vm = env.get_vm(params["main_vm"]) if vm is not None: vm.destroy() src = params.get('images_good') asset_name = '%s' % (os.path.split(params['image_name'])[1]) image = '%s.%s' % (params['image_name'], params['image_format']) dst_path = storage.get_image_filename(params, data_dir.get_data_dir()) image_dir = os.path.dirname(dst_path) if params.get("rename_error_image", "no") == "yes": error_image = os.path.basename(params['image_name']) + "-error" error_image += '.' + params['image_format'] error_dst_path = os.path.join(image_dir, error_image) mv_cmd = "/bin/mv %s %s" % (dst_path, error_dst_path) utils.system(mv_cmd, timeout=360, ignore_status=True) if src: mount_dest_dir = params.get('dst_dir', '/mnt/images') if not os.path.exists(mount_dest_dir): try: os.makedirs(mount_dest_dir) except OSError, err: logging.warning('mkdir %s error:\n%s', mount_dest_dir, err) if not os.path.exists(mount_dest_dir): raise error.TestError('Failed to create NFS share dir %s' % mount_dest_dir) error.context("Mount the NFS share directory") if not utils_misc.mount(src, mount_dest_dir, 'nfs', 'ro'): raise error.TestError('Could not mount NFS share %s to %s' % (src, mount_dest_dir)) error.context("Check the existence of source image") src_path = '%s/%s.%s' % (mount_dest_dir, asset_name, params['image_format']) asset_info = virttest.asset.get_file_asset(asset_name, src_path, dst_path) if asset_info is None: raise error.TestError('Could not find %s' % image)
def parse_params(vm, params): """Parse params for bitmap.""" bitmaps = [] for bitmap in params.get("bitmaps", "").split(): bitmap_params = params.object_params(bitmap) bitmap_params.setdefault("bitmap_name", bitmap) target_image = bitmap_params.get("target_image") target_image_params = params.object_params(target_image) target_image_filename = storage.get_image_filename( target_image_params, data_dir.get_data_dir()) target_device = vm.get_block({"file": target_image_filename}) bitmap_params["target_device"] = target_device bitmaps.append(bitmap_params) return bitmaps
def convert(self, t_params={}): """ create image file from one format to another format """ error.context("convert image file", logging.info) params = self.params.object_params(self.tag) params.update(t_params) cache_mode = params.get("cache_mode") super(ConvertTest, self).convert(params, self.data_dir, cache_mode) params["image_name"] = params["convert_name"] params["image_format"] = params["convert_format"] converted = storage.get_image_filename(params, self.data_dir) utils.run("sync") self.trash.append(converted) return params
def create_snapshot(self, t_params={}): """ create snapshot image file """ error.context("create snapshot image") params = self.params.object_params(self.tag) params.update(t_params) if len(params.get("image_chain", "").split()) < 2: return dict() snapshot = storage.get_image_filename(params, self.data_dir) if os.path.exists(snapshot): utils.run("rm -f %s" % snapshot) super(QemuImgTest, self).create(params) self.trash.append(snapshot) return params
def create_snapshot(self, t_params=None): """ create snapshot image file """ error_context.context("create snapshot image") params = self.params.object_params(self.tag) if t_params: params.update(t_params) if len(params.get("image_chain", "").split()) < 2: return {} snapshot = storage.get_image_filename(params, self.data_dir) storage.file_remove(params, snapshot) super(QemuImgTest, self).create(params) self.trash.append(snapshot) return params
def convert(self, t_params=None): """ create image file from one format to another format """ error_context.context("convert image file", logging.info) params = self.params.object_params(self.tag) if t_params: params.update(t_params) cache_mode = params.get("cache_mode") conv = super(ConvertTest, self).convert(params, self.data_dir, cache_mode) params = params.object_params(conv) converted = storage.get_image_filename(params, self.data_dir) process.run("sync") self.trash.append(converted) return params
def _on_resize(obj, msg): logging.info("Receive resize msg:%s", msg) data_image_params = params.object_params("stg0") data_image_size = params.get_numeric("new_image_size_stg0") data_image_filename = storage.get_image_filename( data_image_params, data_dir.get_data_dir()) data_image_dev = vm.get_block({'file': data_image_filename}) args = (None, data_image_size, data_image_dev) vm.monitor.block_resize(*args) time.sleep(2) vm.verify_status("running") guest_cmd_output = session.cmd("lsblk -dn", timeout=60).strip() logging.debug("Guest cmd output: '%s'", guest_cmd_output) obj.send_message("status-req") logging.info("Finish handle on_resize")
def _get_image_meta(image, params, root_dir): """Retrieve image meta dict.""" image_filename = storage.get_image_filename(params, root_dir) image_format = params.get("image_format", "qcow2") image_encryption = params.get("image_encryption", "off") meta = collections.OrderedDict() secret = storage.ImageSecret.image_secret_define_by_params(image, params) if image_format == "qcow2" and image_encryption == "luks": meta["encrypt.key-secret"] = secret.aid meta["driver"] = image_format meta["file"] = collections.OrderedDict() meta["file"]["driver"] = "file" meta["file"]["filename"] = image_filename if image_format == "luks": meta["key-secret"] = secret.aid return meta
def commit_snapshots(self): device = self.params.get("device_tag") device_params = self.params.object_params(device) snapshot_tags = device_params["snapshot_tags"].split() self.device_node = self.get_node_name(device) options = ["base-node", "top-node", "speed", "backing-file"] arguments = self.params.copy_from_keys(options) arguments["base-node"] = self.get_node_name(device) backing_file = self.params.object_params(snapshot_tags[-2]) self.backing_file = storage.get_image_filename(backing_file, data_dir.get_data_dir()) arguments["backing-file"] = self.backing_file arguments["top-node"] = self.get_node_name(snapshot_tags[-2]) device = self.get_node_name(snapshot_tags[-1]) backup_utils.block_commit(self.main_vm, device, **arguments) self.main_vm.destroy()
def _parse_options(self, params): """Build options used for qemu-img amend, create, convert, measure.""" options_mapping = { "preallocated": (None, "preallocation", ("qcow2", "raw", "luks")), "image_cluster_size": (None, "cluster_size", ("qcow2", )), "lazy_refcounts": (None, "lazy_refcounts", ("qcow2", )), "qcow2_compatible": (None, "compat", ("qcow2", )) } image_format = params.get("image_format", "qcow2") options = [] for key, (default, opt_key, support_fmt) in options_mapping.items(): if image_format in support_fmt: value = params.get(key, default) if value is not None: options.append("%s=%s" % (opt_key, value)) if self.encryption_config.key_secret: opts = list(self.encryption_config) opts.remove("base_key_secrets") if image_format == "luks": opts.remove("format") for opt_key in opts: opt_val = getattr(self.encryption_config, opt_key) if opt_val: if image_format == "qcow2": opt_key = "encrypt.%s" % opt_key options.append("%s=%s" % (opt_key.replace("_", "-"), str(opt_val))) access_secret, secret_type = self._get_access_secret_info() if access_secret is not None: if secret_type == 'password': options.append("password-secret=%s" % access_secret.aid) elif secret_type == 'key': options.append("key-secret=%s" % access_secret.aid) image_extra_params = params.get("image_extra_params") if image_extra_params: options.append(image_extra_params.strip(',')) if params.get("has_backing_file") == "yes": backing_param = params.object_params("backing_file") backing_file = storage.get_image_filename(backing_param, self.root_dir) options.append("backing_file=%s" % backing_file) backing_fmt = backing_param.get("image_format") options.append("backing_fmt=%s" % backing_fmt) return options
def create_target_block_device(vm, params, backing_info): """Create target backup device by qemu""" jobs = list() image_dir = data_dir.get_data_dir() random_id = utils_misc.generate_random_id() img_node_name = "img_%s" % random_id dev_node_name = "dev_%s" % random_id image_size = align_image_size(params["image_size"]) filename = storage.get_image_filename(params, image_dir) image_create_options = { "driver": params["image_type"], "filename": filename, "size": 0 } image_add_options = { "driver": params["image_type"], "filename": filename, "node-name": img_node_name } format_image_options = { "driver": params["image_format"], "size": image_size, "file": img_node_name } add_device_options = { "driver": params["image_format"], "file": image_add_options["node-name"], "node-name": dev_node_name } if backing_info: format_image_options.update({ "backing-file": backing_info["backing-file"], "backing-fmt": backing_info["backing-fmt"] }) add_device_options.update({"backing": backing_info["backing"]}) try: jobs += [blockdev_create(vm, image_create_options)] blockdev_add(vm, image_add_options) jobs += [blockdev_create(vm, format_image_options)] blockdev_add(vm, add_device_options) finally: list(map(partial(job_utils.job_dismiss, vm), jobs)) if get_block_node_by_name(vm, dev_node_name): return dev_node_name, filename return None, None
def commit(self, drop=False, cache_mode=None, base=None): """ Commit snapshot to base file """ error_context.context("commit snapshot") cmds = [self.image_cmd, "commit"] if drop: cmds.append("-d") if cache_mode: cmds.extend(["-t", cache_mode]) if base: base_image_filename = storage.get_image_filename( self.params.object_params(base), self.root_dir) cmds.extend(["-b", base_image_filename]) cmds.extend(["-f", self.image_format, self.image_filename]) logging.info("Commit image %s", self.image_filename) process.system(" ".join(cmds))
def get_target_image(self): params = self.parser_test_args() t_params = {} t_params["image_name"] = params["target_image"] t_params["image_format"] = params["target_format"] target_image = storage.get_image_filename(t_params, self.data_dir) if params.get("target_image_type") == "nfs": image = nfs.Nfs(params) image.setup() # sleep 30s to wait nfs ready, it's requried by some rhel6 host time.sleep(30) elif params.get("target_image_type") == "iscsi": image = qemu_storage.Iscsidev(params, self.data_dir, "") target_image = image.setup() if (params["create_mode"] == "existing" and not os.path.exists(target_image)): image = qemu_storage.QemuImg(t_params, self.data_dir, "") image.create(t_params) return target_image
def run(test, params, env): """ Test svirt in virt-install. (1). Init variables. (2). Set selinux on host. (3). Set label of image. (4). run unattended install. (5). clean up. """ # Get general variables. status_error = ('yes' == params.get("status_error", 'no')) host_sestatus = params.get("host_selinux", "enforcing") # Set selinux status on host. backup_sestatus = utils_selinux.get_status() utils_selinux.set_status(host_sestatus) # Set the image label. disk_label = params.get("disk_label", None) vm_name = params.get("main_vm", None) vm_params = params.object_params(vm_name) base_dir = params.get("images_base_dir", data_dir.get_data_dir()) image_filename = storage.get_image_filename(vm_params, base_dir) utils_selinux.set_context_of_file(image_filename, disk_label) try: try: unattended_install.run(test, params, env) # Install completed. if status_error: raise error.TestFail('Test successed in negative case.') except error.CmdError, e: # Install failed. if not status_error: raise error.TestFail("Test failed in positive case." "error: %s" % e) finally: # cleanup utils_selinux.set_status(backup_sestatus) if virsh.domain_exists(vm_name): virsh.remove_domain(vm_name)
def get_target_image(self): params = self.parser_test_args() target_image = storage.get_image_filename(params, self.data_dir) if params.get("image_type") == "nfs": image = nfs.Nfs(params) image.setup() 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() if (params["create_mode"] == "existing" and not os.path.exists(target_image)): image = qemu_storage.QemuImg(params, self.data_dir, params["target_image"]) image.create(params) return target_image
def compare_test(self, t_params): """ Compare images. :param t_params: Dictionary with the test parameters """ for mode in t_params.objects("compare_mode_list"): error_context.context("Compare images in %s mode" % mode, logging.info) cmd_result = None is_strict = ("strict" == mode) image1 = self.image_filename image2 = storage.get_image_filename(t_params, self.data_dir) try: cmd_result = self.compare_images(image1, image2, is_strict) except (exceptions.TestFail, exceptions.TestError) as detail: if not is_strict: raise if is_strict and cmd_result: self.test.fail("images are identical in strict mode")
def guest_listing(options): if options.vt_type == 'lvsb': raise ValueError("No guest types available for lvsb testing") index = 0 LOG.debug("Searched %s for guest images\n", os.path.join(data_dir.get_data_dir(), 'images')) LOG.debug("Available guests in config:\n") guest_name_parser = standalone_test.get_guest_name_parser(options) guest_name_parser.only_filter('i440fx') for params in guest_name_parser.get_dicts(): index += 1 base_dir = params.get("images_base_dir", data_dir.get_data_dir()) image_name = storage.get_image_filename(params, base_dir) name = params['name'] if os.path.isfile(image_name): out = name else: missing = "(missing %s)" % os.path.basename(image_name) out = (name + " " + output.TERM_SUPPORT.warn_header_str(missing)) LOG.debug(out)
def guest_listing(options): """ List available guest os and info about image availability """ if options.vt_type == "lvsb": raise ValueError("No guest types available for lvsb testing") LOG.debug("Using %s for guest images\n", os.path.join(data_dir.get_data_dir(), "images")) LOG.info("Available guests in config:") guest_name_parser = standalone_test.get_guest_name_parser(options) for params in guest_name_parser.get_dicts(): base_dir = params.get("images_base_dir", data_dir.get_data_dir()) image_name = storage.get_image_filename(params, base_dir) name = params["name"] if os.path.isfile(image_name): out = name else: missing = "(missing %s)" % os.path.basename(image_name) out = name + " " + output.TERM_SUPPORT.warn_header_str(missing) LOG.debug(out) LOG.debug("")
def run_qemu_img(test, params, env): """ 'qemu-img' functions test: 1) Judge what subcommand is going to be tested 2) Run subcommand test @param test: QEMU test object @param params: Dictionary with the test parameters @param env: Dictionary with test environment. """ qemu_img_binary = utils_misc.get_qemu_img_binary(params) cmd = qemu_img_binary if not os.path.exists(cmd): raise error.TestError("Binary of 'qemu-img' not found") image_format = params["image_format"] image_size = params.get("image_size", "10G") image_name = storage.get_image_filename(params, data_dir.get_data_dir()) def _check(cmd, img): """ Simple 'qemu-img check' function implementation. @param cmd: qemu-img base command. @param img: image to be checked """ cmd += " check %s" % img error.context("Checking image '%s' by command '%s'" % (img, cmd), logging.info) try: output = utils.system_output(cmd, verbose=False) except error.CmdError, err: if "does not support checks" in str(err): return (True, "") else: return (False, str(err)) return (True, output)
def guest_listing(options, view): term_support = output.TermSupport() if options.vt_type == 'lvsb': raise ValueError("No guest types available for lvsb testing") index = 0 view.notify(event='minor', msg=("Searched %s for guest images\n" % os.path.join(data_dir.get_data_dir(), 'images'))) view.notify(event='minor', msg="Available guests in config:") view.notify(msg='') guest_name_parser = standalone_test.get_guest_name_parser(options) guest_name_parser.only_filter('i440fx') for params in guest_name_parser.get_dicts(): index += 1 base_dir = params.get("images_base_dir", data_dir.get_data_dir()) image_name = storage.get_image_filename(params, base_dir) name = params['name'] if os.path.isfile(image_name): out = name else: out = (name + " " + term_support.warn_header_str("(missing %s)" % os.path.basename(image_name))) view.notify(event='minor', msg=out)
def commit_test(cmd): """ Subcommand 'qemu-img commit' test. 1) Create a overlay file of the qemu harddisk specified by image_name. 2) Start a VM using the overlay file as its harddisk. 3) Touch a file "commit_testfile" in the overlay file, and shutdown the VM. 4) Commit the change to the backing harddisk by executing "qemu-img commit" command. 5) Start the VM using the backing harddisk. 6) Check if the file "commit_testfile" exists. :param cmd: qemu-img base command. """ logging.info("Commit testing started!") image_name = storage.get_image_filename(params, data_dir.get_data_dir()) pre_name = '.'.join(image_name.split('.')[:-1]) image_format = params.get("image_format", "qcow2") overlay_file_name = "%s_overlay.%s" % (pre_name, image_format) file_create_cmd = params.get("file_create_cmd", "touch /commit_testfile") file_info_cmd = params.get("file_info_cmd", "ls / | grep commit_testfile") file_exist_chk_cmd = params.get("file_exist_chk_cmd", "[ -e /commit_testfile ] && echo $?") file_del_cmd = params.get("file_del_cmd", "rm -f /commit_testfile") try: # Remove the existing overlay file if os.path.isfile(overlay_file_name): remove(overlay_file_name) # Create the new overlay file create_cmd = "%s create -b %s -f %s %s" % (cmd, image_name, image_format, overlay_file_name) msg = "Create overlay file by command: %s" % create_cmd error.context(msg, logging.info) try: utils.system(create_cmd, verbose=False) except error.CmdError: raise error.TestFail("Could not create a overlay file!") logging.info("overlay file (%s) created!" % overlay_file_name) # Set the qemu harddisk to the overlay file logging.info( "Original image_name is: %s", params.get('image_name')) params['image_name'] = '.'.join(overlay_file_name.split('.')[:-1]) logging.info("Param image_name changed to: %s", params.get('image_name')) msg = "Start a new VM, using overlay file as its harddisk" error.context(msg, logging.info) vm_name = params['main_vm'] env_process.preprocess_vm(test, params, env, vm_name) vm = env.get_vm(vm_name) vm.verify_alive() timeout = int(params.get("login_timeout", 360)) session = vm.wait_for_login(timeout=timeout) # Do some changes to the overlay_file harddisk try: output = session.cmd(file_create_cmd) logging.info("Output of %s: %s", file_create_cmd, output) output = session.cmd(file_info_cmd) logging.info("Output of %s: %s", file_info_cmd, output) except Exception, err: raise error.TestFail("Could not create commit_testfile in the " "overlay file %s" % err) vm.destroy() # Execute the commit command cmitcmd = "%s commit -f %s %s" % (cmd, image_format, overlay_file_name) error.context("Committing image by command %s" % cmitcmd, logging.info) try: utils.system(cmitcmd, verbose=False) except error.CmdError: raise error.TestFail("Could not commit the overlay file") logging.info("overlay file (%s) committed!" % overlay_file_name) msg = "Start a new VM, using image_name as its harddisk" error.context(msg, logging.info) params['image_name'] = pre_name vm_name = params['main_vm'] env_process.preprocess_vm(test, params, env, vm_name) vm = env.get_vm(vm_name) vm.verify_alive() timeout = int(params.get("login_timeout", 360)) session = vm.wait_for_login(timeout=timeout) try: output = session.cmd(file_exist_chk_cmd) logging.info("Output of %s: %s", file_exist_chk_cmd, output) session.cmd(file_del_cmd) except Exception: raise error.TestFail("Could not find commit_testfile after a " "commit") vm.destroy()
session = vm.wait_for_login(timeout=timeout) qtree = qemu_qtree.QtreeContainer() try: qtree.parse_info_qtree(vm.monitor.info('qtree')) except AttributeError: # monitor doesn't support info qtree qtree = None logging.info("Starting physical resources check test") logging.info("Values assigned to VM are the values we expect " "to see reported by the Operating System") # Define a failure counter, as we want to check all physical # resources to know which checks passed and which ones failed n_fail = [] # We will check HDs with the image name image_name = storage.get_image_filename(params, data_dir.get_data_dir()) # Check cpu count logging.info("CPU count check") actual_cpu_nr = vm.get_cpu_count() if vm.cpuinfo.smp != actual_cpu_nr: fail_log = "CPU count mismatch:\n" fail_log += " Assigned to VM: %s \n" % vm.cpuinfo.smp fail_log += " Reported by OS: %s" % actual_cpu_nr n_fail.append(fail_log) logging.error(fail_log) n_fail.extend(check_cpu_number("cores", vm.cpuinfo.cores, chk_timeout)) n_fail.extend(check_cpu_number("threads", vm.cpuinfo.threads, chk_timeout))
def clean(self): params = self.params for sn in params.get("image_chain").split()[1:]: _params = params.object_params(sn) _image = storage.get_image_filename(_params, self.data_dir) process.run("rm -f %s" % _image)
def run(test, params, env): """ Timer device measure clock drift after sleep in guest with kvmclock: 1) Sync the host system time with ntp server 2) Boot a guest with multiple vcpus, using kvm-clock 3) Check the clock source currently used on guest 4) Stop auto sync service in guest (Optional) 5) Sync time from guest to ntpserver 6) Pin (only 1/none/all) vcpus to host cpu. 7) Sleep a while and check the time drift on guest :param test: QEMU test object. :param params: Dictionary with test parameters. :param env: Dictionary with the test environment. """ def verify_elapsed_time(): usleep_cmd = r'echo "for n in \$(seq 1000);' usleep_cmd += ' do usleep 10000; done"'' > /tmp/usleep.sh' session.cmd(usleep_cmd) get_time_cmd = 'for (( i=0; i<$(grep "processor" /proc/cpuinfo' get_time_cmd += ' | wc -l); i+=1 )); do /usr/bin/time -f"%e"' get_time_cmd += ' taskset -c $i sh /tmp/usleep.sh; done' output = session.cmd_output(get_time_cmd, timeout=timeout) times_list = output.splitlines()[1:] times_list = [_ for _ in times_list if _ > 10.0 or _ < 11.0] if times_list: test.fail("Unexpected time drift found: Detail: '%s'" % output) error_context.context("Sync the host system time with ntp server", logging.info) process.system("yum install -y ntpdate; ntpdate clock.redhat.com", shell=True) error_context.context("Boot the guest", logging.info) vm = env.get_vm(params["main_vm"]) vm.verify_alive() timeout = int(params.get("login_timeout", 360)) session = vm.wait_for_login(timeout=timeout) error_context.context("Check the clock source currently used on guest", logging.info) cmd = "cat /sys/devices/system/clocksource/" cmd += "clocksource0/current_clocksource" if "kvm-clock" not in session.cmd(cmd): grub_file = params.get("grub_file", "/boot/grub2/grub.cfg") if "clocksource=" not in session.cmd("cat %s" % grub_file): test.fail("Guest didn't use 'kvm-clock' clocksource") error_context.context("Shutdown guest") vm.destroy() env.unregister_vm(vm.name) error_context.context("Update guest kernel cli to kvm-clock", logging.info) image_filename = storage.get_image_filename(params, data_dir.get_data_dir()) kernel_cfg_pattern = params.get("kernel_cfg_pos_reg", r".*vmlinuz-\d+.*") disk_obj = utils_disk.GuestFSModiDisk(image_filename) kernel_cfg_original = disk_obj.read_file(grub_file) try: logging.warn("Update the first kernel entry to kvm-clock only") kernel_cfg = re.findall(kernel_cfg_pattern, kernel_cfg_original)[0] except IndexError as detail: test.error("Couldn't find the kernel config, regex" " pattern is '%s', detail: '%s'" % (kernel_cfg_pattern, detail)) if "clocksource=" in kernel_cfg: kernel_cfg_new = re.sub(r"clocksource=[a-z\- ]+", " ", kernel_cfg) disk_obj.replace_image_file_content(grub_file, kernel_cfg, kernel_cfg_new) error_context.context("Boot the guest", logging.info) vm_name = params["main_vm"] cpu_model_flags = params.get("cpu_model_flags") params["cpu_model_flags"] = cpu_model_flags + ",-kvmclock" env_process.preprocess_vm(test, params, env, vm_name) vm = env.get_vm(vm_name) vm.verify_alive() session = vm.wait_for_login(timeout=timeout) error_context.context("Stop auto sync service in guest", logging.info) cmd = "(service chronyd status | grep 'Loaded: loaded')" cmd += " && service chronyd stop" session.cmd_status_output(cmd) error_context.context("Sync time from guest to ntpserver", logging.info) session.cmd("yum install -y ntpdate; ntpdate clock.redhat.com", timeout=timeout) error_context.context("Sleep a while and check the time drift on guest" " (without any pinned vcpu)", logging.info) verify_elapsed_time() error_context.context("Pin every vcpu to physical cpu", logging.info) host_cpu_cnt_cmd = params["host_cpu_cnt_cmd"] host_cpu_num = process.system_output(host_cpu_cnt_cmd, shell=True).strip() host_cpu_list = (_ for _ in range(int(host_cpu_num))) cpu_pin_list = list(zip(vm.vcpu_threads, host_cpu_list)) if len(cpu_pin_list) < len(vm.vcpu_threads): test.cancel("There isn't enough physical cpu to pin all the vcpus") check_one_cpu_pinned = False for vcpu, pcpu in cpu_pin_list: process.system("taskset -p -c %s %s" % (pcpu, vcpu)) if not check_one_cpu_pinned: error_context.context("Sleep a while and check the time drift on" "guest (with one pinned vcpu)", logging.info) verify_elapsed_time() check_one_cpu_pinned = True error_context.context("Sleep a while and check the time drift on" "guest (with all pinned vcpus)", logging.info) verify_elapsed_time()
def run(test, params, env): """ Timer device check guest after update kernel line without kvmclock: 1) Boot a guest with kvm-clock 2) Check the current clocksource in guest 3) Check the available clocksource in guest 4) Update "clocksource=" parameter in guest kernel cli 5) Boot guest system 6) Check the current clocksource in guest :param test: QEMU test object. :param params: Dictionary with test parameters. :param env: Dictionary with the test environment. """ def verify_guest_clock_source(session, expected): error.context("Check the current clocksource in guest", logging.info) cmd = "cat /sys/devices/system/clocksource/" cmd += "clocksource0/current_clocksource" if expected not in session.cmd(cmd): raise error.TestFail( "Guest didn't use '%s' clocksource" % expected) error.context("Boot a guest with kvm-clock", logging.info) vm = env.get_vm(params["main_vm"]) vm.verify_alive() timeout = int(params.get("login_timeout", 360)) session = vm.wait_for_login(timeout=timeout) error.context("Check the current clocksource in guest", logging.info) cmd = "cat /sys/devices/system/clocksource/" cmd += "clocksource0/current_clocksource" if "kvm-clock" not in session.cmd(cmd): grub_file = params.get("grub_file", "/boot/grub2/grub.cfg") if "clocksource=" not in session.cmd("cat %s" % grub_file): raise error.TestFail("Guest didn't use 'kvm-clock' clocksource") error.context("Shutdown guest") vm.destroy() env.unregister_vm(vm.name) error.context("Update guest kernel cli to kvm-clock", logging.info) image_filename = storage.get_image_filename(params, data_dir.get_data_dir()) kernel_cfg_pattern = params.get("kernel_cfg_pos_reg", r".*vmlinuz-\d+.*") disk_obj = utils_disk.GuestFSModiDisk(image_filename) kernel_cfg_original = disk_obj.read_file(grub_file) try: logging.warn("Update the first kernel entry to" " kvm-clock only") kernel_cfg = re.findall(kernel_cfg_pattern, kernel_cfg_original)[0] except IndexError, detail: raise error.TestError("Couldn't find the kernel config, regex" " pattern is '%s', detail: '%s'" % (kernel_cfg_pattern, detail)) if "clocksource=" in kernel_cfg: kernel_cfg_new = re.sub("clocksource=[a-z\- ]+", " ", kernel_cfg) disk_obj.replace_image_file_content(grub_file, kernel_cfg, kernel_cfg_new) error.context("Boot the guest", logging.info) vm_name = params["main_vm"] cpu_model_flags = params.get("cpu_model_flags") params["cpu_model_flags"] = cpu_model_flags + ",-kvmclock" env_process.preprocess_vm(test, params, env, vm_name) vm = env.get_vm(vm_name) vm.verify_alive() session = vm.wait_for_login(timeout=timeout)
def run(test, params, env): """ KVM block resize test: 1) Start guest with data image and check the data image size. 2) Enlarge(or Decrease) the data image and check it in guest. :param test: QEMU test object :param params: Dictionary with the test parameters :param env: Dictionary with test environment. """ def get_block_size(session, block_cmd, block_pattern): """ Get block size inside guest. """ output = session.cmd_output(block_cmd) block_size = re.findall(block_pattern, output) if block_size: if not re.search("[a-zA-Z]", block_size[0]): return int(block_size[0]) else: return float(utils_misc.normalize_data_size(block_size[0], order_magnitude="B")) else: raise error.TestError( "Can not find the block size for the" " deivce. The output of command" " is: %s" % output ) def compare_block_size(session, block_cmd, block_pattern): """ Compare the current block size with the expected size. """ global current_size current_size = get_block_size(session, block_size_cmd, block_size_pattern) if current_size <= block_size and current_size >= block_size * (1 - accept_ratio): logging.info( "Block Resizing Finished !!! \n" "Current size %s is same as the expected %s", current_size, block_size ) return True return error.context("Check image size in guest", logging.info) vm = env.get_vm(params["main_vm"]) vm.verify_alive() timeout = float(params.get("login_timeout", 240)) session = vm.wait_for_login(timeout=timeout) data_image = params.get("images").split()[-1] data_image_params = params.object_params(data_image) data_image_size = data_image_params.get("image_size") data_image_size = float(utils_misc.normalize_data_size(data_image_size, order_magnitude="B")) data_image_filename = storage.get_image_filename(data_image_params, data_dir.get_data_dir()) data_image_dev = vm.get_block({"file": data_image_filename}) block_size_cmd = params["block_size_cmd"] block_size_pattern = params.get("block_size_pattern") need_reboot = params.get("need_reboot", "no") == "yes" accept_ratio = float(params.get("accept_ratio", 0)) block_size = get_block_size(session, block_size_cmd, block_size_pattern) if block_size > data_image_size or block_size < data_image_size * (1 - accept_ratio): raise error.TestError( "Please check your system and image size check" " command. The command output is not compatible" " with the image size." ) if params.get("guest_prepare_cmd"): session.cmd(params.get("guest_prepare_cmd")) disk_update_cmd = params.get("disk_update_cmd") if disk_update_cmd: disk_update_cmd = disk_update_cmd.split("::") disk_rescan_cmd = params.get("disk_rescan_cmd") block_size = data_image_size disk_change_ratio = params["disk_change_ratio"] for index, ratio in enumerate(disk_change_ratio.strip().split()): old_block_size = block_size block_size = int(int(data_image_size) * float(ratio)) if block_size == old_block_size: logging.warn("Block size is not changed in round %s." " Just skip it" % index) continue if disk_update_cmd: if "DISK_CHANGE_SIZE" in disk_update_cmd[index]: disk_unit = params.get("disk_unit", "M") size = abs(block_size - old_block_size) change_size = utils_misc.normalize_data_size("%sB" % size, disk_unit) disk_update_cmd[index] = re.sub("DISK_CHANGE_SIZE", change_size.split(".")[0], disk_update_cmd[index]) error.context("Change the disk size to %s" % block_size, logging.info) # So far only virtio drivers support online auto block size change in # linux guest. So we need manully update the the disk or even reboot # guest to get the right block size after change it from monitor. # We need shrink the disk in guest first, than in monitor if block_size < old_block_size and disk_update_cmd: session.cmd(disk_update_cmd[index]) vm.monitor.block_resize(data_image_dev, block_size) if need_reboot: session = vm.reboot(session=session) elif disk_rescan_cmd: session.cmd(disk_rescan_cmd) # We need expand disk in monitor first than extend it in guest if block_size > old_block_size and disk_update_cmd: session.cmd(disk_update_cmd[index]) global current_size current_size = 0 if not utils_misc.wait_for( lambda: compare_block_size(session, block_size_cmd, block_size_pattern), 20, 0, 1, "Block Resizing" ): raise error.TestFail( "Guest reported a wrong disk size:\n" " reported: %s\n" " expect: %s\n" % (current_size, block_size) )