Skip to content

Commit

Permalink
vIOMMU: Add a vm lifecycle test
Browse files Browse the repository at this point in the history
This PR adds:
    VIRT-294807 - [vIOMMU] Lifecycle test for vm with iommu device

Signed-off-by: Yingshun Cui <[email protected]>
  • Loading branch information
Yingshun committed Jan 29, 2024
1 parent 5cfb96d commit 8c0b583
Show file tree
Hide file tree
Showing 3 changed files with 141 additions and 8 deletions.
41 changes: 41 additions & 0 deletions libvirt/tests/cfg/sriov/vIOMMU/iommu_device_lifecycle.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
- vIOMMU.iommu_device_lifecycle:
type = iommu_device_lifecycle
start_vm = "no"
disk_driver = {'name': 'qemu', 'type': 'qcow2', 'iommu': 'on'}
variants:
- virtio:
only q35, aarch64
func_supported_since_libvirt_ver = (8, 3, 0)
iommu_dict = {'model': 'virtio'}
- intel:
only q35
start_vm = "yes"
enable_guest_iommu = "yes"
iommu_dict = {'model': 'intel', 'driver': {'intremap': 'on', 'caching_mode': 'on', 'eim': 'on', 'iotlb': 'on', 'aw_bits': '48'}}
- smmuv3:
only aarch64
func_supported_since_libvirt_ver = (5, 5, 0)
iommu_dict = {'model': 'smmuv3'}
variants:
- e1000e:
no smmuv3
iface_model = 'e1000e'
iface_dict = {'type_name': 'network', 'model': '${iface_model}', 'source': {'network': 'default'}}
- virtio_muti_devices:
disk_dict = {'target': {'dev': 'vda', 'bus': 'virtio'}, 'device': 'disk', 'driver': ${disk_driver}}
video_dict = {'primary': 'yes', 'model_heads': '1', 'model_type': 'virtio', 'driver': {'iommu': 'on'}}
test_devices = ["Eth", "block", "gpu"]
variants:
- vhost_on:
interface_driver_name = "vhost"
interface_driver = {'driver_attr': {'name': '${interface_driver_name}', 'iommu': 'on'}}
iface_dict = {'type_name': 'network', 'model': 'virtio', 'driver': ${interface_driver}, 'source': {'network': 'default'}}
- hostdev_iface:
only virtio
no save_restore
iface_dict = {'managed': 'yes', 'type_name': 'hostdev', 'hostdev_address': {'type_name': 'pci', 'attrs': vf_pci_addr}}
variants test_scenario:
- save_restore:
- suspend_resume:
- reboot_many_times:
loop_time = 5
82 changes: 82 additions & 0 deletions libvirt/tests/src/sriov/vIOMMU/iommu_device_lifecycle.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import os

from virttest import libvirt_version
from virttest import utils_misc
from virttest import virsh

from virttest.libvirt_xml import vm_xml
from virttest.utils_libvirt import libvirt_vmxml

from provider.save import save_base
from provider.sriov import sriov_base
from provider.sriov import check_points

VIRSH_ARGS = {'debug': True, 'ignore_status': False}


def run(test, params, env):
"""
Test lifecycle for vm with vIOMMU enabled with different devices.
"""
libvirt_version.is_libvirt_feature_supported(params)
cleanup_ifaces = "yes" == params.get("cleanup_ifaces", "yes")
ping_dest = params.get('ping_dest', "127.0.0.1")
iommu_dict = eval(params.get('iommu_dict', '{}'))
test_scenario = params.get("test_scenario")

vm_name = params.get("main_vm", "avocado-vt-vm1")
vm = env.get_vm(vm_name)

rand_id = utils_misc.generate_random_string(3)
save_path = f'/var/tmp/{vm_name}_{rand_id}.save'
test_obj = sriov_base.SRIOVTest(vm, test, params)
try:
test.log.info("TEST_SETUP: Update VM XML.")
test_obj.setup_iommu_test(iommu_dict=iommu_dict,
cleanup_ifaces=cleanup_ifaces)
test_obj.prepare_controller()
for dev in ["disk", "video"]:
dev_dict = eval(params.get('%s_dict' % dev, '{}'))
if dev == "disk":
dev_dict = test_obj.update_disk_addr(dev_dict)
libvirt_vmxml.modify_vm_device(
vm_xml.VMXML.new_from_dumpxml(vm.name), dev, dev_dict)
iface_dict = test_obj.parse_iface_dict()
if cleanup_ifaces:
libvirt_vmxml.modify_vm_device(
vm_xml.VMXML.new_from_dumpxml(vm.name),
"interface", iface_dict)

test.log.info("TEST_STEP: Start the VM.")
vm.start()
test.log.debug(vm_xml.VMXML.new_from_dumpxml(vm.name))
if test_scenario == "reboot_many_times":
vm.cleanup_serial_console()
vm.create_serial_console()
for _ in range(int(params.get('loop_time', '5'))):
test.log.info("TEST_STEP: Reboot the VM.")
session = vm.wait_for_serial_login(
timeout=int(params.get('login_timeout')))
session.sendline(params.get("reboot_command"))
_match, _text = session.read_until_last_line_matches(
[r"[Ll]ogin:\s*$"], timeout=240, internal_timeout=0.5)
session.close()

session = vm.wait_for_serial_login(
timeout=int(params.get('login_timeout')))
check_points.check_vm_network_accessed(session, ping_dest=ping_dest)
else:
pid_ping, upsince = save_base.pre_save_setup(vm, serial=True)
if test_scenario == "save_restore":
test.log.info("TEST_STEP: Save and restore the VM.")
virsh.save(vm.name, save_path, **VIRSH_ARGS)
virsh.restore(save_path, **VIRSH_ARGS)
elif test_scenario == "suspend_resume":
test.log.info("TEST_STEP: Suspend and resume the VM.")
virsh.suspend(vm.name, **VIRSH_ARGS)
virsh.resume(vm.name, **VIRSH_ARGS)
save_base.post_save_check(vm, pid_ping, upsince, serial=True)
finally:
test_obj.teardown_iommu_test()
if os.path.exists(save_path):
os.remove(save_path)
26 changes: 18 additions & 8 deletions provider/save/save_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,33 @@
VIRSH_ARGS = {'debug': True, 'ignore_status': False}


def pre_save_setup(vm):
def pre_save_setup(vm, serial=False):
"""
Setup vm before save:
Start ping process and get uptime since when on vm
:param vm: vm instance
:param serial: Whether to use a serial connection
:return: a tuple of pid of ping and uptime since when
"""
session = vm.wait_for_login()
if serial:
vm.cleanup_serial_console()
vm.create_serial_console()
session = vm.wait_for_serial_login()
else:
session = vm.wait_for_login()
upsince = session.cmd_output('uptime --since').strip()
LOG.debug(f'VM has been up since {upsince}')
ping_cmd = 'ping 127.0.0.1'
ping_cmd = 'ping 127.0.0.1 >/tmp/ping_out 2>&1'
# This session shouldn't be closed or it will kill ping
session.sendline(ping_cmd + '&')
check_session = vm.wait_for_login()
pid_ping = check_session.cmd_output('pidof ping').strip().split()[-1]
check_session.close()
pid_ping = session.cmd_output('pidof ping').strip().split()[-1]
LOG.debug(f'Pid of ping: {pid_ping}')

return pid_ping, upsince


def post_save_check(vm, pid_ping, upsince):
def post_save_check(vm, pid_ping, upsince, serial=False):
"""
Check vm status after save-restore:
Whether ping is still running, uptime since when is the same as before
Expand All @@ -39,8 +43,14 @@ def post_save_check(vm, pid_ping, upsince):
:param vm: vm instance
:param pid_ping: pid of ping
:param upsince: uptime since when
:param serial: Whether to use a serial connection
"""
session = vm.wait_for_login()
if serial:
vm.cleanup_serial_console()
vm.create_serial_console()
session = vm.wait_for_serial_login()
else:
session = vm.wait_for_login()
upsince_restore = session.cmd_output('uptime --since').strip()
LOG.debug(f'VM has been up (after restore) since {upsince_restore}')
LOG.debug(session.cmd_output(f'pidof ping'))
Expand Down

0 comments on commit 8c0b583

Please sign in to comment.