diff --git a/virttest/env_process.py b/virttest/env_process.py index dbb99a65ee..698e65a399 100644 --- a/virttest/env_process.py +++ b/virttest/env_process.py @@ -424,8 +424,10 @@ def check_image(test, params, image_name, vm_process_status=None): """ clone_master = params.get("clone_master", None) base_dir = data_dir.get_data_dir() - image = qemu_storage.QemuImg(params, base_dir, image_name) check_image_flag = params.get("check_image") == "yes" + if not check_image_flag: + return + image = qemu_storage.QemuImg(params, base_dir, image_name) if vm_process_status == "running" and check_image_flag: if params.get("skip_image_check_during_running") == "yes": @@ -498,9 +500,11 @@ def postprocess_image(test, params, image_name, vm_process_status=None): restored, removed = (False, False) clone_master = params.get("clone_master", None) base_dir = params.get("images_base_dir", data_dir.get_data_dir()) - image = qemu_storage.QemuImg(params, base_dir, image_name) + image = None if params.get("img_check_failed") == "yes": + image = qemu_storage.QemuImg(params, base_dir, + image_name) if not image else image if params.get("restore_image_on_check_error", "no") == "yes": image.backup_image(params, base_dir, "restore", True) restored = True @@ -511,17 +515,25 @@ def postprocess_image(test, params, image_name, vm_process_status=None): # example for this is when 'unattended_install' is run. if (params.get("backup_image_after_testing_passed", "no") == "yes" and params.get("test_passed") == "True"): + image = qemu_storage.QemuImg(params, base_dir, + image_name) if not image else image image.backup_image(params, base_dir, "backup", True) if (not restored and params.get("restore_image", "no") == "yes"): + image = qemu_storage.QemuImg(params, base_dir, + image_name) if not image else image image.backup_image(params, base_dir, "restore", True) restored = True if (not restored and params.get("restore_image_after_testing", "no") == "yes"): + image = qemu_storage.QemuImg(params, base_dir, + image_name) if not image else image image.backup_image(params, base_dir, "restore", True) if params.get("img_check_failed") == "yes": + image = qemu_storage.QemuImg(params, base_dir, + image_name) if not image else image if params.get("remove_image_on_check_error", "no") == "yes": cl_images = params.get("master_images_clone", "") if image_name in cl_images.split(): @@ -529,6 +541,8 @@ def postprocess_image(test, params, image_name, vm_process_status=None): removed = True if (not removed and params.get("remove_image", "yes") == "yes"): + image = qemu_storage.QemuImg(params, base_dir, + image_name) if not image else image LOG.info("Remove image on %s." % image.storage_type) if clone_master is None: image.remove() diff --git a/virttest/qemu_devices/qcontainer.py b/virttest/qemu_devices/qcontainer.py index be6dfee508..5a40a475bb 100644 --- a/virttest/qemu_devices/qcontainer.py +++ b/virttest/qemu_devices/qcontainer.py @@ -2110,6 +2110,8 @@ def define_hbas(qtype, atype, bus, unit, port, qbus, pci_bus, iothread, protocol_cls = qdevices.QBlockdevProtocolFTPS elif filename.startswith('ftp:'): protocol_cls = qdevices.QBlockdevProtocolFTP + elif filename.startswith('vdpa:'): + protocol_cls = qdevices.QBlockdevProtocolVirtioBlkVhostVdpa elif fmt in ('scsi-generic', 'scsi-block'): protocol_cls = qdevices.QBlockdevProtocolHostDevice elif blkdebug is not None: @@ -2454,6 +2456,9 @@ def images_define_by_params(self, name, image_params, media=None, strict_mode is True :param name: Name of the new disk :param params: Disk params (params.object_params(name)) + + :raise NotImplementedError: if image_filename shows that this is a vdpa + device """ data_root = data_dir.get_data_dir() shared_dir = os.path.join(data_root, "shared") @@ -2480,6 +2485,9 @@ def images_define_by_params(self, name, image_params, media=None, image_base_dir = image_params.get("images_base_dir", data_root) image_filename = storage.get_image_filename(image_params, image_base_dir) imgfmt = image_params.get("image_format") + if image_filename.startswith("vdpa://") and image_params.get( + "image_snapshot") == "yes": + raise NotImplementedError("vdpa does NOT support the snapshot!") if (Flags.BLOCKDEV in self.caps and image_params.get("image_snapshot") == "yes"): sn_params = Params() diff --git a/virttest/qemu_devices/qdevices.py b/virttest/qemu_devices/qdevices.py index 4c0aa4193a..dd48fdbcd5 100644 --- a/virttest/qemu_devices/qdevices.py +++ b/virttest/qemu_devices/qdevices.py @@ -920,6 +920,11 @@ def __init__(self, aobject): super(QBlockdevProtocol, self).__init__(aobject, None, False) +class QBlockdevProtocolVirtioBlkVhostVdpa(QBlockdevProtocol): + """ New a protocol virtio-blk-vhost-vdpa blockdev node. """ + TYPE = 'virtio-blk-vhost-vdpa' + + class QBlockdevProtocolFile(QBlockdevProtocol): """ New a protocol file blockdev node. """ TYPE = 'file' diff --git a/virttest/qemu_storage.py b/virttest/qemu_storage.py index f53a388b2b..77fa8b2444 100755 --- a/virttest/qemu_storage.py +++ b/virttest/qemu_storage.py @@ -187,6 +187,11 @@ def filename_to_file_opts(filename): if matches['user'] is not None: file_opts['username'] = matches['user'] + # FIXME: vdpa is a customized protocol instead of a standard protocol. + elif filename.startswith("vdpa:"): + # filename[7:] mean: remove the prefix "vdpa://" + file_opts = {'driver': 'virtio-blk-vhost-vdpa', + 'path': filename[7:]} # FIXME: Judge the host device by the string starts with "/dev/". elif filename.startswith('/dev/'): file_opts = {'driver': 'host_device', 'filename': filename} @@ -517,7 +522,12 @@ def __init__(self, params, root_dir, tag): :param params: Dictionary containing the test parameters. :param root_dir: Base directory for relative filenames. :param tag: Image tag defined in parameter images + + :raise NotImplementedError: If the image type is not supported. """ + if params.get("storage_type") == "vhost-vdpa": + raise NotImplementedError("Vdpa is NOT supported to handle " + "the image!") storage.QemuImg.__init__(self, params, root_dir, tag) self.image_cmd = utils_misc.get_qemu_img_binary(params) q_result = process.run(self.image_cmd + ' -h', ignore_status=True, diff --git a/virttest/storage.py b/virttest/storage.py index 86e60ff1fb..90d96e3a93 100644 --- a/virttest/storage.py +++ b/virttest/storage.py @@ -31,6 +31,7 @@ from virttest import ceph from virttest import nvme from virttest import data_dir +from virttest import vdpa_blk LOG = logging.getLogger('avocado.' + __name__) @@ -182,6 +183,8 @@ def get_image_filename(params, root_dir, basename=False): storage_type = params.get("storage_type") if image_name: image_format = params.get("image_format", "qcow2") + if storage_type == "vhost-vdpa": + return vdpa_blk.get_image_filename(image_name) if enable_curl: # required libcurl params curl_protocol = params['curl_protocol'] diff --git a/virttest/vdpa_blk.py b/virttest/vdpa_blk.py new file mode 100644 index 0000000000..571fe39b59 --- /dev/null +++ b/virttest/vdpa_blk.py @@ -0,0 +1,24 @@ +""" +This module provides interfaces about vdpa storage backend. + +Available functions: +- get_image_filename: Get the device path from vdpa. + +""" +from virttest import utils_vdpa + + +def get_image_filename(name): + """ + Get the device path from vdpa. + NOTE: the vdpa protocol is a customized-private protocol + instead of a standard protocol. + + :param name: the name of device + :type name: str + :return: The path from vdpa in vpda protocol + e.g: vdpa:///dev/vhost-vdpa + :rtype: str + """ + path = utils_vdpa.get_vdpa_dev_file_by_name(name) + return 'vdpa://%s' % path