From ba8b2890888200968586062d380bd99828835946 Mon Sep 17 00:00:00 2001 From: Meina Li Date: Wed, 15 Nov 2023 21:31:01 -0500 Subject: [PATCH] guest os booting: add hotplug case with boot order element This PR mainly implements the hotpluging of disk/usb/filesystem devices with boot order elements. Signed-off-by: Meina Li --- .../hotplug_device_with_boot_order.cfg | 20 ++++ .../hotplug_device_with_boot_order.py | 101 ++++++++++++++++++ 2 files changed, 121 insertions(+) create mode 100644 libvirt/tests/cfg/guest_os_booting/boot_order/hotplug_device_with_boot_order.cfg create mode 100644 libvirt/tests/src/guest_os_booting/boot_order/hotplug_device_with_boot_order.py diff --git a/libvirt/tests/cfg/guest_os_booting/boot_order/hotplug_device_with_boot_order.cfg b/libvirt/tests/cfg/guest_os_booting/boot_order/hotplug_device_with_boot_order.cfg new file mode 100644 index 00000000000..bdf0b26fdbc --- /dev/null +++ b/libvirt/tests/cfg/guest_os_booting/boot_order/hotplug_device_with_boot_order.cfg @@ -0,0 +1,20 @@ +- guest_os_booting.boot_order.hotplug: + type = hotplug_device_with_boot_order + start_vm = no + target_dev = "vda" + boot_order = 1 + order_xpath = [{'element_attrs': ["./devices/disk/boot[@order='2']"]}] + variants device_type: + - disk_device: + bus_type = "virtio" + target_disk = "vdb" + device_dict = {"type_name":"file", "target":{"dev": "${target_disk}", "bus": "${bus_type}"}, 'boot': '2'} + - usb_device: + bus_type = "usb" + target_disk = "sda" + device_dict = {"type_name":"file", "target":{"dev": "${target_disk}", "bus": "${bus_type}"}, 'boot': '2'} + - filesystem_device: + target_dir = "mount_tag" + source_dir = "/tmp" + order_xpath = [{'element_attrs': ["./devices/filesystem/boot[@order='2']"]}] + device_dict = {'target': {'dir': '${target_dir}'}, 'type_name': 'mount', 'source': {'dir': '${source_dir}'}, 'binary': {'path': '/usr/libexec/virtiofsd'}, 'accessmode': 'passthrough', 'boot': '2', 'driver': {'type': 'virtiofs'}} diff --git a/libvirt/tests/src/guest_os_booting/boot_order/hotplug_device_with_boot_order.py b/libvirt/tests/src/guest_os_booting/boot_order/hotplug_device_with_boot_order.py new file mode 100644 index 00000000000..9612483f39f --- /dev/null +++ b/libvirt/tests/src/guest_os_booting/boot_order/hotplug_device_with_boot_order.py @@ -0,0 +1,101 @@ +# Copyright Red Hat +# SPDX-License-Identifier: GPL-2.0 +# Author: Meina Li + +import os + +from virttest import virsh +from virttest.libvirt_xml import vm_xml +from virttest.libvirt_xml.devices.filesystem import Filesystem +from virttest.utils_libvirt import libvirt_vmxml + +from provider.virtual_disk import disk_base + + +def run(test, params, env): + """ + This case is to verify hotplugging device with boot order element. + 1) Prepare a running guest. + 2) Hotplug the device with boot order element. + 3) Check the dumpxml. + 4) Hot-unplug the device. + """ + def prepare_device_xml(vm_xml, device_type): + """ + Prepare the hot-plugged device xml. + + :params vm_xml: the instance of VMXML class + :params device_type: the device type + :return device_xml: the device xml + :return image_path: the disk path + """ + image_path = '' + # Need to use shared memory for filesystem device + if device_type == "filesystem_device": + vm_xml.VMXML.set_memoryBacking_tag(vm_name, access_mode="shared", + hpgs=False) + device_xml = Filesystem() + device_xml.setup_attrs(**device_dict) + else: + device_xml, image_path = disk_obj.prepare_disk_obj("file", device_dict) + return device_xml, image_path + + def check_dumpxml(device_type, image_path, hotplug=True): + """ + Check if the device is existed and included the boot order element. + + :params vmxml: the current guest xml + :params device_type: the device type + :params image_path: the disk path + :params hotplug: determine whether it is a hotplug step + """ + vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name) + test.log.debug(f"The current guest xml is: {vmxml}") + if device_type == "filesystem_device": + device_status = vmxml.devices.by_device_tag('filesystem') + else: + device_status = vm_xml.VMXML.check_disk_exist(vm_name, image_path) + # To make sure the boot order is also in device xml + if hotplug: + if not device_status: + test.fail(f"No {device_type} in guest xml after hotplug.") + libvirt_vmxml.check_guest_xml_by_xpaths(vmxml, order_xpath, ignore_status=False) + if not hotplug and device_status: + test.fail(f"The {device_type} isn't detached successfully.") + + vm_name = params.get("main_vm") + device_type = params.get("device_type") + target_dev = params.get("target_dev") + boot_order = params.get("boot_order", "1") + device_dict = eval(params.get("device_dict")) + order_xpath = eval(params.get("order_xpath")) + virsh_dargs = {'debug': True, 'ignore_status': False} + + vm = env.get_vm(vm_name) + vmxml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name) + bkxml = vmxml.copy() + disk_obj = disk_base.DiskBase(test, vm, params) + + try: + test.log.info("STEP1: Prepare a guest with boot order.") + vmxml.remove_all_boots() + vmxml.set_boot_order_by_target_dev(target_dev, order=boot_order) + vmxml.sync() + + test.log.info(f"STEP2: Hotplug the {device_type}.") + device_xml, image_path = prepare_device_xml(vm_xml, device_type) + if not vm.is_alive(): + virsh.start(vm_name, **virsh_dargs) + vm.wait_for_login() + virsh.attach_device(vm_name, device_xml.xml, **virsh_dargs) + check_dumpxml(device_type, image_path) + + test.log.info(f"STEP3: Hot-unplug the {device_type}.") + virsh.detach_device(vm_name, device_xml.xml, wait_for_event=True, **virsh_dargs) + check_dumpxml(device_type, image_path, hotplug=False) + finally: + if vm.is_alive(): + virsh.destroy(vm_name, **virsh_dargs) + if image_path and os.path.exists(image_path): + os.remove(image_path) + bkxml.sync()