def bind_vfs(pf_pci, vf_no=4): """ Bind VFs :param pf_pci: PF's pci, eg. 0000:5e:00.0 :param vf_no: VFs' numbers """ for idx in range(vf_no): pci_addr = utils_sriov.get_vf_pci_id(pf_pci, idx) cmd = "echo %s > /sys/bus/pci/drivers/mlx5_core/bind" % pci_addr process.run(cmd, shell=True)
def config_vdpa_dev(self): """ Bind VFs and add vDPA dev :raise: TestError if vf device is not found """ utils_switchdev.bind_vfs(self.pf_pci, self.vf_no) for idx in range(self.vf_no): vf_pci = utils_sriov.get_vf_pci_id(self.pf_pci, vf_index=idx) vf_dev = utils_sriov.get_iface_name(vf_pci) if not vf_dev: raise exceptions.TestError("Cannot get VF network device!") self.set_tc_offload(vf_dev) self.set_dev_managed_no(vf_dev) self.add_vdpa_dev(idx, vf_pci)
def add_hostdev_device(vm_name, pf_pci, params): """ Add a hostdev device to the guest :param vm_name: VM's name :param pf_pci: The PF's pci :param params: The parameters used """ vf_pci = utils_sriov.get_vf_pci_id(pf_pci) hostdev_teaming_dict = params.get("hostdev_device_teaming_dict", '{}') vmxml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name) hostdev_dev = libvirt.create_hostdev_xml(vf_pci, teaming=hostdev_teaming_dict) vmxml.add_device(hostdev_dev) vmxml.sync()
def setup_hostdev(): """ Setup test environment for hostdev """ pf_pci = utils_sriov.get_pf_pci() sriov_base.setup_vf(pf_pci, params) vf_pci = utils_misc.wait_for(lambda: utils_sriov.get_vf_pci_id(pf_pci), 30, 5) pci_to_addr = utils_sriov.pci_to_addr(vf_pci) if params.get('iface_dict'): params.update({'iface_dict': params.get('iface_dict') % pci_to_addr}) elif params.get('hostdev_dict'): del pci_to_addr['type'] params.update( {'hostdev_dict': params.get('hostdev_dict') % pci_to_addr})
def test_vf(): """ Detach/Reattach a vf when it is used in guest 1) Detach/reattach the device 2) Add the device to VM 3) Start the VM 4) Check driver of the device 5) Detach/reattach the device again """ logging.info("Initialize the vfs.") sriov_base.setup_vf(pf_pci, params) vf_pci = utils_sriov.get_vf_pci_id(pf_pci) pf_name = utils_sriov.get_pf_info_by_pci(pf_pci).get('iface') vf_mac = utils_sriov.get_vf_mac(pf_name, is_admin=False) logging.debug("VF's mac: %s.", vf_mac) logging.info("Check the vf's driver, it should not be vfio-pci.") dev_name = utils_sriov.get_device_name(vf_pci) check_driver_from_xml(dev_name) logging.info("Detach and reattach the device and check vf's mac.") nodedev_test(dev_name, no_reset=True) utils_misc.wait_for( lambda: libvirt_vfio.check_vfio_pci(vf_pci, True, True), 10, 5) compare_vf_mac(pf_name, vf_mac) logging.info("Cold-plug the device into the VM.") add_hostdev_iface(vm, vf_pci) vm.start() check_hostdev_iface(vm.name) logging.info("Check the device info. It should be vfio-pci.") check_driver_from_xml(dev_name, status_error=True) nodedev_test(dev_name, True) logging.info("Destroy the vm, and check the vf's mac is recovered.") vm.destroy(gracefully=False) compare_vf_mac(pf_name, vf_mac)
def test_duplicated_cust_alias(): """ Hotplug hostdev interface with duplicate custom alias """ vm.cleanup_serial_console() vm.create_serial_console() vm.wait_for_serial_login(timeout=240).close() alias_name = 'ua-' + str(uuid.uuid4()) hostdev_dict = eval( params.get('hostdev_iface_dict') % (utils_sriov.pci_to_addr(vf_pci), alias_name)) exec_test(vm, hostdev_dict, params) host_dev = vm_xml.VMXML.new_from_dumpxml(vm.name)\ .devices.by_device_tag("interface")[0] test.log.info("TEST_STEP3: Hotplug another hostdev interface with the" "same alias name") vf2_pci = utils_sriov.get_vf_pci_id(pf_pci, vf_index=1) hostdev_dict['hostdev_address']['attrs'] = utils_sriov.pci_to_addr( vf2_pci) host_dev2 = interface_base.create_iface('hostdev', hostdev_dict) result = virsh.attach_device(vm_name, host_dev2.xml, debug=True) libvirt.check_exit_status(result, True) test.log.info("TEST_STEP4: Detach the first hostdev interface.") virsh.detach_device(vm_name, host_dev.xml, wait_for_event=True, debug=True, ignore_status=False) test.log.info("TEST_STEP5: Attach the second hostdev interface again.") virsh.attach_device(vm_name, host_dev2.xml, debug=True, ignore_status=False) check_points.comp_hostdev_xml(vm, "interface", hostdev_dict)
def run(test, params, env): """ Test interfaces attached from network """ def test_at_dt(): """ Test attach-detach interfaces """ if not pf_status: logging.info("Set pf state to down.") pf_iface_obj = utils_net.Interface(pf_name) pf_iface_obj.down() logging.info("Define network - %s.", params.get("net_name")) create_network(params) logging.debug("Remove VM's interface devices.") libvirt_vmxml.remove_vm_devices_by_type(vm, 'interface') vm.start() vm_session = vm.wait_for_serial_login(timeout=240) logging.info("Hotplug an interface to VM.") iface_dict = { "model": "virtio", "source": { 'network': params.get("net_name") } } iface = create_iface(iface_dict) res = virsh.attach_device(vm_name, iface.xml, debug=True) libvirt.check_exit_status(res, status_error) if not pf_status: logging.info("Set pf state to up then check again.") pf_iface_obj.up() virsh.attach_device(vm_name, iface.xml, debug=True, ignore_status=False) libvirt_vmxml.check_guest_xml(vm.name, params["net_name"]) sriov_base.check_vm_network_accessed(vm_session) def test_connection(): """ Test network connections 1. Create a network 2. Attach the interfaces and check network connections 3. Check the network connections after detaching ifaces, restarting libvirtd and destroying the VM """ vf_no = int(params.get("vf_no", "4")) net_name = params.get("net_name") iface_type = params.get("iface_type") logging.info("Define network - %s.", net_name) create_network(params) libvirt_vmxml.remove_vm_devices_by_type(vm, 'interface') libvirt_pcicontr.reset_pci_num(vm_name) vm.start() vm.wait_for_serial_login(timeout=240) logging.info("Attach 4 interfaces to the guest.") opts = ' '.join( ["network", net_name, params.get('attach_extra_opts', "")]) for i in range(vf_no): virsh.attach_interface(vm_name, option=opts, debug=True, ignore_status=False) libvirt_network.check_network_connection(net_name, i + 1) logging.info("Try to attach one more interface.") res = virsh.attach_interface(vm_name, option=opts, debug=True) libvirt.check_exit_status(res, True) logging.info("Detach an interface.") vm_ifaces = [ iface for iface in vm_xml.VMXML.new_from_dumpxml( vm_name).devices.by_device_tag("interface") ] mac_addr = vm_ifaces[0].get_mac_address() opts = ' '.join([iface_type, "--mac %s" % mac_addr]) virsh.detach_interface(vm_name, option=opts, debug=True, wait_for_event=True, ignore_status=False) libvirt_network.check_network_connection(net_name, vf_no - 1) logging.info( "Restart libvirtd service and check the network connection.") utils_libvirtd.Libvirtd().restart() libvirt_network.check_network_connection(net_name, vf_no - 1) logging.info("Destroy the VM and check the network connection.") vm.destroy(gracefully=False) libvirt_network.check_network_connection(net_name, 0) test_case = params.get("test_case", "") run_test = eval("test_%s" % test_case) status_error = "yes" == params.get("status_error", "no") vm_name = params.get("main_vm", "avocado-vt-vm1") vm = env.get_vm(vm_name) pf_pci = utils_sriov.get_pf_pci() if not pf_pci: test.cancel("NO available pf found.") sriov_base.setup_vf(pf_pci, params) vf_pci = utils_sriov.get_vf_pci_id(pf_pci) params['vf_iface'] = utils_sriov.get_iface_name(vf_pci) pf_status = "active" == params.get("pf_status", "active") pf_name = utils_sriov.get_pf_info_by_pci(pf_pci).get('iface') params['pf_name'] = pf_name vmxml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name) orig_config_xml = vmxml.copy() try: run_test() finally: logging.info("Recover test enviroment.") if not pf_status: pf_iface_obj = utils_net.Interface(pf_name) pf_iface_obj.up() sriov_base.recover_vf(pf_pci, params) if vm.is_alive(): vm.destroy(gracefully=False) orig_config_xml.sync() libvirt_network.create_or_del_network( {"net_name": params.get("net_name")}, True)
def run(test, params, env): """ SR-IOV: managed related test. """ def start_vm(vm, test_login=False, destroy_vm=False): """ Start up VM :param vm: The vm object :param test_login: Whether to login VM :param destroy_vm: Whether to destroy VM """ if vm.is_alive(): vm.destroy() vm.start() if test_login: vm.wait_for_serial_login(timeout=180).close() if destroy_vm: vm.destroy() def create_vf_pool(): """ Create VF pool """ net_hostdev_dict = { "net_name": params.get("net_name"), "net_forward": params.get("net_forward"), "vf_list_attrs": "[%s]" % utils_sriov.pci_to_addr(vf_pci) } libvirt_network.create_or_del_network(net_hostdev_dict) def check_vm_iface_managed(vm_name, iface_dict): """ Check 'managed' in VM's iface :param vm_name: Name of VM :param iface_dict: The parameters dict :raise: TestFail if not match """ vm_iface_managed = [ iface.get("managed") for iface in vm_xml.VMXML.new_from_dumpxml( vm_name).devices.by_device_tag("interface") ][0] expr_managed = "yes" if iface_dict.get("managed", "") == "yes" else None if vm_iface_managed != expr_managed: test.fail("Unable to get the expected managed! Actual: %s, " "Expected: %s." % (vm_iface_managed, expr_managed)) def test_networks(): """ Start vm with VF from VF Pool with "managed=no" or default setting 1) Create VF pool 2) Prepare device xml and hot-plug to the guest 3) Detach the device from host 4) Check the driver of device 5) Start VM 6) Destroy vm then check the driver 7) Reattach the device to the host and check the driver """ create_vf_pool() libvirt_vfio.check_vfio_pci(vf_pci, status_error=True) iface_dict = { "type": "network", "source": "{'network': '%s'}" % params.get("net_name") } libvirt.modify_vm_iface(vm.name, "update_iface", iface_dict) res = virsh.start(vm.name, debug=True) libvirt.check_exit_status(res, True) virsh.nodedev_detach(dev_name, debug=True, ignore_status=False) libvirt_vfio.check_vfio_pci(vf_pci) start_vm(vm, True, True) libvirt_vfio.check_vfio_pci(vf_pci) virsh.nodedev_reattach(dev_name, debug=True, ignore_status=False) libvirt_vfio.check_vfio_pci(vf_pci, status_error=True) def test_device_hotplug(): """ Hotplug/unplug VF with managed='no' 1) Prepare a running guest 2) Check the driver of vf on host 3) Prepare a xml with "managed=no"and attach to guest 4) Detach the device from host 5) Check the driver of vf on host 6) Attach the device to guest 7) Check the interface of the guest 8) Detach the device from guest and check the driver 9) Reattach the device to the host and check the driver """ libvirt_vmxml.remove_vm_devices_by_type(vm, 'interface') start_vm(vm) libvirt_vfio.check_vfio_pci(vf_pci, status_error=True) mac_addr = utils_net.generate_mac_address_simple() iface_dict = eval( params.get('iface_dict', '{"hostdev_addr": "%s"}') % utils_sriov.pci_to_addr(vf_pci)) iface = interface.Interface("hostdev") iface.xml = libvirt.modify_vm_iface(vm.name, "get_xml", iface_dict) res = virsh.attach_device(vm_name, iface.xml, debug=True) libvirt.check_exit_status(res, True) virsh.nodedev_detach(dev_name, debug=True, ignore_status=False) libvirt_vfio.check_vfio_pci(vf_pci) virsh.attach_device(vm_name, iface.xml, debug=True, ignore_status=False) check_vm_iface_managed(vm_name, iface_dict) vm.wait_for_serial_login().close() virsh.detach_device(vm_name, iface.xml, wait_remove_event=True, debug=True, ignore_status=False) libvirt_vfio.check_vfio_pci(vf_pci) virsh.nodedev_reattach(dev_name, debug=True, ignore_status=False) libvirt_vfio.check_vfio_pci(vf_pci, status_error=True) test_case = params.get("test_case", "") run_test = eval("test_%s" % test_case) vm_name = params.get("main_vm", "avocado-vt-vm1") vm = env.get_vm(vm_name) pf_pci = utils_sriov.get_pf_pci() if not pf_pci: test.cancel("NO available pf found.") default_vf = sriov_base.setup_vf(pf_pci, params) vf_pci = utils_sriov.get_vf_pci_id(pf_pci) dev_name = utils_sriov.get_device_name(vf_pci) vmxml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name) orig_config_xml = vmxml.copy() try: run_test() finally: logging.info("Recover test enviroment.") sriov_base.recover_vf(pf_pci, params, default_vf) if vm.is_alive(): vm.destroy(gracefully=False) orig_config_xml.sync() libvirt_network.create_or_del_network( {"net_name": params.get("net_name")}, True) virsh.nodedev_reattach(dev_name, debug=True)
def run(test, params, env): """ Test when the PCI configuration file is in read-only mode """ def test_vf_hotplug(): """ Hot-plug VF to VM """ logging.info("Preparing a running guest...") libvirt_vmxml.remove_vm_devices_by_type(vm, 'interface') vm.start() vm_session = vm.wait_for_serial_login(timeout=180) logging.info("Attaching VF to the guest...") mac_addr = utils_net.generate_mac_address_simple() iface_dict = eval( params.get('iface_dict', '{"hostdev_addr": "%s"}') % utils_sriov.pci_to_addr(vf_pci)) iface = interface.Interface("hostdev") iface.xml = libvirt.modify_vm_iface(vm.name, "get_xml", iface_dict) virsh.attach_device(vm_name, iface.xml, debug=True, ignore_status=False) logging.info("Checking VF in the guest...") vm_iface_types = [ iface.get_type_name() for iface in vm_xml.VMXML.new_from_dumpxml( vm_name).devices.by_device_tag("interface") ] if 'hostdev' not in vm_iface_types: test.fail('Unable to get hostdev interface!') if cmd_in_vm: if not utils_misc.wait_for( lambda: not vm_session.cmd_status(cmd_in_vm), 30, 10): test.fail("Can not get the Virtual Function info on vm!") vm_session.close() libvirt_version.is_libvirt_feature_supported(params) test_case = params.get("test_case", "") run_test = eval("test_%s" % test_case) cmd_in_vm = params.get("cmd_in_vm") vm_name = params.get("main_vm", "avocado-vt-vm1") vm = env.get_vm(vm_name) pf_pci = utils_sriov.get_pf_pci() if not pf_pci: test.cancel("NO available pf found.") default_vf = sriov_base.setup_vf(pf_pci, params) vf_pci = utils_sriov.get_vf_pci_id(pf_pci) dev_name = utils_sriov.get_device_name(vf_pci) vmxml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name) orig_config_xml = vmxml.copy() libvirtd = utils_libvirtd.Libvirtd('virtqemud') try: virsh.nodedev_detach(dev_name, debug=True, ignore_status=False) logging.info("Re-mounting sysfs with ro mode...") utils_misc.mount('/sys', '', None, 'remount,ro') libvirtd.restart() run_test() finally: logging.info("Recover test enviroment.") utils_misc.mount('/sys', '', None, 'remount,rw') sriov_base.recover_vf(pf_pci, params, default_vf) if vm.is_alive(): vm.destroy(gracefully=False) orig_config_xml.sync() virsh.nodedev_reattach(dev_name, debug=True)
def run(test, params, env): """ Sriov net failover related test. """ def setup_hotplug_hostdev_iface_with_teaming(): logging.info("Create hostdev network.") net_hostdev_fwd = params.get("net_hostdev_fwd", '{"mode": "hostdev", "managed": "yes"}') net_hostdev_dict = { "net_name": net_hostdev_name, "net_forward": net_hostdev_fwd, "net_forward_pf": '{"dev": "%s"}' % pf_name } libvirt_network.create_or_del_network(net_hostdev_dict) logging.info("Clear up VM interface.") libvirt_vmxml.remove_vm_devices_by_type(vm, 'interface') iface = interface.Interface("network") iface.xml = create_bridge_iface_xml(vm, mac_addr, params) virsh.attach_device(vm_name, iface.xml, flagstr='--persistent', debug=True, ignore_status=False) vm.start() vm.wait_for_serial_login(timeout=180).close() def teardown_hotplug_hostdev_iface_with_teaming(): logging.info("Delete hostdev network.") net_hostdev_dict = {"net_name": net_hostdev_name} libvirt_network.create_or_del_network(net_hostdev_dict, is_del=True) def test_hotplug_hostdev_iface_with_teaming(): logging.info("Attach a hostdev interface.") hostdev_iface_xml = create_hostdev_iface_xml(vm, mac_addr, params) virsh.attach_device(vm_name, hostdev_iface_xml, debug=True, ignore_status=False) check_ifaces(vm_name, expected_ifaces={"bridge", "hostdev"}) vm_session = vm.wait_for_serial_login(timeout=240) ping_ip = get_ping_dest(vm_session, mac_addr) check_vm_network_accessed(vm_session, ping_dest=ping_ip, tcpdump_iface=bridge_name, tcpdump_status_error=True) logging.info("Detach the hostdev interface.") hostdev_iface = interface.Interface("network") for ifc in vm_xml.VMXML.new_from_dumpxml( vm_name).devices.by_device_tag("interface"): if ifc.type_name == "hostdev": ifc.del_address() hostdev_iface = ifc virsh.detach_device(vm_name, hostdev_iface.xml, wait_remove_event=True, debug=True, ignore_status=False) check_ifaces(vm_name, expected_ifaces={"hostdev"}, status_error=True) check_vm_network_accessed(vm_session, 2, ping_dest=ping_ip, tcpdump_iface=bridge_name, tcpdump_status_error=False) libvirt_vfio.check_vfio_pci(vf_pci, status_error=True) logging.info("Re-attach the hostdev interface.") virsh.attach_device(vm_name, hostdev_iface.xml, debug=True, ignore_status=False) check_vm_network_accessed(vm_session, ping_dest=ping_ip, tcpdump_iface=bridge_name, tcpdump_status_error=True) def setup_hotplug_hostdev_device_with_teaming(): libvirt_vmxml.remove_vm_devices_by_type(vm, 'interface') vm.start() vm.wait_for_serial_login(timeout=240).close() def test_hotplug_hostdev_device_with_teaming(): default_vf_mac = utils_sriov.get_vf_mac(pf_name) utils_sriov.set_vf_mac(pf_name, mac_addr) logging.info("Attach the bridge interface.") brg_iface_xml = create_bridge_iface_xml(vm, mac_addr, params) virsh.attach_device(vm_name, brg_iface_xml, debug=True, ignore_status=False) # Wait for 10s before attaching the hostdev device time.sleep(10) logging.info("Attach the hostdev device.") hostdev_dev = libvirt.create_hostdev_xml(vf_pci, teaming=hostdev_teaming_dict) virsh.attach_device(vm_name, hostdev_dev.xml, debug=True, ignore_status=False) vm_session = vm.wait_for_serial_login(timeout=240) ping_ip = get_ping_dest(vm_session, mac_addr) check_vm_network_accessed(vm_session, ping_dest=ping_ip, tcpdump_iface=bridge_name, tcpdump_status_error=True) logging.info("Detach the hostdev device.") virsh.detach_device(vm_name, hostdev_dev.xml, wait_remove_event=True, debug=True, ignore_status=False) logging.debug("Recover vf's mac to %s.", default_vf_mac) utils_sriov.set_vf_mac(pf_name, default_vf_mac) check_hostdev = vm_xml.VMXML.new_from_dumpxml(vm_name)\ .devices.by_device_tag('hostdev') if check_hostdev: test.fail("The hostdev device exists after detaching %s." % check_hostdev) libvirt_vfio.check_vfio_pci(vf_pci, status_error=True) check_vm_network_accessed(vm_session, 2, ping_dest=ping_ip, tcpdump_iface=bridge_name, tcpdump_status_error=False) def setup_save_restore_hostdev_device_with_teaming(): logging.info("Start a VM with bridge iface and hostdev device.") libvirt_vmxml.remove_vm_devices_by_type(vm, 'interface') vmxml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name) iface = interface.Interface("network") iface.xml = create_bridge_iface_xml(vm, mac_addr, params) vmxml.add_device(iface) hostdev_dev = libvirt.create_hostdev_xml(vf_pci, teaming=hostdev_teaming_dict) vmxml.add_device(hostdev_dev) vmxml.sync() vm.start() utils_sriov.set_vf_mac(pf_name, mac_addr) vm.wait_for_serial_login(timeout=240).close() def test_save_restore_hostdev_device_with_teaming(): logging.info("Save/restore VM.") save_file = os.path.join(data_dir.get_tmp_dir(), "save_file") virsh.save(vm_name, save_file, debug=True, ignore_status=False, timeout=10) if not libvirt.check_vm_state(vm_name, "shut off"): test.fail("The guest should be down after executing 'virsh save'.") virsh.restore(save_file, debug=True, ignore_status=False) if not libvirt.check_vm_state(vm_name, "running"): test.fail( "The guest should be running after executing 'virsh restore'.") vm.cleanup_serial_console() vm.create_serial_console() vm_session = vm.wait_for_serial_login() ping_ip = get_ping_dest(vm_session, mac_addr) check_vm_network_accessed(vm_session, ping_dest=ping_ip, tcpdump_iface=bridge_name, tcpdump_status_error=True) logging.info("Detach the hostdev device.") hostdev_dev = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name).devices.\ by_device_tag("hostdev") virsh.detach_device(vm_name, hostdev_dev.xml, wait_remove_event=True, debug=True, ignore_status=False) check_hostdev = vm_xml.VMXML.new_from_dumpxml(vm_name)\ .devices.by_device_tag('hostdev') if check_hostdev: test.fail("The hostdev device exists after detaching %s." % check_hostdev) check_vm_network_accessed(vm_session, 2, ping_dest=ping_ip, tcpdump_iface=bridge_name, tcpdump_status_error=False) logging.info("Attach the hostdev device.") virsh.attach_device(vm_name, hostdev_dev.xml, debug=True, ignore_status=False) check_vm_network_accessed(vm_session, ping_dest=ping_ip, tcpdump_iface=bridge_name, tcpdump_status_error=True) def setup_save_restore_hostdev_iface_with_teaming(): logging.info("Create hostdev network.") net_hostdev_fwd = params.get("net_hostdev_fwd", '{"mode": "hostdev", "managed": "yes"}') net_hostdev_dict = { "net_name": net_hostdev_name, "net_forward": net_hostdev_fwd, "net_forward_pf": '{"dev": "%s"}' % pf_name } libvirt_network.create_or_del_network(net_hostdev_dict) libvirt_vmxml.remove_vm_devices_by_type(vm, 'interface') vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name) iface = interface.Interface("network") iface.xml = create_bridge_iface_xml(vm, mac_addr, params) vmxml.add_device(iface) iface.xml = create_hostdev_iface_xml(vm, mac_addr, params) vmxml.add_device(iface) vmxml.sync() logging.debug("VMXML after updating ifaces: %s.", vm_xml.VMXML.new_from_dumpxml(vm_name)) vm.start() vm_session = vm.wait_for_serial_login(timeout=240) ping_ip = get_ping_dest(vm_session, mac_addr) check_vm_network_accessed(vm_session, ping_dest=ping_ip, tcpdump_iface=bridge_name, tcpdump_status_error=True) def teardown_save_restore_hostdev_iface_with_teaming(): teardown_hotplug_hostdev_iface_with_teaming() def test_save_restore_hostdev_iface_with_teaming(): logging.info("Save/restore VM.") save_file = os.path.join(data_dir.get_tmp_dir(), "save_file") virsh.save(vm_name, save_file, debug=True, ignore_status=False, timeout=10) if not libvirt.check_vm_state(vm_name, "shut off"): test.fail("The guest should be down after executing 'virsh save'.") virsh.restore(save_file, debug=True, ignore_status=False) if not libvirt.check_vm_state(vm_name, "running"): test.fail( "The guest should be running after executing 'virsh restore'.") vm.cleanup_serial_console() vm.create_serial_console() vm_session = vm.wait_for_serial_login(timeout=240) ping_ip = get_ping_dest(vm_session, mac_addr, False) logging.debug(ping_ip) check_vm_network_accessed(vm_session, ping_dest=ping_ip, tcpdump_iface=bridge_name, tcpdump_status_error=True) def check_vm_iface_num(session, exp_num=3): """ Check he number of interfaces :param session: The session to the guest :param exp_num: The expected number :return: True when interfaces' number is equal to exp_num """ p_iface = utils_net.get_remote_host_net_ifs(session)[0] logging.debug("Ifaces in VM: %s", p_iface) return len(p_iface) == exp_num def check_vm_network_accessed(vm_session, expected_iface_no=3, ping_dest="8.8.8.8", timeout=30, tcpdump_iface=None, tcpdump_status_error=False): """ Test VM's network by checking ifaces' number and the accessibility :param vm_session: The session object to the guest :param expected_iface_no: The expected number of ifaces :param ping_dest: The destination to be ping :param timeout: The timeout of the checking :param tcpdump_iface: The interface to check :param tcpdump_status_error: Whether the tcpdump's output should include the string "ICMP echo request" :raise: test.fail when ifaces' number is incorrect or ping fails. """ if not utils_misc.wait_for( lambda: check_vm_iface_num(vm_session, expected_iface_no), first=3, timeout=timeout): test.fail("%d interfaces should be found on the vm." % expected_iface_no) if tcpdump_iface: cmd = "tcpdump -i %s icmp" % tcpdump_iface tcpdump_session = aexpect.ShellSession('bash') tcpdump_session.sendline(cmd) if not utils_misc.wait_for( lambda: not utils_test.ping(ping_dest, count=3, timeout=5, output_func=logging.debug, session=vm_session)[0], first=5, timeout=timeout): test.fail("Failed to ping %s." % ping_dest) if tcpdump_iface: output = tcpdump_session.get_stripped_output() logging.debug("tcpdump's output: %s.", output) pat_str = "ICMP echo request" if re.search(pat_str, output): if tcpdump_status_error: test.fail( "Get incorrect tcpdump output: {}, it should not " "include '{}'.".format(output, pat_str)) else: if not tcpdump_status_error: test.fail("Get incorrect tcpdump output: {}, it should " "include '{}'.".format(output, pat_str)) def get_ping_dest(vm_session, mac_addr, restart_network=True): """ Get an ip address to ping :param vm_session: The session object to the guest :param mac_addr: mac address of given interface :param restart_network: Whether to restart guest's network :return: ip address """ if restart_network: utils_misc.cmd_status_output("dhclient -r; sleep 5; dhclient", shell=True, session=vm_session) vm_iface_info = utils_net.get_linux_iface_info( mac_addr, vm_session)['addr_info'][0]['local'] return re.sub('\d+$', '1', vm_iface_info) def create_bridge_iface_xml(vm, mac_addr, params): """ Create xml of bridge interface :param vm: The vm object :param mac_address: The mac address :param params: Dictionary with the test parameters :return: The interface xml """ net_bridge_name = params.get("net_bridge_name", "host-bridge") iface_bridge_dict = { "type": "network", "source": "{'network': '%s'}" % net_bridge_name, "mac": mac_addr, "model": "virtio", "teaming": '{"type":"persistent"}', "alias": '{"name": "ua-backup0"}' } return libvirt.modify_vm_iface(vm.name, "get_xml", iface_bridge_dict) def create_hostdev_iface_xml(vm, mac_addr, params): """ Create xml of hostdev interface :param vm: The vm object :param mac_address: The mac address :param params: Dictionary with the test parameters :return: The interface xml """ net_hostdev_name = params.get("net_hostdev_name", "hostdev-net") hostdev_iface_dict = { "type": "network", "source": "{'network': '%s'}" % net_hostdev_name, "mac": mac_addr, "teaming": '{"type":"transient", "persistent": "ua-backup0"}' } return libvirt.modify_vm_iface(vm.name, "get_xml", hostdev_iface_dict, 4) def check_ifaces(vm_name, expected_ifaces={"bridge", "hostdev"}, status_error=False): """ Check VM's interfaces :param vm_name: The name of VM :param expected_ifaces: The expected interfaces :param status_error: Whether the ifaces should be same with the expected_ifaces :raise: test.fail if the interface(s) is(are) as expected """ if not expected_ifaces: return else: expected_ifaces = set(expected_ifaces) vm_ifaces = [ iface for iface in vm_xml.VMXML.new_from_dumpxml( vm_name).devices.by_device_tag("interface") ] ifaces_net = {iface.get_type_name() for iface in vm_ifaces} if expected_ifaces.issubset(ifaces_net) == status_error: test.fail( "Unable to get expected interface. The interface %s " "should%s be %s." % (ifaces_net, ' not' if status_error else '', expected_ifaces)) else: logging.debug("{}Found iface(s) as expected: {}.".format( 'Not ' if status_error else '', expected_ifaces)) test_case = params.get("test_case", "") run_test = eval("test_%s" % test_case) setup_test = eval("setup_%s" % test_case) if "setup_%s" % test_case in \ locals() else "setup_%s" % test_case teardown_test = eval("teardown_%s" % test_case) if "teardown_%s" % \ test_case in locals() else "teardown_%s" % test_case vm_name = params.get("main_vm", "avocado-vt-vm1") vm = env.get_vm(params["main_vm"]) driver = params.get("driver", "ixgbe") bridge_name = params.get("bridge_name", "br0") net_bridge_name = params.get("net_bridge_name", "host-bridge") net_bridge_fwd = params.get("net_bridge_fwd", '{"mode": "bridge"}') net_hostdev_name = params.get("net_hostdev_name", "hostdev-net") bridge_name = params.get("bridge_name", "br0") hostdev_teaming_dict = params.get("hostdev_device_teaming_dict", '{}') default_vf = 0 try: vf_no = int(params.get("vf_no", "4")) except ValueError as e: test.error(e) libvirt_version.is_libvirt_feature_supported(params) mac_addr = utils_net.generate_mac_address_simple() pf_pci = utils_sriov.get_pf_pci() if not pf_pci: test.cancel("NO available pf found.") pf_name = utils_sriov.get_pf_info_by_pci(pf_pci).get('iface') brg_dict = {'pf_name': pf_name, 'bridge_name': bridge_name} bridge_dict = { "net_name": net_bridge_name, "net_forward": net_bridge_fwd, "net_bridge": '{"name": "%s"}' % bridge_name } pf_pci_path = utils_misc.get_pci_path(pf_pci) cmd = "cat %s/sriov_numvfs" % (pf_pci_path) default_vf = process.run(cmd, shell=True, verbose=True).stdout_text new_xml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name) orig_config_xml = new_xml.copy() try: if not utils_sriov.set_vf(pf_pci_path, vf_no): test.error("Failed to set vf.") utils_sriov.add_or_del_connection(brg_dict, is_del=False) libvirt_network.create_or_del_network(bridge_dict) vf_pci = utils_sriov.get_vf_pci_id(pf_pci) exec_function(setup_test) run_test() finally: logging.info("Recover test enviroment.") utils_sriov.add_or_del_connection(brg_dict, is_del=True) libvirt_network.create_or_del_network(bridge_dict, is_del=True) if 'pf_pci_path' in locals() and default_vf != vf_no: utils_sriov.set_vf(pf_pci_path, default_vf) if vm.is_alive(): vm.destroy(gracefully=False) try: orig_config_xml.sync() except: # FIXME: Workaround for 'save'/'managedsave' hanging issue utils_libvirtd.Libvirtd().restart() orig_config_xml.sync() exec_function(teardown_test)
def run(test, params, env): """ Test VFs when PF is down """ def setup_default(): """ Default setup """ test.log.info("Set pf state to down.") pf_iface_obj = utils_net.Interface(pf_name) pf_iface_obj.down() def teardown_default(): """ Default cleanup """ pf_iface_obj = utils_net.Interface(pf_name) pf_iface_obj.up() def test_at_dt(): """ Test attach-detach interfaces """ options = '' if vm.is_alive() else '--config' iface_dict = eval(params.get('iface_dict') % utils_sriov.pci_to_addr(vf_pci)) iface = interface_base.create_iface('hostdev', iface_dict) result = virsh.attach_device(vm_name, iface.xml, flagstr=options, debug=True) if not start_vm: result = virsh.start(vm.name, debug=True) libvirt.check_exit_status(result, status_error) if error_msg: libvirt.check_result(result, error_msg) test_case = params.get("test_case", "") run_test = eval("test_%s" % test_case) start_vm = "yes" == params.get("start_vm") status_error = "yes" == params.get("status_error", "no") error_msg = params.get("error_msg") vm_name = params.get("main_vm", "avocado-vt-vm1") vm = env.get_vm(vm_name) pf_pci = utils_sriov.get_pf_pci() if not pf_pci: test.cancel("NO available pf found.") sriov_base.setup_vf(pf_pci, params) vf_pci = utils_sriov.get_vf_pci_id(pf_pci) pf_name = utils_sriov.get_pf_info_by_pci(pf_pci).get('iface') setup_test = eval("setup_%s" % test_case) if "setup_%s" % test_case in \ locals() else setup_default teardown_test = eval("teardown_%s" % test_case) if "teardown_%s" % \ test_case in locals() else teardown_default vmxml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name) orig_config_xml = vmxml.copy() try: setup_test() run_test() finally: test.log.info("Recover test enviroment.") orig_config_xml.sync() teardown_test()
def run(test, params, env): """ Test hostdev attach/detach """ def setup_default(): """ Default setup """ test.log.info("TEST_SETUP: Clear up VM interface(s).") libvirt_vmxml.remove_vm_devices_by_type(vm, 'interface') def teardown_default(): """ Default cleanup """ test.log.info("TEST_TEARDOWN: Recover test enviroment.") orig_config_xml.sync() sriov_base.recover_vf(pf_pci, params, 0) def exec_test(vm, hostdev_dict, params): """ Execute basic test :param vm: VM object :param hostdev_dict: Hostdev attrs :param params: Test parameters """ start_vm = "yes" == params.get("start_vm") options = '' if vm.is_alive() else '--config' status_error = "yes" == params.get("status_error", "no") error_msg = params.get("error_msg") host_dev = create_dev(params, hostdev_dict) test.log.debug("Hostdev XML: %s.", host_dev) test.log.info("TEST_STEP1: Attach hostdev interface.") result = virsh.attach_device(vm_name, host_dev.xml, flagstr=options, debug=True) libvirt.check_exit_status(result, status_error) if error_msg: libvirt.check_result(result, error_msg) if status_error: return if not start_vm: vm.start() vm.wait_for_serial_login(timeout=240).close() test.log.info("TEST_STEP2: Check VM XML.") device_type = "interface" if params.get( 'hostdev_iface_dict') else 'hostdev' check_points.comp_hostdev_xml(vm, device_type, hostdev_dict) def test_unassigned_address(): """ Cold/Hot plug hostdev interface with 'unassigned' address type """ hostdev_dict = get_hostdev_dict(vf_pci, params) exec_test(vm, hostdev_dict, params) if params.get("status_error") == "yes": return test.log.info("Check if the VM is not using VF.") libvirt_vfio.check_vfio_pci(vf_pci) vm.cleanup_serial_console() vm.create_serial_console() vm_session = vm.wait_for_serial_login(timeout=240) p_iface = utils_net.get_remote_host_net_ifs(vm_session)[0] if p_iface: test.fail("There should be no interface, but got %s." % p_iface) def test_duplicated_cust_alias(): """ Hotplug hostdev interface with duplicate custom alias """ vm.cleanup_serial_console() vm.create_serial_console() vm.wait_for_serial_login(timeout=240).close() alias_name = 'ua-' + str(uuid.uuid4()) hostdev_dict = eval( params.get('hostdev_iface_dict') % (utils_sriov.pci_to_addr(vf_pci), alias_name)) exec_test(vm, hostdev_dict, params) host_dev = vm_xml.VMXML.new_from_dumpxml(vm.name)\ .devices.by_device_tag("interface")[0] test.log.info("TEST_STEP3: Hotplug another hostdev interface with the" "same alias name") vf2_pci = utils_sriov.get_vf_pci_id(pf_pci, vf_index=1) hostdev_dict['hostdev_address']['attrs'] = utils_sriov.pci_to_addr( vf2_pci) host_dev2 = interface_base.create_iface('hostdev', hostdev_dict) result = virsh.attach_device(vm_name, host_dev2.xml, debug=True) libvirt.check_exit_status(result, True) test.log.info("TEST_STEP4: Detach the first hostdev interface.") virsh.detach_device(vm_name, host_dev.xml, wait_for_event=True, debug=True, ignore_status=False) test.log.info("TEST_STEP5: Attach the second hostdev interface again.") virsh.attach_device(vm_name, host_dev2.xml, debug=True, ignore_status=False) check_points.comp_hostdev_xml(vm, "interface", hostdev_dict) libvirt_version.is_libvirt_feature_supported(params) test_case = params.get("test_case", "") run_test = eval("test_%s" % test_case) vm_name = params.get("main_vm", "avocado-vt-vm1") vm = env.get_vm(vm_name) pf_pci = utils_sriov.get_pf_pci() if not pf_pci: test.cancel("NO available pf found.") sriov_base.setup_vf(pf_pci, params) vf_pci = utils_sriov.get_vf_pci_id(pf_pci) setup_test = eval("setup_%s" % test_case) if "setup_%s" % test_case in \ locals() else setup_default teardown_test = eval("teardown_%s" % test_case) if "teardown_%s" % \ test_case in locals() else teardown_default vmxml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name) orig_config_xml = vmxml.copy() try: test.log.info("TEST_CASE: %s", run_test.__doc__.lstrip().split('\n\n')[0]) setup_test() run_test() finally: teardown_test()
def run(test, params, env): """ Test virsh migrate command. """ def check_vm_network_accessed(session=None, ping_dest="8.8.8.8"): """ The operations to the VM need to be done before or after migration happens :param session: The session object to the host :param ping_dest: The destination to be ping :raise: test.fail when ping fails """ # Confirm local/remote VM can be accessed through network. logging.info("Check VM network connectivity") status, output = utils_test.ping(ping_dest, count=10, timeout=20, output_func=logging.debug, session=session) if status != 0: test.fail("Ping failed, status: %s," " output: %s" % (status, output)) def get_vm_ifaces(session=None): """ Get interfaces of vm :param session: The session object to the host :return: interfaces """ p_iface, v_iface = utils_net.get_remote_host_net_ifs(session) return p_iface def check_vm_iface_num(iface_list, exp_num=3): """ Check he number of interfaces :param iface_list: The interface list :param exp_num: The expected number :raise: test.fail when interfaces' number is not equal to exp_num """ if len(iface_list) != exp_num: test.fail("%d interfaces should be found on the vm, " "but find %s." % (exp_num, iface_list)) def create_or_del_networks(pf_name, params, remote_virsh_session=None, is_del=False): """ Create or delete network on local or remote :param params: Dictionary with the test parameters :param pf_name: The name of PF :param remote_virsh_session: The virsh session object to the remote host :param is_del: Whether the networks should be deleted :raise: test.fail when fails to define/start network """ net_bridge_name = params.get("net_bridge_name", "host-bridge") net_bridge_fwd = params.get("net_bridge_fwd", '{"mode": "bridge"}') bridge_name = params.get("bridge_name", "br0") bridge_dict = {"net_name": net_bridge_name, "net_forward": net_bridge_fwd, "net_bridge": '{"name": "%s"}' % bridge_name} net_list = [bridge_dict] enable_hostdev_iface = "yes" == params.get("enable_hostdev_iface", "no") if enable_hostdev_iface: net_hostdev_name = params.get("net_hostdev_name", "hostdev-net") net_hostdev_fwd = params.get("net_hostdev_fwd", '{"mode": "hostdev", "managed": "yes"}') net_dict = {"net_name": net_hostdev_name, "net_forward": net_hostdev_fwd, "net_forward_pf": '{"dev": "%s"}' % pf_name} net_list.append(net_dict) if not is_del: for net_params in net_list: net_dev = libvirt.create_net_xml(net_params.get("net_name"), net_params) if not remote_virsh_session: if net_dev.get_active(): net_dev.undefine() net_dev.define() net_dev.start() else: remote.scp_to_remote(server_ip, '22', server_user, server_pwd, net_dev.xml, net_dev.xml, limit="", log_filename=None, timeout=600, interface=None) remote_virsh_session.net_define(net_dev.xml, **virsh_args) remote_virsh_session.net_start(net_params.get("net_name"), **virsh_args) else: virsh_session = virsh if remote_virsh_session: virsh_session = remote_virsh_session for nname in [n_dict.get("net_name") for n_dict in net_list]: if nname not in virsh_session.net_state_dict(): continue virsh_session.net_destroy(nname, debug=True, ignore_status=True) virsh_session.net_undefine(nname, debug=True, ignore_status=True) def check_vm_network_connection(net_name, expected_conn=0): """ Check network connections in network xml :param net_name: The network to be checked :param expected_conn: The expected value :raise: test.fail when fails """ output = virsh.net_dumpxml(net_name, debug=True).stdout_text if expected_conn == 0: reg_pattern = r"<network>" else: reg_pattern = r"<network connections='(\d)'>" res = re.findall(reg_pattern, output, re.I) if not res: test.fail("Unable to find expected connection in %s." % net_name) if expected_conn != 0: if expected_conn != int(res[0]): test.fail("Unable to get expected connection number." "Expected: %s, Actual %s" % (expected_conn, int(res[0]))) def get_hostdev_addr_from_xml(): """ Get VM hostdev address :return: pci driver id """ address_dict = {} for ifac in vm_xml.VMXML.new_from_dumpxml(vm_name).devices.by_device_tag("interface"): if ifac.type_name == "hostdev": address_dict = ifac.hostdev_address.attrs return libvirt.pci_info_from_address(address_dict, 16, "id") def check_vfio_pci(pci_path, status_error=False): """ Check if vf driver is vfio-pci :param pci_path: The absolute path of pci device :param status_error: Whether the driver should be vfio-pci """ cmd = "readlink %s/driver | awk -F '/' '{print $NF}'" % pci_path output = process.run(cmd, shell=True, verbose=True).stdout_text.strip() if (output == "vfio-pci") == status_error: test.fail("Get incorrect driver %s, it should%s be vfio-pci." % (output, ' not' if status_error else '')) def update_iface_xml(vmxml, enable_hostdev_iface): """ Update interfaces for guest :param vmxml: vm_xml.VMXML object """ vmxml.remove_all_device_by_type('interface') vmxml.sync() iface_list = [] iface_dict = {"type": "network", "source": "{'network': 'host-bridge'}", "mac": mac_addr, "model": "virtio", "teaming": '{"type":"persistent"}', "alias": '{"name": "ua-backup0"}', "inbound": '{"average":"5"}', "outbound": '{"average":"5"}'} iface_list.append(iface_dict) if enable_hostdev_iface: iface_dict2 = {"type": "network", "source": "{'network': 'hostdev-net'}", "mac": mac_addr, "model": "virtio", "teaming": '{"type":"transient", \ "persistent": "ua-backup0"}'} iface_list.append(iface_dict2) iface = interface.Interface('network') for ifc in iface_list: iface.xml = libvirt.modify_vm_iface(vm.name, "get_xml", ifc) vmxml.add_device(iface) vmxml.sync() def add_hostdev_device(vm_name, pf_pci, params): """ Add a hostdev device to the guest :param vm_name: VM's name :param pf_pci: The PF's pci :param params: The parameters used """ vf_pci = utils_sriov.get_vf_pci_id(pf_pci) hostdev_teaming_dict = params.get("hostdev_device_teaming_dict", '{}') vmxml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name) hostdev_dev = libvirt.create_hostdev_xml(vf_pci, teaming=hostdev_teaming_dict) vmxml.add_device(hostdev_dev) vmxml.sync() migration_test = migration.MigrationTest() migration_test.check_parameters(params) # Params for NFS shared storage shared_storage = params.get("migrate_shared_storage", "") if shared_storage == "": default_guest_asset = defaults.get_default_guest_os_info()['asset'] default_guest_asset = "%s.qcow2" % default_guest_asset shared_storage = os.path.join(params.get("nfs_mount_dir"), default_guest_asset) logging.debug("shared_storage:%s", shared_storage) # Params to update disk using shared storage params["disk_type"] = "file" params["disk_source_protocol"] = "netfs" params["mnt_path_name"] = params.get("nfs_mount_dir") # Local variables virsh_args = {"debug": True} virsh_options = params.get("virsh_options", "") server_ip = params.get("server_ip") server_user = params.get("server_user", "root") server_pwd = params.get("server_pwd") client_ip = params.get("client_ip") client_pwd = params.get("client_pwd") extra = params.get("virsh_migrate_extra") options = params.get("virsh_migrate_options") bridge_name = params.get("bridge_name", "br0") net_hostdev_name = params.get("net_hostdev_name", "hostdev-net") net_bridge_name = params.get("net_bridge_name", "host-bridge") enable_hostdev_iface = "yes" == params.get("enable_hostdev_iface", "no") enable_hostdev_device = "yes" == params.get("enable_hostdev_device", "no") driver = params.get("driver", "ixgbe") vm_tmp_file = params.get("vm_tmp_file", "/tmp/test.txt") cmd_during_mig = params.get("cmd_during_mig") net_failover_test = "yes" == params.get("net_failover_test", "no") cancel_migration = "yes" == params.get("cancel_migration", "no") try: vf_no = int(params.get("vf_no", "4")) except ValueError as e: test.error(e) migr_vm_back = "yes" == params.get("migrate_vm_back", "no") err_msg = params.get("err_msg") status_error = "yes" == params.get("status_error", "no") cmd_parms = {'server_ip': server_ip, 'server_user': server_user, 'server_pwd': server_pwd} remote_virsh_dargs = {'remote_ip': server_ip, 'remote_user': server_user, 'remote_pwd': server_pwd, 'unprivileged_user': None, 'ssh_remote_auth': True} remote_dargs = {'server_ip': server_ip, 'server_user': server_user, 'server_pwd': server_pwd, 'file_path': "/etc/libvirt/libvirt.conf"} destparams_dict = copy.deepcopy(params) remote_virsh_session = None vm_session = None vm = None mig_result = None action_during_mig = None default_src_vf = 0 default_dest_vf = 0 default_src_rp_filter = 1 default_dest_rp_filer = 1 remove_dict = {} remote_libvirt_file = None src_libvirt_file = None libvirt_version.is_libvirt_feature_supported(params) # params for migration connection params["virsh_migrate_desturi"] = libvirt_vm.complete_uri( params.get("migrate_dest_host")) params["virsh_migrate_connect_uri"] = libvirt_vm.complete_uri( params.get("migrate_source_host")) src_uri = params.get("virsh_migrate_connect_uri") dest_uri = params.get("virsh_migrate_desturi") vm_name = params.get("migrate_main_vm") vm = env.get_vm(vm_name) vm.verify_alive() bk_uri = vm.connect_uri extra_args = migration_test.update_virsh_migrate_extra_args(params) # For safety reasons, we'd better back up xmlfile. new_xml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name) orig_config_xml = new_xml.copy() try: # Create a remote runner for later use runner_on_target = remote.RemoteRunner(host=server_ip, username=server_user, password=server_pwd) server_session = remote.wait_for_login('ssh', server_ip, '22', server_user, server_pwd, r"[\#\$]\s*$") if net_failover_test: src_pf, src_pf_pci = utils_sriov.find_pf(driver) logging.debug("src_pf is %s. src_pf_pci: %s", src_pf, src_pf_pci) params['pf_name'] = src_pf dest_pf, dest_pf_pci = utils_sriov.find_pf(driver, server_session) logging.debug("dest_pf is %s. dest_pf_pci: %s", dest_pf, dest_pf_pci) destparams_dict['pf_name'] = dest_pf src_pf_pci_path = utils_misc.get_pci_path(src_pf_pci) dest_pf_pci_path = utils_misc.get_pci_path(dest_pf_pci, server_session) cmd = "cat %s/sriov_numvfs" % (src_pf_pci_path) default_src_vf = process.run(cmd, shell=True, verbose=True).stdout_text cmd = "cat %s/sriov_numvfs" % (dest_pf_pci_path) status, default_dest_vf = utils_misc.cmd_status_output(cmd, shell=True, session=server_session) if status: test.error("Unable to get default sriov_numvfs on target!" "status: %s, output: %s" % (status, default_dest_vf)) if not utils_sriov.set_vf(src_pf_pci_path, vf_no): test.error("Failed to set vf on source.") if not utils_sriov.set_vf(dest_pf_pci_path, vf_no, session=server_session): test.error("Failed to set vf on target.") # Create PF and bridge connection on source and target host cmd = 'cat /proc/sys/net/ipv4/conf/all/rp_filter' default_src_rp_filter = process.run(cmd, shell=True, verbose=True).stdout_text status, default_dest_rp_filter = utils_misc.cmd_status_output(cmd, shell=True, session=server_session) if status: test.error("Unable to get default rp_filter on target!" "status: %s, output: %s" % (status, default_dest_rp_filter)) cmd = 'echo 0 >/proc/sys/net/ipv4/conf/all/rp_filter' process.run(cmd, shell=True, verbose=True) utils_misc.cmd_status_output(cmd, shell=True, session=server_session) if enable_hostdev_device: hostdev_pci_id = utils_sriov.get_vf_pci_id(src_pf_pci).strip() dest_vf_pci_id = utils_sriov.get_vf_pci_id( dest_pf_pci, session=server_session).strip() logging.debug("src_vf_pci_id:%s", hostdev_pci_id) logging.debug("dest_vf_pci_id:%s", dest_vf_pci_id) if dest_vf_pci_id != hostdev_pci_id: # TODO: Create migratable xml with the updated vf's pci address test.error("The pci address of vf is different on source " "host and target host.") utils_sriov.add_or_del_connection(params, is_del=False) utils_sriov.add_or_del_connection(destparams_dict, is_del=False, session=server_session) if not remote_virsh_session: remote_virsh_session = virsh.VirshPersistent(**remote_virsh_dargs) create_or_del_networks(dest_pf, params, remote_virsh_session=remote_virsh_session) remote_virsh_session.close_session() create_or_del_networks(src_pf, params) # Change network interface xml mac_addr = utils_net.generate_mac_address_simple() if enable_hostdev_device: utils_sriov.set_vf_mac(src_pf, mac_addr) utils_sriov.set_vf_mac(dest_pf, mac_addr, session=server_session) update_iface_xml(new_xml, enable_hostdev_iface) if enable_hostdev_device: add_hostdev_device(vm_name, src_pf_pci, params) # Change the disk of the vm libvirt.set_vm_disk(vm, params) if not vm.is_alive(): vm.start() # Check local guest network connection before migration if vm.serial_console is not None: vm.cleanup_serial_console() vm.create_serial_console() vm_session = vm.wait_for_serial_login(timeout=240) if net_failover_test: utils_net.restart_guest_network(vm_session) iface_list = get_vm_ifaces(vm_session) vm_ipv4, vm_ipv6 = utils_net.get_linux_ipaddr(vm_session, iface_list[0]) check_vm_network_accessed(ping_dest=vm_ipv4) if net_failover_test: check_vm_iface_num(iface_list) if enable_hostdev_iface: check_vm_network_connection(net_hostdev_name, 1) check_vm_network_connection(net_bridge_name, 1) if enable_hostdev_iface: hostdev_pci_id = get_hostdev_addr_from_xml() vf_path = utils_misc.get_pci_path(hostdev_pci_id) check_vfio_pci(vf_path) if cmd_during_mig: s, o = utils_misc.cmd_status_output(cmd_during_mig, shell=True, session=vm_session) if s: test.fail("Failed to run %s in vm." % cmd_during_mig) if extra.count("--postcopy"): action_during_mig = virsh.migrate_postcopy if cancel_migration: action_during_mig = virsh.domjobabort remove_dict = {"do_search": '{"%s": "ssh:/"}' % dest_uri} src_libvirt_file = libvirt_config.remove_key_for_modular_daemon( remove_dict) # Execute migration process vms = [vm] migration_test.do_migration(vms, None, dest_uri, 'orderly', options, thread_timeout=900, ignore_status=True, virsh_opt=virsh_options, func=action_during_mig, extra_opts=extra, **extra_args) mig_result = migration_test.ret if int(mig_result.exit_status) == 0: server_session = remote.wait_for_login('ssh', server_ip, '22', server_user, server_pwd, r"[\#\$]\s*$") check_vm_network_accessed(server_session, vm_ipv4) server_session.close() if net_failover_test: # Check network connection if enable_hostdev_iface: check_vm_network_connection(net_hostdev_name) check_vm_network_connection(net_bridge_name) # VF driver should not be vfio-pci check_vfio_pci(vf_path, True) vm.connect_uri = dest_uri vm_after_mig = vm.wait_for_serial_login(timeout=240) cmd = "ip link" cmd_result = vm_after_mig.cmd_output(cmd) vm.connect_uri = bk_uri p_iface = re.findall(r"\d+:\s+(\w+):\s+.*", cmd_result) p_iface = [x for x in p_iface if x != 'lo'] check_vm_iface_num(p_iface) # Check the output of ping command cmd = 'cat %s' % vm_tmp_file cmd_result = vm_after_mig.cmd_output(cmd) if re.findall('Destination Host Unreachable', cmd_result, re.M): test.fail("The network does not work well during " "the migration period. ping output: %s" % cmd_result) # Execute migration from remote if migr_vm_back: ssh_connection = utils_conn.SSHConnection(server_ip=client_ip, server_pwd=client_pwd, client_ip=server_ip, client_pwd=server_pwd) try: ssh_connection.conn_check() except utils_conn.ConnectionError: ssh_connection.conn_setup() ssh_connection.conn_check() # Pre migration setup for local machine migration_test.migrate_pre_setup(src_uri, params) remove_dict = {"do_search": ('{"%s": "ssh:/"}' % src_uri)} remote_libvirt_file = libvirt_config\ .remove_key_for_modular_daemon(remove_dict, remote_dargs) cmd = "virsh migrate %s %s %s" % (vm_name, options, src_uri) logging.debug("Start migration: %s", cmd) cmd_result = remote.run_remote_cmd(cmd, params, runner_on_target) logging.info(cmd_result) if cmd_result.exit_status: test.fail("Failed to run '%s' on remote: %s" % (cmd, cmd_result)) logging.debug("migration back done") check_vm_network_accessed(ping_dest=vm_ipv4) if net_failover_test: vm.cleanup_serial_console() vm.create_serial_console() vm_session = vm.wait_for_serial_login(timeout=240) iface_list = get_vm_ifaces(vm_session) check_vm_iface_num(iface_list) else: check_vm_network_accessed(ping_dest=vm_ipv4) if net_failover_test: iface_list = get_vm_ifaces(vm_session) check_vm_iface_num(iface_list) finally: logging.debug("Recover test environment") vm.connect_uri = bk_uri # Clean VM on destination migration_test.cleanup_vm(vm, dest_uri) logging.info("Recover VM XML configuration") orig_config_xml.sync() logging.debug("The current VM XML:\n%s", orig_config_xml.xmltreefile) if src_libvirt_file: src_libvirt_file.restore() if remote_libvirt_file: del remote_libvirt_file server_session = remote.wait_for_login('ssh', server_ip, '22', server_user, server_pwd, r"[\#\$]\s*$") if 'src_pf' in locals(): cmd = 'echo %s >/proc/sys/net/ipv4/conf/all/rp_filter' % default_src_rp_filter process.run(cmd, shell=True, verbose=True) utils_sriov.add_or_del_connection(params, is_del=True) create_or_del_networks(src_pf, params, is_del=True) if 'dest_pf' in locals(): cmd = 'echo %s >/proc/sys/net/ipv4/conf/all/rp_filter' % default_dest_rp_filter utils_misc.cmd_status_output(cmd, shell=True, session=server_session) utils_sriov.add_or_del_connection(destparams_dict, session=server_session, is_del=True) remote_virsh_session = virsh.VirshPersistent(**remote_virsh_dargs) create_or_del_networks(dest_pf, params, remote_virsh_session, is_del=True) remote_virsh_session.close_session() if 'dest_pf_pci_path' in locals() and default_dest_vf != vf_no: utils_sriov.set_vf(dest_pf_pci_path, default_dest_vf, server_session) if 'src_pf_pci_path' in locals() and default_src_vf != vf_no: utils_sriov.set_vf(src_pf_pci_path, default_src_vf) # Clean up of pre migration setup for local machine if migr_vm_back: if 'ssh_connection' in locals(): ssh_connection.auto_recover = True migration_test.migrate_pre_setup(src_uri, params, cleanup=True) server_session.close() if remote_virsh_session: remote_virsh_session.close_session() logging.info("Remove local NFS image") source_file = params.get("source_file") if source_file: libvirt.delete_local_disk("file", path=source_file)