-
Notifications
You must be signed in to change notification settings - Fork 182
Virtual_disk: add two nvme disk related blockcopy scenarios #6655
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,4 @@ | ||
| import ast | ||
| import logging | ||
| import platform | ||
| import shutil | ||
|
|
@@ -9,9 +10,13 @@ | |
| from virttest import utils_misc | ||
| from virttest import virsh | ||
| from virttest import virt_vm | ||
| from virttest import libvirt_version | ||
|
|
||
| from virttest.libvirt_xml import vm_xml, xcepts | ||
| from virttest.utils_libvirt import libvirt_disk | ||
| from virttest.utils_test import libvirt | ||
|
|
||
| from provider.virtual_disk import disk_base | ||
|
|
||
| LOG = logging.getLogger('avocado.' + __name__) | ||
|
|
||
|
|
@@ -20,15 +25,20 @@ def run(test, params, env): | |
| """ | ||
| Test nvme virtual. | ||
|
|
||
| For attach test case: | ||
| 1.Prepare a vm with nvme type disk | ||
| 2.Attach the virtual disk to the vm | ||
| 3.Start vm | ||
| 4.Check the disk in vm | ||
| 5.Detach nvme device | ||
| """ | ||
| vm_name = params.get("main_vm") | ||
| vm = env.get_vm(vm_name) | ||
|
|
||
| For blockcopy test case: | ||
| 1.Start a VM with a regular disk | ||
| 2.Prepare nvme destination disk XML | ||
| 3.Execute blockcopy with --xml option (--finish or --pivot) | ||
| 4.Check VM XML after operation | ||
| 5.Verify disk source in VM | ||
| """ | ||
| def get_new_disks(old_partitions): | ||
| """ | ||
| Get new virtual disks in VM after disk plug. | ||
|
|
@@ -81,40 +91,92 @@ def create_customized_disk(params, pci_address): | |
| disk_device = params.get("device_type") | ||
| device_target = params.get("target_dev") | ||
| device_bus = params.get("target_bus") | ||
| device_format = params.get("target_format") | ||
| device_format = params.get("disk_image_format") | ||
|
|
||
| customized_disk = libvirt_disk.create_primitive_disk_xml( | ||
| type_name, disk_device, | ||
| device_target, device_bus, | ||
| device_format, None, None) | ||
|
|
||
| source_dict = eval(params.get("source_attrs")) | ||
| source_dict = ast.literal_eval(params.get("source_attrs", "{}")) | ||
| disk_src_dict = {"attrs": source_dict} | ||
| disk_source = customized_disk.new_disk_source(**disk_src_dict) | ||
| disk_source.address = pci_address | ||
| customized_disk.source = disk_source | ||
| LOG.debug("create customized xml: %s", customized_disk) | ||
| return customized_disk | ||
|
|
||
| hotplug = "yes" == params.get("virt_device_hotplug") | ||
| pkgs_host = params.get("pkgs_host", "") | ||
| def create_block_nvme_disk(params, disk_type, disk_obj, disk_dict): | ||
| """ | ||
| Create a block NVME disk by partitioning an NVME device and creating disk XML | ||
|
|
||
| # Get disk partitions info before hot/cold plug virtual disk | ||
| if vm.is_dead(): | ||
| vm.start() | ||
| session = vm.wait_for_login() | ||
| old_partitions = utils_disk.get_parts_list(session) | ||
| session.close() | ||
| vm.destroy(gracefully=False) | ||
| :param params: Dictionary containing test parameters | ||
| :param disk_type: the disk type | ||
| :param disk_obj: DiskBase object used for preparing disk XML configuration | ||
| :param disk_dict: Dictionary containing disk configuration parameters | ||
| :return: Tuple containing: | ||
| disk_xml: Disk XML object for the created NVME partition | ||
| nvme_device: String path of the base NVME device (e.g., "/dev/nvme0n1") | ||
| nvme_partition_path: String path of the created partition (e.g., "/dev/nvme0n1p1") | ||
| luks_sec_uuid: UUID of the LUKS secret (None if LUKS not used) | ||
| """ | ||
| luks_secret_passwd = params.get("luks_secret_passwd", "redhat") | ||
| with_luks = "yes" == params.get("with_luks", "no") | ||
| luks_sec_uuid = None | ||
| try: | ||
| LOG.info("SETUP_TEST: Getting available NVME device in host") | ||
| lsblk_result = process.run("lsblk -d -n -o NAME | grep nvme", | ||
| timeout=10, ignore_status=True, shell=True) | ||
| if lsblk_result.exit_status != 0: | ||
| test.cancel("No NVME device found in host") | ||
|
|
||
| # Backup vm xml | ||
| vmxml_backup = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name) | ||
| vmxml = vmxml_backup.copy() | ||
| nvme_devices = lsblk_result.stdout_text.strip().split('\n') | ||
| for device in nvme_devices: | ||
| device_path = "/dev/" + device.strip() | ||
| mount_check = process.run(f"lsblk {device_path} | grep -q SWAP\\|/", | ||
| ignore_status=True, shell=True) | ||
| if mount_check.exit_status != 0: | ||
| nvme_device = device_path | ||
|
Comment on lines
+128
to
+139
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chainFix NVMe “unused” detection to avoid wiping in-use host disks The logic: lsblk_result = process.run("lsblk -d -n -o NAME | grep nvme", ...)
...
mount_check = process.run(
f"lsblk {device_path} | grep -q SWAP\\|/", ignore_status=True, shell=True)
if mount_check.exit_status != 0:
nvme_device = device_path
break
...
process.run("sgdisk --zap-all %s" % nvme_device, shell=True, ignore_status=False)has two coupled problems:
You should reliably detect any mounted/swap usage and only pick genuinely unused devices (or make the device explicit via params). For example: - mount_check = process.run(f"lsblk {device_path} | grep -q SWAP\\|/",
- ignore_status=True, shell=True)
- if mount_check.exit_status != 0:
+ # Treat any non-empty mountpoint (including SWAP) as "in use"
+ mount_check = process.run(
+ f"lsblk -n -o MOUNTPOINT {device_path} | grep -qE '\\S'",
+ ignore_status=True, shell=True)
+ if mount_check.exit_status != 0:
nvme_device = device_path
breakand keep Also applies to: 256-257 I'll help you verify this review comment. Let me examine the actual code in the repository to confirm the issues described. Now let me examine the actual code in the repository: Length of output: 2238 🏁 Script executed: #!/bin/bash
# Also check lines around 256-257 for similar issues
if [ -f "libvirt/tests/src/virtual_disks/virtual_disks_nvme.py" ]; then
echo "=== Lines 250-265 ==="
sed -n '250,265p' libvirt/tests/src/virtual_disks/virtual_disks_nvme.py
fiLength of output: 687 🏁 Script executed: #!/bin/bash
# Search for sgdisk calls in the file
rg -n "sgdisk" libvirt/tests/src/virtual_disks/virtual_disks_nvme.pyLength of output: 93 🏁 Script executed: #!/bin/bash
# Get context around grep patterns used in the file
rg -n "grep.*SWAP" -A3 -B3 libvirt/tests/src/virtual_disks/virtual_disks_nvme.pyLength of output: 448 🏁 Script executed: #!/bin/bash
# Check lsblk output to understand what the grep is actually matching against
# Show what lsblk -d -n -o NAME outputs and what lsblk on a device outputs
cat <<'EOF'
=== Understanding lsblk output formats ===
lsblk -d -n -o NAME outputs:
nvme0n1
sda
...
lsblk /dev/nvme0n1 outputs columns like:
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT ...
nvme0n1 259:0 0 476.97G 0 disk
With mounted filesystem:
nvme0n1 259:0 0 476.97G 0 disk
nvme0n1p1 259:1 0 512B 0 part /boot
nvme0n1p2 259:2 0 100G 0 part /
With swap:
nvme0n1 259:0 0 476.97G 0 disk
nvme0n1p1 259:1 0 20G 0 part [SWAP]
EOFLength of output: 408 🏁 Script executed: #!/bin/bash
# Search for all process.run commands with grep patterns
rg -n 'process\.run.*grep' -A2 -B2 libvirt/tests/src/virtual_disks/virtual_disks_nvme.py | head -60Length of output: 635 🏁 Script executed: #!/bin/bash
# Look for the full context of nvme_device assignment and sgdisk usage
ast-grep --pattern 'nvme_device = $_' libvirt/tests/src/virtual_disks/virtual_disks_nvme.pyLength of output: 103 🏁 Script executed: #!/bin/bash
# Search for sgdisk execution pattern
rg -n "sgdisk.*nvme_device" -B5 -A5 libvirt/tests/src/virtual_disks/virtual_disks_nvme.pyLength of output: 583 🏁 Script executed: #!/bin/bash
# Get full function context to understand the flow
rg -n "def.*test.*nvme" -A200 libvirt/tests/src/virtual_disks/virtual_disks_nvme.py | head -150Length of output: 0 🏁 Script executed: #!/bin/bash
# Search for the loop and device selection logic
rg -n "for device in" -A15 libvirt/tests/src/virtual_disks/virtual_disks_nvme.pyLength of output: 931 🏁 Script executed: #!/bin/bash
# Final check - see if break statement exists after nvme_device assignment
rg -n "nvme_device = device_path" -A5 libvirt/tests/src/virtual_disks/virtual_disks_nvme.pyLength of output: 266 I need to verify the exact behavior of the grep command with alternation syntax: Now let me verify the actual behavior of Based on my verification, I've discovered a critical distinction: GNU grep allows you to escape | in BRE (basic regular expressions) and get alternation, so However, your review's actual concern about the device selection logic is valid and critical. The real problem isn't the grep syntax—it's the pattern itself: The mount point will be empty if it is unmounted, and unmounted partitions will have an empty MOUNTPOINT. When running This means a device with partitions mounted anywhere except root or swap would be incorrectly classified as "unused" and subsequently destroyed by Fix NVMe device selection to detect all mount points, not just root/swap Devices can be mounted at arbitrary paths (e.g., - mount_check = process.run(f"lsblk {device_path} | grep -q SWAP\\|/",
- ignore_status=True, shell=True)
- if mount_check.exit_status != 0:
+ # Check for ANY non-empty mountpoint (catches all mount paths, not just / and SWAP)
+ mount_check = process.run(
+ f"lsblk -n -o MOUNTPOINT {device_path} | grep -qE '\\S'",
+ ignore_status=True, shell=True)
+ if mount_check.exit_status != 0:
nvme_device = device_path
breakThis reliably detects any partition with a non-empty mountpoint before invoking 🧰 Tools🪛 Ruff (0.14.4)128-128: Function call with (S604) 136-136: Function call with (S604) 🤖 Prompt for AI Agents |
||
| break | ||
| else: | ||
| test.cancel("No available unmounted NVME device found") | ||
|
|
||
| try: | ||
| # install essential package in host | ||
| if not shutil.which('lspci'): | ||
| test.error("package {} not installed, please install them before testing".format(pkgs_host)) | ||
| LOG.info("SETUP_TEST: Creating GPT partition table on NVME device") | ||
| result = process.run("parted -s %s mklabel gpt" % nvme_device, | ||
| timeout=30, ignore_status=False, verbose=True, shell=True) | ||
| LOG.debug("GPT partition table creation result: %s", result) | ||
|
|
||
| LOG.info("SETUP_TEST: Creating 1G primary partition on NVME device") | ||
| result = process.run("parted -s %s mkpart primary 0%% 1G" % nvme_device, | ||
| timeout=30, ignore_status=False, verbose=True, shell=True) | ||
| LOG.debug("Partition creation result: %s", result) | ||
| time.sleep(2) | ||
|
|
||
| # Use the created partition as disk image | ||
| nvme_partition_path = nvme_device + "p1" | ||
| if with_luks: | ||
| luks_sec_uuid = libvirt.create_secret(params) | ||
| ret = virsh.secret_set_value(luks_sec_uuid, luks_secret_passwd, | ||
| encode=True, debug=True) | ||
| libvirt.check_exit_status(ret) | ||
|
|
||
| disk_xml, _ = disk_obj.prepare_disk_obj(disk_type, disk_dict, nvme_partition_path) | ||
| LOG.debug("Created disk XML: %s", disk_xml) | ||
| return disk_xml, nvme_device, nvme_partition_path, luks_sec_uuid | ||
|
|
||
|
Comment on lines
+123
to
+166
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chainEnsure LUKS NVMe destination XML preserves encryption and secret usage In the LUKS variant, the cfg defines with_luks = "yes" == params.get("with_luks", "no")
...
disk_xml, _ = disk_obj.prepare_disk_obj(disk_type, disk_dict, nvme_partition_path)
...
if with_luks:
cmd = ("qemu-img create -f qcow2 %s %s %s"
% (luks_extra_parameter, nvme_partition_path, disk_size_bytes))
process.run(cmd, shell=True, ignore_status=False)
...
verify_blockcopy_result(..., nvme_partition_path)Given disk_dict.update({'source': {'attrs': {'dev': new_image_path}}})any pre-populated
Consider adjusting this path so that encryption metadata survives:
Also, in elif "--pivot" in specific_option:
current_disk_source = disk_obj.get_source_list(current_vmxml, nvme_disk_type, target_dev)[0]
if current_disk_source != nvme_dest_disk:
...Also applies to: 223-224, 241-249, 261-293 Length of output: 0 🏁 Script executed: #!/bin/bash
# Search for prepare_disk_obj method implementation
rg -n "def prepare_disk_obj" --type=py -A 30Length of output: 5229 🏁 Script executed: #!/bin/bash
# Search for the specific file under review
find . -name "virtual_disks_nvme.py" -type fLength of output: 55 🏁 Script executed: #!/bin/bash
# Search for verify_blockcopy_result function
rg -n "def verify_blockcopy_result" --type=py -A 20Length of output: 2345 🏁 Script executed: #!/bin/bash
# Search for add_luks_encryption_to_disk_dict pattern mentioned in review
rg -n "add_luks_encryption_to_disk_dict" --type=py -B 2 -A 5Length of output: 1311 🏁 Script executed: #!/bin/bash
# Check the specific lines mentioned in the review (223-224, 241-249, 261-293)
find . -name "virtual_disks_nvme.py" -type f -exec sed -n '220,300p' {} \;Length of output: 4568 🏁 Script executed: #!/bin/bash
# Find create_block_nvme_disk function mentioned in review
rg -n "def create_block_nvme_disk" --type=py -A 20Length of output: 2412 Length of output: 1374 🏁 Script executed: #!/bin/bash
# Get the complete prepare_disk_obj method to see how different disk types handle source dict
sed -n '114,250p' ./provider/virtual_disk/disk_base.pyLength of output: 7080 🏁 Script executed: #!/bin/bash
# Check the add_luks_encryption_to_disk_dict implementation
sed -n '252,270p' ./provider/virtual_disk/disk_base.pyLength of output: 835 🏁 Script executed: #!/bin/bash
# Check the file branch to compare with block branch
sed -n '125,136p' ./provider/virtual_disk/disk_base.pyLength of output: 555 🏁 Script executed: #!/bin/bash
# Search for rbd_with_luks_and_auth pattern mentioned in review
rg -n "rbd_with_luks_and_auth\|rbd" ./provider/virtual_disk/disk_base.py -B 3 -A 10 | head -60Length of output: 0 🏁 Script executed: #!/bin/bash
# Check how disk_dict is structured in the NVME test - look for nvme_disk_dict definition
rg -n "nvme_disk_dict" ./libvirt/tests/src/virtual_disks/virtual_disks_nvme.py -B 2 -A 5Length of output: 1234 Length of output: 270 🏁 Script executed: #!/bin/bash
# Search for test configs in the virtual_disks directory
find ./libvirt/tests/cfg -name "*nvme*" -o -name "*virtual_disk*" | head -20Length of output: 1250 🏁 Script executed: #!/bin/bash
# Look specifically at lines 223-224 and surrounding context
sed -n '220,230p' ./libvirt/tests/src/virtual_disks/virtual_disks_nvme.pyLength of output: 770 🏁 Script executed: #!/bin/bash
# Look at lines 241-249
sed -n '238,255p' ./libvirt/tests/src/virtual_disks/virtual_disks_nvme.pyLength of output: 984 🏁 Script executed: #!/bin/bash
# Search for where nvme_disk_dict gets encryption configuration
rg -n "source.*encryption\|encryption.*source" ./libvirt/tests/src/virtual_disks/ --type=py -B 3 -A 3Length of output: 0 🏁 Script executed: #!/bin/bash
# Check if qcow2+LUKS creation happens but encryption is not in XML
sed -n '241,249p' ./libvirt/tests/src/virtual_disks/virtual_disks_nvme.pyLength of output: 639 Length of output: 2226 🏁 Script executed: #!/bin/bash
# Look for nvme_disk_dict that might contain encryption in the config
grep -n "nvme_disk_dict\|encryption\|source" ./libvirt/tests/cfg/virtual_disks/virtual_disks_nvme.cfg -B 2 -A 2 | head -60Length of output: 1544 🏁 Script executed: #!/bin/bash
# Get full context around create_block_nvme_disk to understand the flow
sed -n '109,175p' ./libvirt/tests/src/virtual_disks/virtual_disks_nvme.pyLength of output: 3400 🏁 Script executed: #!/bin/bash
# Verify exact line numbers for the docstring issue in verify_blockcopy_result
sed -n '261,293p' ./libvirt/tests/src/virtual_disks/virtual_disks_nvme.pyLength of output: 1886 Preserve LUKS encryption metadata in block NVME disk XML The test config for However, when disk_dict.update({'source': {'attrs': {'dev': new_image_path}}})This overwrites any pre-populated encryption metadata. Later, when the qcow2+LUKS image is created (lines 241–248) and blockcopy is executed with The Fixes:
🧰 Tools🪛 Ruff (0.14.4)128-128: Function call with (S604) 136-136: Function call with (S604) 145-145: Function call with (S604) 150-150: Function call with (S604) 165-165: Consider moving this statement to an (TRY300) 🤖 Prompt for AI Agents |
||
| except Exception as err: | ||
| test.fail("Failed to create block NVME disk: %s" % str(err)) | ||
|
|
||
| def run_attach_detach_test(): | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe move this out of scope :runtest(), and put them ahead of runtest(). If you implement in runtest(), those will become method inline code |
||
| """ | ||
| Run original attach/detach test with nvme device | ||
| """ | ||
| if vm.is_dead(): | ||
| vm.start() | ||
| session = vm.wait_for_login() | ||
| old_partitions = utils_disk.get_parts_list(session) | ||
| session.close() | ||
| vm.destroy(gracefully=False) | ||
|
|
||
| pci_addr_in_dict = get_usable_nvme_pci_address() | ||
|
|
||
|
|
@@ -131,13 +193,7 @@ def create_customized_disk(params, pci_address): | |
| if hotplug: | ||
| virsh.attach_device(vm_name, device_obj.xml, flagstr="--live", | ||
| ignore_status=False, debug=True) | ||
| except virt_vm.VMStartError as details: | ||
| test.fail("VM failed to start." | ||
| "Error: %s" % str(details)) | ||
| except xcepts.LibvirtXMLError as xml_error: | ||
| test.fail("VM failed to define" | ||
| "Error: %s" % str(xml_error)) | ||
| else: | ||
|
|
||
| utils_misc.wait_for(lambda: get_new_disks(old_partitions), 20) | ||
| new_disks = get_new_disks(old_partitions) | ||
| if len(new_disks) != 1: | ||
|
|
@@ -147,8 +203,117 @@ def create_customized_disk(params, pci_address): | |
| time.sleep(10) | ||
| if not libvirt_disk.check_virtual_disk_io(vm, new_disk): | ||
| test.fail("Cannot operate the newly added disk in vm.") | ||
|
|
||
| virsh.detach_device(vm_name, device_obj.xml, flagstr="--live", | ||
| debug=True, ignore_status=False) | ||
|
|
||
| def run_blockcopy_test(): | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. suggest move it out of runtest() scope |
||
| """ | ||
| Run blockcopy test with nvme destination | ||
| """ | ||
| libvirt_version.is_libvirt_feature_supported(params) | ||
| target_dev = params.get("target_dev", "vdb") | ||
| disk_type = params.get("disk_type", "file") | ||
| nvme_disk_type = params.get("nvme_disk_type", "block") | ||
| disk_dict = ast.literal_eval(params.get("disk_dict", "{}")) | ||
| nvme_disk_dict = ast.literal_eval(params.get("nvme_disk_dict", "{}")) | ||
| common_options = params.get("blockcopy_common_options") | ||
| specific_option = params.get("blockcopy_option", "") | ||
| with_luks = "yes" == params.get("with_luks", "no") | ||
| luks_extra_parameter = params.get("luks_extra_parameter", "") | ||
| disk_obj = disk_base.DiskBase(test, vm, params) | ||
|
|
||
| LOG.info("TEST_STEP1: Start VM.") | ||
| nvme_disk, nvme_device, nvme_partition_path, luks_sec_uuid = create_block_nvme_disk(params, | ||
| nvme_disk_type, | ||
| disk_obj, | ||
| nvme_disk_dict) | ||
| disk_info_dict = utils_misc.get_image_info(nvme_partition_path) | ||
| disk_size = disk_info_dict.get("vsize") | ||
| disk_size_bytes = str(disk_size) + "b" | ||
| original_disk_source = disk_obj.add_vm_disk(disk_type, disk_dict, size=disk_size_bytes) | ||
| LOG.debug("Original disk source: %s", original_disk_source) | ||
| if vm.is_dead(): | ||
| vm.start() | ||
| LOG.debug("The current guest xml is: %s" % (virsh.dumpxml(vm_name).stdout_text)) | ||
| vm.wait_for_login().close() | ||
|
|
||
| LOG.info("TEST_STEP2: Execute blockcopy command with option '%s'.", specific_option) | ||
| if with_luks: | ||
| cmd = ("qemu-img create -f qcow2 %s %s %s" % (luks_extra_parameter, | ||
| nvme_partition_path, | ||
| disk_size_bytes)) | ||
| process.run(cmd, shell=True, ignore_status=False) | ||
| options = "--xml %s %s %s" % (nvme_disk.xml, specific_option, common_options) | ||
| virsh.blockcopy(vm_name, target_dev, options, debug=True, ignore_status=False) | ||
| LOG.debug("Blockcopy completed successfully.") | ||
|
|
||
| LOG.info("TEST_STEP3: Verify blockcopy result in VM XML.") | ||
| verify_blockcopy_result(params, original_disk_source, nvme_partition_path) | ||
|
|
||
| if vm.is_alive(): | ||
| vm.destroy(gracefully=False) | ||
| process.run("sgdisk --zap-all %s" % nvme_device, shell=True, ignore_status=False) | ||
| disk_obj.cleanup_disk_preparation(disk_type) | ||
| if with_luks: | ||
| virsh.secret_undefine(luks_sec_uuid, debug=True, ignore_status=False) | ||
|
|
||
| def verify_blockcopy_result(params, original_source, nvme_dest_disk): | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. suggest move out of runtest scope |
||
| """ | ||
| Verify blockcopy result by checking VM XML | ||
|
|
||
| :param params: Dictionary containing test parameters | ||
| :param original_source: Original disk source path before blockcopy operation | ||
| :param nvme_dest_disk: NVME destination disk XML object used in blockcopy | ||
| """ | ||
| specific_option = params.get("blockcopy_option", "") | ||
| target_dev = params.get("target_dev", "vdb") | ||
| disk_type = params.get("disk_type", "file") | ||
| nvme_disk_type = params.get("nvme_disk_type", "block") | ||
| current_vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name) | ||
| LOG.debug("The current guest xml after blockcopy is: %s" % current_vmxml) | ||
| disk_sources = current_vmxml.get_disk_source(vm_name) | ||
| disk_obj = disk_base.DiskBase(test, vm, params) | ||
| if len(disk_sources) < 2: | ||
| test.fail("VM doesn't have enough disks after blockcopy operation.") | ||
|
|
||
| if "--finish" in specific_option: | ||
| current_disk_source = disk_obj.get_source_list(current_vmxml, disk_type, target_dev)[0] | ||
| if current_disk_source != original_source: | ||
| test.fail("Expected VM to keep old disk source '%s', but found '%s'" % | ||
| (original_source, current_disk_source)) | ||
| LOG.info("PASS: VM disk kept the old disk source as expected with --finish") | ||
|
|
||
| elif "--pivot" in specific_option: | ||
| current_disk_source = disk_obj.get_source_list(current_vmxml, nvme_disk_type, target_dev)[0] | ||
| if current_disk_source != nvme_dest_disk: | ||
| test.fail("Expected VM to pivot to nvme destination, but disk source remains unchanged: '%s'" % | ||
| current_disk_source) | ||
| LOG.info("PASS: VM disk pivoted to the new nvme destination as expected with --pivot") | ||
|
|
||
| vm_name = params.get("main_vm") | ||
| vm = env.get_vm(vm_name) | ||
| with_blockcopy = "yes" == params.get("with_blockcopy", "no") | ||
| hotplug = "yes" == params.get("virt_device_hotplug") | ||
| pkgs_host = params.get("pkgs_host", "") | ||
|
|
||
| vmxml_backup = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name) | ||
| vmxml = vmxml_backup.copy() | ||
|
|
||
| try: | ||
| # install essential package in host | ||
| if not shutil.which('lspci'): | ||
| test.error("package {} not installed, please install them before testing".format(pkgs_host)) | ||
|
|
||
| if with_blockcopy: | ||
| run_blockcopy_test() | ||
| else: | ||
| run_attach_detach_test() | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Better we can have condition when call run_attach_detach_test in order to further expand: |
||
|
|
||
| except virt_vm.VMStartError as details: | ||
| test.fail("VM failed to start. Error: %s" % str(details)) | ||
| except xcepts.LibvirtXMLError as xml_error: | ||
| test.fail("VM failed to define. Error: %s" % str(xml_error)) | ||
| finally: | ||
| if vm.is_alive(): | ||
| vm.destroy(gracefully=False) | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.