def setup_controller_xml(): """ Prepare controller devices of VM XML according to params. """ if cntlr_type is None: type = 'pci' else: type = cntlr_type curcntlr = 0 while curcntlr < cntlr_num: ctrl = Controller(type_name=type) if cntlr_model is not None: ctrl.model = cntlr_model if cntlr_model == 'pci-bridge': ctrl.model_name = {'name': 'pci-bridge'} if cntlr_index is not None: ctrl.index = cntlr_index elif with_index: if cntlr_model is not None and cntlr_model == 'pci-bridge': for i in range(1, int(match_new_addr()['bus'], 16) + 1): vm_xml.add_device(add_device('pci', str(i), 'pci-root')) ctrl.index = str(int(match_new_addr()['bus'], 16) + 1) else: ctrl.index = str(curcntlr) if target_index is not None: ctrl.target = {'index': target_index} elif with_index: if cntlr_model is not None and cntlr_model == 'pci-bridge': ctrl.target = { 'chassisNr': str(int(match_new_addr()['bus'], 16) + 1) } else: ctrl.target = {'index': str(curcntlr)} if addr_str is not None: ctrl.address = ctrl.new_controller_address( attrs=match_new_addr()) logging.debug("Controller XML is:%s", ctrl) vm_xml.add_device(ctrl) curcntlr += 1 if special_num: spe_num = int(special_num) ctrl = Controller(type_name=type) if cntlr_model is not None: ctrl.model = cntlr_model ctrl.index = spe_num ctrl.target = {'index': spe_num} if addr_str is not None: ctrl.address = ctrl.new_controller_address( attrs=match_new_addr()) logging.debug("Controller XML is:%s", ctrl) vm_xml.add_device(ctrl)
def setup_controller_xml(index, addr_target=None): """ Prepare controller devices of VM XML. :param index: The index of controller :param addr_target: The controller address """ ctrl = Controller(type_name=cntlr_type) if model: ctrl.model = model if pcihole: ctrl.pcihole64 = pcihole if vectors: ctrl.vectors = vectors if index: ctrl.index = index if chassisNr: ctrl.target = {'chassisNr': chassisNr} if model_name: ctrl.model_name = {'name': model_name} if addr_target: match = re.match( r"(?P<bus>[0-9]*):(?P<slot>[0-9a-f]*).(?P<function>[0-9])", addr_target) if match: addr_dict = match.groupdict() addr_dict['bus'] = hex(int(addr_dict['bus'], 16)) addr_dict['slot'] = hex(int(addr_dict['slot'], 16)) addr_dict['function'] = hex(int(addr_dict['function'], 16)) addr_dict['domain'] = '0x0000' ctrl.address = ctrl.new_controller_address(attrs=addr_dict) logging.debug("Controller XML is:%s", ctrl) vm_xml.add_device(ctrl) if cmpnn_cntlr_model is not None: for num in range(int(cmpnn_cntlr_num)): ctrl = Controller(type_name=cntlr_type) ctrl.model = cmpnn_cntlr_model + str(num + 1) ctrl.index = index logging.debug("Controller XML is:%s", ctrl) vm_xml.add_device(ctrl)
def create_pci_device(pci_model, pci_model_name, **kwargs): """ Create a pci/pcie bridge :param pci_model: model of pci controller device :param pci_model_name: model name of pci controller device :param kwargs: other k-w args that needed to create device :return: the newly created device object """ pci_bridge = Controller('pci') pci_bridge.model = pci_model pci_bridge.model_name = {'name': pci_model_name} if 'index' in kwargs: pci_bridge.index = kwargs['index'] if 'address' in kwargs: pci_bridge.address = pci_bridge.new_controller_address( attrs=eval(kwargs['address'])) logging.debug('pci_bridge: %s', pci_bridge) return pci_bridge
def create_pci_device(pci_model, pci_model_name, **kwargs): """ Create a pci/pcie bridge :param pci_model: model of pci controller device :param pci_model_name: model name of pci controller device :param kwargs: other k-w args that needed to create device :return: the newly created device object """ pci_bridge = Controller('pci') pci_bridge.model = pci_model pci_bridge.model_name = {'name': pci_model_name} if 'index' in kwargs: pci_bridge.index = kwargs['index'] if 'address' in kwargs: pci_bridge.address = pci_bridge.new_controller_address( attrs=eval(kwargs['address'])) logging.debug('pci_bridge: %s', pci_bridge) return pci_bridge
def run(test, params, env): """ Test watchdog device: 1.Add watchdog device to the guest xml. 2.Start the guest. 3.Trigger the watchdog in the guest. 4.Confirm the guest status. """ def trigger_watchdog(model): """ Trigger watchdog :param model: action when watchdog triggered """ watchdog_device = "device %s" % model if action == "dump": watchdog_action = "watchdog-action pause" else: watchdog_action = "watchdog-action %s" % action if not hotplug_test: vm_pid = vm.get_pid() with open("/proc/%s/cmdline" % vm_pid) as vm_cmdline_file: vm_cmdline = vm_cmdline_file.read() vm_cmdline = vm_cmdline.replace('\x00', ' ') if not all(option in vm_cmdline for option in (watchdog_device, watchdog_action)): test.fail("Can not find %s or %s in qemu cmd line" % (watchdog_device, watchdog_action)) cmd = "gsettings set org.gnome.settings-daemon.plugins.power button-power shutdown" session.cmd(cmd, ignore_all_errors=True) try: if model == "ib700": try: session.cmd("modprobe ib700wdt") except aexpect.ShellCmdError: session.close() test.fail("Failed to load module ib700wdt") session.cmd("dmesg | grep -i %s && lsmod | grep %s" % (model, model)) session.cmd("echo 1 > /dev/watchdog") except aexpect.ShellCmdError as e: session.close() test.fail("Failed to trigger watchdog: %s" % e) def watchdog_attached(vm_name): """ Confirm whether watchdog device is attached to vm by checking domain dumpxml :param vm_name: vm name """ vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name) if vmxml.xmltreefile.find('devices/watchdog'): return True else: return False def confirm_guest_status(): """ Confirm the guest status after watchdog triggered """ def _booting_completed(): session = vm.wait_for_login() status = None second_boot_time = None try: status, second_boot_time = session.cmd_status_output("uptime --since") logging.debug("The second boot time is %s", second_boot_time) except (aexpect.ShellStatusError, aexpect.ShellProcessTerminatedError) as e: logging.error("Exception caught:%s", e) session.close() return second_boot_time > first_boot_time def _inject_nmi(): session = vm.wait_for_login() status, output = session.cmd_status_output("dmesg | grep -i nmi") session.close() if status == 0: logging.debug(output) return True return False def _inject_nmi_event(): virsh_session.send_ctrl("^C") output = virsh_session.get_stripped_output() if "inject-nmi" not in output: return False return True def _check_dump_file(dump_path, domain_id): dump_file = glob.glob('%s%s-*' % (dump_path, domain_id)) if len(dump_file): logging.debug("Find the auto core dump file:\n%s", dump_file[0]) os.remove(dump_file[0]) return True return False if action in ["poweroff", "shutdown"]: if not utils_misc.wait_for(lambda: vm.state() == "shut off", 180, 10): test.fail("Guest not shutdown after watchdog triggered") else: logging.debug("Guest is in shutdown state after watchdog triggered") elif action == "reset": if not utils_misc.wait_for(_booting_completed, 600, 10): test.fail("Guest not reboot after watchdog triggered") else: logging.debug("Guest is rebooted after watchdog triggered") elif action == "pause": if utils_misc.wait_for(lambda: vm.state() == "paused", 180, 10): logging.debug("Guest is in paused status after watchdog triggered.") cmd_output = virsh.domstate(vm_name, '--reason').stdout.strip() logging.debug("Check guest status: %s\n", cmd_output) if cmd_output != "paused (watchdog)": test.fail("The domstate is not correct after dump by watchdog") else: test.fail("Guest not pause after watchdog triggered") elif action == "none": if utils_misc.wait_for(lambda: vm.state() == "shut off", 180, 10): test.fail("Guest shutdown unexpectedly") else: logging.debug("Guest is not in shutoff state since watchdog action is none.") elif action == "inject-nmi": if not utils_misc.wait_for(_inject_nmi, 180, 10): test.fail("Guest not receive inject-nmi after watchdog triggered\n") elif not utils_misc.wait_for(_inject_nmi_event, 180, 10): test.fail("No inject-nmi watchdog event caught") else: logging.debug("Guest received inject-nmi and inject-nmi watchdog event " " has been caught.") virsh_session.close() elif action == "dump": domain_id = vm.get_id() dump_path = "/var/lib/libvirt/qemu/dump/" if not utils_misc.wait_for(lambda: _check_dump_file(dump_path, domain_id), 180, 10): test.fail("No auto core dump file found after watchdog triggered") else: logging.debug("VM core has been dumped after watchdog triggered.") name_length = params.get("name_length", "default") vm_name = params.get("main_vm", "avocado-vt-vm1") vm = env.get_vm(params["main_vm"]) model = params.get("model") action = params.get("action") model_test = params.get("model_test") == "yes" hotplug_test = params.get("hotplug_test") == "yes" hotunplug_test = params.get("hotunplug_test") == "yes" machine_type = params.get("machine_type") if machine_type == "q35" and model == "ib700": test.cancel("ib700wdt watchdog device is not supported " "on guest with q35 machine type") # Backup xml file vmxml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name) backup_xml = vmxml.copy() # Rename the guest name to the length defined in the config file if name_length != "default": origin_name = vm_name name_length = int(params.get("name_length", "1")) vm_name = ''.join([random.choice(string.ascii_letters+string.digits) for _ in range(name_length)]) vm_xml.VMXML.vm_rename(vm, vm_name) # Generate the renamed xml file vmxml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name) # Coldplug pcie-to-pci-bridge to vm xml for q35 guest as i6300esb watchdog # device can only be plugged to conventional PCI slot if (machine_type == 'q35' and not vmxml.get_controllers(controller_type='pci', model='pcie-to-pci-bridge')): logging.debug("Add pcie-root-port and pcie-to-pci-bridge controller to vm") pcie_root_port = Controller("pci") pcie_pci_bridge = Controller("pci") pcie_root_port.model = "pcie-root-port" pcie_pci_bridge.model = "pcie-to-pci-bridge" pcie_root_port.model_name = {'name': 'pcie-root-port'} pcie_pci_bridge.model_name = {'name': 'pcie-pci-bridge'} vmxml.add_device(pcie_root_port) vmxml.add_device(pcie_pci_bridge) vmxml.sync() if hotplug_test: vm.start() session = vm.wait_for_login() # Add watchdog device to domain vmxml.remove_all_device_by_type('watchdog') watchdog_dev = Watchdog() watchdog_dev.model_type = model watchdog_dev.action = action chars = string.ascii_letters + string.digits + '-_' alias_name = 'ua-' + ''.join(random.choice(chars) for _ in list(range(64))) watchdog_dev.alias = {'name': alias_name} try: if model_test or hotunplug_test: vmxml.add_device(watchdog_dev) vmxml.sync() try: vm.start() except Exception: test.fail("VM startup after adding watchdog device failed!") elif hotplug_test: watchdog_xml = watchdog_dev.xml attach_result = virsh.attach_device(vm_name, watchdog_xml, ignore_status=False, debug=True) if not utils_misc.wait_for(lambda: watchdog_attached(vm.name), 60): test.fail("Failed to hotplug watchdog device.") session = vm.wait_for_login() # No need to trigger watchdog after hotunplug if hotunplug_test: cur_xml = vm_xml.VMXML.new_from_dumpxml(vm_name) cur_watchdog = cur_xml.xmltreefile.find('devices/watchdog') cur_watchdog_xml = Watchdog.new_from_element(cur_watchdog).xml detach_result = virsh.detach_device(vm_name, cur_watchdog_xml, ignore_status=True, debug=True) if detach_result.exit_status: test.fail("i6300esb watchdog device can NOT be detached successfully, " "result:\n%s" % detach_result) elif not utils_misc.wait_for(lambda: not watchdog_attached(vm.name), 60): test.fail("Failed to hotunplug watchdog device.") return if action == "reset": status, first_boot_time = session.cmd_status_output("uptime --since") logging.info("The first boot time is %s\n", first_boot_time) if action == "inject-nmi": virsh_session = virsh.VirshSession(virsh_exec=virsh.VIRSH_EXEC, auto_close=True) event_cmd = "event --event watchdog --all --loop" virsh_session.sendline(event_cmd) trigger_watchdog(model) confirm_guest_status() finally: if vm.is_alive(): vm.destroy(gracefully=False) if name_length != "default": vm_xml.VMXML.vm_rename(vm, origin_name) backup_xml.sync()
def run(test, params, env): """ Test pci/pcie-to-pci bridge Hotplug interface to pci/pcie-to-pci bridge, then check xml and inside vm. Hotunplug interface, then check xml and inside vm """ vm_name = params.get('main_vm') pci_model = params.get('pci_model', 'pci') hotplug = 'yes' == params.get('hotplug', 'no') pci_model_name = params.get('pci_model_name') pci_br_has_device = 'yes' == params.get('pci_br_has_device', 'no') sound_dev_model_type = params.get('sound_dev_model_type', '') sound_dev_address = params.get('sound_dev_address', '') iface_model = params.get('iface_model', '') iface_source = params.get('iface_source', '') vmxml = VMXML.new_from_inactive_dumpxml(vm_name) bkxml = vmxml.copy() vm = env.get_vm(vm_name) try: # Check if there is a pci/pcie-to-pci bridge, if so, # just use the existing pci/pcie-to-pci-bridge to test ori_pci_br = [ dev for dev in vmxml.get_devices('controller') if dev.type == 'pci' and dev.model == pci_model ] # If there is not a pci/pcie-to-pci bridge to test, # create one and add to vm if not ori_pci_br: logging.info('No %s on vm, create one', pci_model) pci_bridge = Controller('pci') pci_bridge.model = pci_model pci_bridge.model_name = {'name': pci_model_name} vmxml.add_device(pci_bridge) vmxml.sync() logging.debug(virsh.dumpxml(vm_name)) # Check if pci/pcie-to-pci bridge is successfully added vmxml = VMXML.new_from_inactive_dumpxml(vm_name) cur_pci_br = [ dev for dev in vmxml.get_devices('controller') if dev.type == 'pci' and dev.model == pci_model ] if not cur_pci_br: test.error('Failed to add %s controller to vm xml' % pci_model) pci_br = cur_pci_br[0] logging.debug(pci_br) pci_br_index = pci_br.index # If test scenario requires another pci device on pci/pcie-to-pci # bridge before hotplug, add a sound device and make sure # the 'bus' is same with pci bridge index if pci_br_has_device: sound_dev = Sound() sound_dev.model_type = sound_dev_model_type sound_dev.address = eval(sound_dev_address % pci_br_index) logging.debug(sound_dev.address) vmxml.add_device(sound_dev) vmxml.sync() # Test hotplug scenario if hotplug: vm.start() vm.wait_for_login().close() # Create interface to be hotplugged logging.info('Create interface to be hotplugged') iface = Interface('network') iface.model = iface_model iface.source = eval(iface_source) mac = utils_net.generate_mac_address_simple() iface.mac_address = mac logging.debug(iface) result = virsh.attach_device(vm_name, iface.xml, debug=True) libvirt.check_exit_status(result) xml_after_attach = VMXML.new_from_dumpxml(vm_name) logging.debug(virsh.dumpxml(vm_name)) # Check if the iface with given mac address is successfully attached iface_list = [ iface for iface in xml_after_attach.get_devices('interface') if iface.mac_address == mac ] logging.debug('iface list after attach: %s', iface_list) if not iface_list: test.error('Failed to attach interface %s' % iface) # Check inside vm def check_inside_vm(session, expect=True): ip_output = session.cmd('ip a') logging.debug(ip_output) return expect if mac in ip_output else not expect session = vm.wait_for_serial_login() if not utils_misc.wait_for(lambda: check_inside_vm(session, True), timeout=60, step=5): test.fail('Check interface inside vm failed,' 'interface not successfully attached:' 'not found mac address %s' % mac) session.close() # Test hotunplug result = virsh.detach_device(vm_name, iface.xml, debug=True) libvirt.check_exit_status(result) logging.debug(virsh.dumpxml(vm_name)) # Check if the iface with given mac address has been # successfully detached xml_after_detach = VMXML.new_from_dumpxml(vm_name) iface_list_after_detach = [ iface for iface in xml_after_detach.get_devices('interface') if iface.mac_address == mac ] logging.debug('iface list after detach: %s', iface_list_after_detach) if iface_list_after_detach: test.fail('Failed to detach device: %s', iface) # Check again inside vm session = vm.wait_for_serial_login() if not utils_misc.wait_for(lambda: check_inside_vm(session, False), timeout=60, step=5): test.fail('Check interface inside vm failed,' 'interface not successfully detached:' 'found mac address %s' % mac) session.close() finally: bkxml.sync()