示例#1
0
 def check_support_device(dev):
     if is_qmp_monitor:
         devices_supported = vm.monitor.human_monitor_cmd("%s ?" % cmd_type)
     else:
         devices_supported = vm.monitor.send_args_cmd("%s ?" % cmd_type)
     # Check if the device is support in qemu
     is_support = utils_test.find_substring(devices_supported, dev)
     if not is_support:
         raise error.TestError("%s doesn't support device: %s" %
                               (cmd_type, dev))
示例#2
0
 def check_support_device(dev):
     if is_qmp_monitor:
         devices_supported = vm.monitor.human_monitor_cmd("%s ?" % cmd_type)
     else:
         devices_supported = vm.monitor.send_args_cmd("%s ?" % cmd_type)
     # Check if the device is support in qemu
     is_support = utils_test.find_substring(devices_supported, dev)
     if not is_support:
         raise error.TestError("%s doesn't support device: %s" %
                               (cmd_type, dev))
示例#3
0
def run_sr_iov_hotplug(test, params, env):
    """
    Test hotplug of sr-iov devices.

    (Elements between [] are configurable test parameters)
    1) Set up sr-iov test environment in host.
    2) Start VM.
    3) PCI add one/multi sr-io  deivce with (or without) repeat
    4) Compare output of monitor command 'info pci'.
    5) Compare output of guest command [reference_cmd].
    6) Verify whether pci_model is shown in [pci_find_cmd].
    7) Check whether the newly added PCI device works fine.
    8) Delete the device, verify whether could remove the sr-iov device.

    @param test:   KVM test object.
    @param params: Dictionary with the test parameters.
    @param env:    Dictionary with test environment.
    """
    def pci_add_iov(pci_num):
        pci_add_cmd = ("pci_add pci_addr=auto host host=%s,if=%s" %
                       (pa_pci_ids[pci_num], pci_model))
        if params.get("hotplug_params"):
            assign_param = params.get("hotplug_params").split()
            for param in assign_param:
                value = params.get(param)
                if value:
                    pci_add_cmd += ",%s=%s" % (param, value)

        return pci_add(pci_add_cmd)

    def pci_add(pci_add_cmd):
        error.context("Adding pci device with command 'pci_add'")
        add_output = vm.monitor.send_args_cmd(pci_add_cmd, convert=False)
        pci_info.append(['', add_output])

        if not "OK domain" in add_output:
            raise error.TestFail("Add PCI device failed. "
                                 "Monitor command is: %s, Output: %r" %
                                 (pci_add_cmd, add_output))
        return vm.monitor.info("pci")

    def check_support_device(dev):
        if is_qmp_monitor:
            devices_supported = vm.monitor.human_monitor_cmd("%s ?" % cmd_type)
        else:
            devices_supported = vm.monitor.send_args_cmd("%s ?" % cmd_type)
        # Check if the device is support in qemu
        is_support = utils_test.find_substring(devices_supported, dev)
        if not is_support:
            raise error.TestError("%s doesn't support device: %s" %
                                  (cmd_type, dev))

    def device_add_iov(pci_num):
        device_id = "%s" % pci_model + "-" + utils_misc.generate_random_id()
        pci_info.append([device_id])
        check_support_device("pci-assign")
        pci_add_cmd = ("device_add id=%s,driver=pci-assign,host=%s" %
                       (pci_info[pci_num][0], pa_pci_ids[pci_num]))
        if params.get("hotplug_params"):
            assign_param = params.get("hotplug_params").split()
            for param in assign_param:
                value = params.get(param)
                if value:
                    pci_add_cmd += ",%s=%s" % (param, value)
        return device_add(pci_num, pci_add_cmd)

    def device_add(pci_num, pci_add_cmd):
        error.context("Adding pci device with command 'device_add'")
        if is_qmp_monitor:
            add_output = vm.monitor.send_args_cmd(pci_add_cmd)
        else:
            add_output = vm.monitor.send_args_cmd(pci_add_cmd, convert=False)
        pci_info[pci_num].append(add_output)

        after_add = vm.monitor.info("pci")
        if pci_info[pci_num][0] not in after_add:
            logging.debug("Print info pci after add the block: %s" % after_add)
            raise error.TestFail("Add device failed. Monitor command is: %s"
                                 ". Output: %r" % (pci_add_cmd, add_output))
        return after_add

    # Hot add a pci device
    def add_device(pci_num):
        reference_cmd = params.get("reference_cmd")
        find_pci_cmd = params.get("find_pci_cmd")
        info_pci_ref = vm.monitor.info("pci")
        reference = session.cmd_output(reference_cmd)

        try:
            # get function for adding device.
            add_fuction = local_functions["%s_iov" % cmd_type]
        except Exception:
            raise error.TestError(
                "No function for adding sr-iov dev with '%s'" % cmd_type)
        after_add = None
        if add_fuction:
            # Do add pci device.
            after_add = add_fuction(pci_num)

        try:
            # Define a helper function to compare the output
            def _new_shown():
                o = session.cmd_output(reference_cmd)
                return o != reference

            # Define a helper function to catch PCI device string
            def _find_pci():
                o = session.cmd_output(find_pci_cmd)
                if re.search(match_string, o, re.IGNORECASE):
                    return True
                else:
                    return False

            error.context("Start checking new added device")
            # Compare the output of 'info pci'
            if after_add == info_pci_ref:
                raise error.TestFail("No new PCI device shown after executing "
                                     "monitor command: 'info pci'")

            secs = int(params.get("wait_secs_for_hook_up"))
            if not utils_misc.wait_for(_new_shown, test_timeout, secs, 3):
                raise error.TestFail(
                    "No new device shown in output of command "
                    "executed inside the guest: %s" % reference_cmd)

            if not utils_misc.wait_for(_find_pci, test_timeout, 3, 3):
                raise error.TestFail(
                    "New add sr-iov device not found in guest. "
                    "Command was: %s" % find_pci_cmd)

            # Test the newly added device
            try:
                session.cmd(params.get("pci_test_cmd") % (pci_num + 1))
            except aexpect.ShellError, e:
                raise error.TestFail(
                    "Check for sr-iov device failed after PCI "
                    "hotplug. Output: %r" % e.output)

        except Exception:
            pci_del(pci_num, ignore_failure=True)
            raise

    # Hot delete a pci device
    def pci_del(pci_num, ignore_failure=False):
        def _device_removed():
            after_del = vm.monitor.info("pci")
            return after_del != before_del

        before_del = vm.monitor.info("pci")
        if cmd_type == "pci_add":
            slot_id = "0" + pci_info[pci_num][1].split(",")[2].split()[1]
            cmd = "pci_del pci_addr=%s" % slot_id
            vm.monitor.send_args_cmd(cmd, convert=False)
        elif cmd_type == "device_add":
            cmd = "device_del id=%s" % pci_info[pci_num][0]
            vm.monitor.send_args_cmd(cmd)

        if (not utils_misc.wait_for(_device_removed, test_timeout, 0, 1)
                and not ignore_failure):
            raise error.TestFail("Failed to hot remove PCI device: %s. "
                                 "Monitor command: %s" % (pci_model, cmd))

    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    timeout = int(params.get("login_timeout", 360))
    session = vm.wait_for_login(timeout=timeout)

    test_timeout = int(params.get("test_timeout", 360))
    # Test if it is nic or block
    pci_num_range = int(params.get("pci_num", 1))
    rp_times = int(params.get("repeat_times", 1))
    pci_model = params.get("pci_model", "pci-assign")
    # Need udpate match_string if you use a card other than 82576
    match_string = params.get("match_string", "82576")
    if vm.pci_assignable is not None:
        pa_pci_ids = vm.pci_assignable.request_devs(pci_num_range)

    # Modprobe the module if specified in config file
    module = params.get("modprobe_module")
    if module:
        error.context("modprobe the module %s" % module, logging.info)
        session.cmd("modprobe %s" % module)

    # check monitor type
    qemu_binary = params.get("qemu_binary", "/usr/bin/qemu-kvm")
    qemu_binary = utils_misc.get_path(test.bindir, qemu_binary)
    is_qmp_monitor = (utils_misc.qemu_has_option("qmp", qemu_binary)
                      and params.get("monitor_type") == "qmp")
    # Probe qemu to verify what is the supported syntax for PCI hotplug
    if is_qmp_monitor:
        cmd_o = vm.monitor.info("commands")
    else:
        cmd_o = vm.monitor.send_args_cmd("help")

    cmd_type = utils_test.find_substring(str(cmd_o), "device_add", "pci_add")
    if not cmd_o:
        raise error.TestError("Unknow version of qemu")

    local_functions = locals()

    for j in range(rp_times):
        # pci_info is a list of list.
        # each element 'i' has 4 members:
        # pci_info[i][0] == device id, only used for device_add
        # pci_info[i][1] == output of device add command
        pci_info = []
        for pci_num in xrange(pci_num_range):
            msg = "Start hot-adding %sth pci device, repeat %d" % (pci_num + 1,
                                                                   j + 1)
            error.context(msg, logging.info)
            add_device(pci_num)
        for pci_num in xrange(pci_num_range):
            msg = "start hot-deleting %sth pci device repeat %d" % (pci_num +
                                                                    1, j + 1)
            error.context(msg, logging.info)
            pci_del(-(pci_num + 1))
def run_sr_iov_hotplug_negative(test, params, env):
    """
    KVM sr-iov hotplug negatvie test:
    1) Boot up VM.
    2) Try to remove sr-iov device driver module (optional)
    3) Hotplug sr-iov device to VM with negative parameters
    4) Verify that qemu could handle the negative parameters
       check hotplug error message (optional)

    @param test: qemu test object
    @param params: Dictionary with the test parameters
    @param env: Dictionary with test environment.
    """


    def make_pci_add_cmd(pa_pci_id, pci_addr="auto"):
        pci_add_cmd = ("pci_add pci_addr=%s host host=%s,if=%s" %
                       (pci_addr, pa_pci_id, pci_model))
        if params.get("hotplug_params"):
            assign_param = params.get("hotplug_params").split()
            for param in assign_param:
                value = params.get(param)
                if value:
                    pci_add_cmd += ",%s=%s" % (param, value)
        return pci_add_cmd

    def make_device_add_cmd(pa_pci_id, pci_addr=None):
        device_id = "%s" % pci_model + "-" + utils_misc.generate_random_id()
        pci_add_cmd = ("device_add id=%s,driver=pci-assign,host=%s" %
                       (device_id, pa_pci_id))
        if pci_addr is not None:
            pci_add_cmd += ",addr=%s" % pci_addr
        if params.get("hotplug_params"):
            assign_param = params.get("hotplug_params").split()
            for param in assign_param:
                value = params.get(param)
                if value:
                    pci_add_cmd += ",%s=%s" % (param, value)
        return pci_add_cmd


    neg_msg = params.get("negative_msg")
    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    rp_times = int(params.get("repeat_times", 1))
    pci_model = params.get("pci_model", "pci-assign")
    pci_addr = params.get("pci_addr")
    modprobe_cmd = params.get("modprobe_cmd")

    if modprobe_cmd:
        #negative test, both guest and host should still work well.
        msg = "Try to remove sr-iov module in host."
        error.context(msg, logging.info)
        utils.system(modprobe_cmd)
    if vm.pci_assignable is not None:
        pa_pci_ids = vm.pci_assignable.request_devs(1)
    # Probe qemu to verify what is the supported syntax for PCI hotplug
    if vm.monitor.protocol == 'qmp':
        cmd_output = vm.monitor.info("commands")
    else:
        cmd_output = vm.monitor.send_args_cmd("help")

    if not cmd_output:
        raise error.TestError("Unknow version of qemu")

    cmd_type = utils_test.find_substring(str(cmd_output), "pci_add",
                                                          "device_add")
    for j in range(rp_times):
        if cmd_type == "pci_add":
            pci_add_cmd = make_pci_add_cmd(pa_pci_ids[0], pci_addr)
        elif cmd_type == "device_add":
            pci_add_cmd = make_device_add_cmd(pa_pci_ids[0], pci_addr)
        try:
            msg = "Adding pci device with command '%s'" % pci_add_cmd
            error.context(msg, logging.info)
            case_fail = False
            add_output = vm.monitor.send_args_cmd(pci_add_cmd, convert=False)
            case_fail = True
        except Exception, e:
            if neg_msg:
                msg = "Check negative hotplug error message"
                error.context(msg, logging.info)
                if neg_msg not in str(e):
                    msg = "Could not find '%s' in error msg '%s'" % (neg_msg, e)
                    raise error.TestFail(msg)
            logging.debug("Could not boot up vm, %s" % e)
        if case_fail:
            raise error.TestFail("Did not raise exception during hotpluging")
示例#5
0
def run_pci_hotplug(test, params, env):
    """
    Test hotplug of PCI devices.

    (Elements between [] are configurable test parameters)
    1) PCI add one/multi device (NIC / block) with(or without) repeat
    2) Compare output of monitor command 'info pci'.
    3) Compare output of guest command [reference_cmd].
    4) Verify whether pci_model is shown in [pci_find_cmd].
    5) Check whether the newly added PCI device works fine.
    6) PCI delete the device, verify whether could remove the PCI device.
    7) reboot VM after guest wakeup form S3/S4 status (Optional Step).

    :param test:   QEMU test object.
    :param params: Dictionary with the test parameters.
    :param env:    Dictionary with test environment.
    """
    # Select an image file
    def find_image(pci_num):
        image_params = params.object_params("%s" % img_list[pci_num + 1])
        o = storage.get_image_filename(image_params, data_dir.get_data_dir())
        return o

    def pci_add_nic(pci_num):
        pci_add_cmd = "pci_add pci_addr=auto nic model=%s" % pci_model
        return pci_add(pci_add_cmd)

    def pci_add_block(pci_num):
        image_filename = find_image(pci_num)
        pci_add_cmd = ("pci_add pci_addr=auto storage file=%s,if=%s" %
                       (image_filename, pci_model))
        return pci_add(pci_add_cmd)

    def pci_add(pci_add_cmd):
        error.context("Adding pci device with command 'pci_add'")
        add_output = vm.monitor.send_args_cmd(pci_add_cmd, convert=False)
        pci_info.append(['', '', add_output, pci_model])

        if not "OK domain" in add_output:
            raise error.TestFail("Add PCI device failed. "
                                 "Monitor command is: %s, Output: %r" %
                                 (pci_add_cmd, add_output))
        return vm.monitor.info("pci")

    def is_supported_device(dev):
        # Probe qemu to verify what is the supported syntax for PCI hotplug
        cmd_output = vm.monitor.human_monitor_cmd("?")
        if len(re.findall("\ndevice_add", cmd_output)) > 0:
            cmd_type = "device_add"
        elif len(re.findall("\npci_add", cmd_output)) > 0:
            cmd_type = "pci_add"
        else:
            raise error.TestError("Unknow version of qemu")

        # Probe qemu for a list of supported devices
        probe_output = vm.monitor.human_monitor_cmd("%s ?" % cmd_type)
        devices_supported = [j.strip('"') for j in
                             re.findall('\"[a-z|0-9|\-|\_|\,|\.]*\"',
                                        probe_output, re.MULTILINE)]
        logging.debug("QEMU reported the following supported devices for "
                      "PCI hotplug: %s", devices_supported)
        return (dev in devices_supported)

    def verify_supported_device(dev):
        if not is_supported_device(dev):
            raise error.TestError("%s doesn't support device: %s" %
                                  (cmd_type, dev))

    def device_add_nic(pci_num, queues=1):
        device_id = pci_type + "-" + utils_misc.generate_random_id()
        pci_info.append([device_id, device_id])

        pci_model = params.get("pci_model")
        if pci_model == "virtio":
            pci_model = "virtio-net-pci"
        verify_supported_device(pci_model)
        pci_add_cmd = "device_add id=%s,driver=%s" % (pci_info[pci_num][1],
                                                      pci_model)
        if queues > 1 and "virtio" in pci_model:
            pci_add_cmd += ",mq=on"
        return device_add(pci_num, pci_add_cmd)

    def device_add_block(pci_num):
        device_id = pci_type + "-" + utils_misc.generate_random_id()
        pci_info.append([device_id, device_id])

        image_format = params.get("image_format_%s" % img_list[pci_num + 1])
        if not image_format:
            image_format = params.get("image_format", "qcow2")
        image_filename = find_image(pci_num)

        pci_model = params.get("pci_model")
        controller_model = None
        if pci_model == "virtio":
            pci_model = "virtio-blk-pci"

        if pci_model == "scsi":
            pci_model = "scsi-disk"
            controller_model = "lsi53c895a"
            verify_supported_device(controller_model)
            controller_id = "controller-" + device_id
            controller_add_cmd = ("device_add %s,id=%s" %
                                  (controller_model, controller_id))
            error.context("Adding SCSI controller.")
            vm.monitor.send_args_cmd(controller_add_cmd)

        verify_supported_device(pci_model)
        if drive_cmd_type == "drive_add":
            driver_add_cmd = ("%s auto file=%s,if=none,format=%s,id=%s" %
                              (drive_cmd_type, image_filename, image_format,
                               pci_info[pci_num][0]))
        elif drive_cmd_type == "__com.redhat_drive_add":
            driver_add_cmd = ("%s file=%s,format=%s,id=%s" %
                             (drive_cmd_type, image_filename, image_format,
                              pci_info[pci_num][0]))
        # add driver.
        error.context("Adding driver.")
        vm.monitor.send_args_cmd(driver_add_cmd, convert=False)

        pci_add_cmd = ("device_add id=%s,driver=%s,drive=%s" %
                       (pci_info[pci_num][1], pci_model, pci_info[pci_num][0]))
        return device_add(pci_num, pci_add_cmd)

    def device_add(pci_num, pci_add_cmd):
        error.context("Adding pci device with command 'device_add'")
        if vm.monitor.protocol == 'qmp':
            add_output = vm.monitor.send_args_cmd(pci_add_cmd)
        else:
            add_output = vm.monitor.send_args_cmd(pci_add_cmd, convert=False)
        pci_info[pci_num].append(add_output)
        pci_info[pci_num].append(pci_model)

        after_add = vm.monitor.info("pci")
        if pci_info[pci_num][1] not in after_add:
            logging.error("Could not find matched id in monitor:"
                          " %s" % pci_info[pci_num][1])
            raise error.TestFail("Add device failed. Monitor command is: %s"
                                 ". Output: %r" % (pci_add_cmd, add_output))
        return after_add

    # Hot add a pci device
    def add_device(pci_num, queues=1):
        info_pci_ref = vm.monitor.info("pci")
        reference = session.cmd_output(reference_cmd)

        try:
            # get function for adding device.
            add_fuction = local_functions["%s_%s" % (cmd_type, pci_type)]
        except Exception:
            raise error.TestError("No function for adding '%s' dev with '%s'" %
                                  (pci_type, cmd_type))
        after_add = None
        if add_fuction:
            # Do add pci device.
            after_add = add_fuction(pci_num, queues)

        try:
            # Define a helper function to compare the output
            def _new_shown():
                o = session.cmd_output(reference_cmd)
                return o != reference

            # Define a helper function to catch PCI device string
            def _find_pci():
                output = session.cmd_output(params.get("find_pci_cmd"))
                output = map(string.strip, output.splitlines())
                ref = map(string.strip, reference.splitlines())
                output = [_ for _ in output if _ not in ref]
                output = "\n".join(output)
                if re.search(params.get("match_string"), output, re.I):
                    return True
                return False

            error.context("Start checking new added device")
            # Compare the output of 'info pci'
            if after_add == info_pci_ref:
                raise error.TestFail("No new PCI device shown after executing "
                                     "monitor command: 'info pci'")

            secs = int(params.get("wait_secs_for_hook_up"))
            if not utils_misc.wait_for(_new_shown, test_timeout, secs, 3):
                raise error.TestFail("No new device shown in output of command "
                                     "executed inside the guest: %s" %
                                     reference_cmd)

            if not utils_misc.wait_for(_find_pci, test_timeout, 3, 3):
                raise error.TestFail("PCI %s %s device not found in guest. "
                                     "Command was: %s" %
                                     (pci_model, pci_type,
                                      params.get("find_pci_cmd")))

            # Test the newly added device
            try:
                session.cmd(params.get("pci_test_cmd") % (pci_num + 1))
            except aexpect.ShellError, e:
                raise error.TestFail("Check for %s device failed after PCI "
                                     "hotplug. Output: %r" % (pci_type, e.output))

        except Exception:
            pci_del(pci_num, ignore_failure=True)
            raise

    # Hot delete a pci device
    def pci_del(pci_num, ignore_failure=False):
        def _device_removed():
            after_del = vm.monitor.info("pci")
            return after_del != before_del

        before_del = vm.monitor.info("pci")
        if cmd_type == "pci_add":
            slot_id = int(pci_info[pci_num][2].split(",")[2].split()[1])
            cmd = "pci_del pci_addr=%s" % hex(slot_id)
            vm.monitor.send_args_cmd(cmd, convert=False)
        elif cmd_type == "device_add":
            cmd = "device_del id=%s" % pci_info[pci_num][1]
            vm.monitor.send_args_cmd(cmd)

        if (not utils_misc.wait_for(_device_removed, test_timeout, 0, 1)
                and not ignore_failure):
            raise error.TestFail("Failed to hot remove PCI device: %s. "
                                 "Monitor command: %s" %
                                 (pci_info[pci_num][3], cmd))

    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    timeout = int(params.get("login_timeout", 360))
    session = vm.wait_for_login(timeout=timeout)

    test_timeout = int(params.get("hotplug_timeout", 360))
    reference_cmd = params["reference_cmd"]
    # Test if it is nic or block
    pci_type = params["pci_type"]
    pci_model = params["pci_model"]

    # Modprobe the module if specified in config file
    module = params.get("modprobe_module")
    if module:
        session.cmd("modprobe %s" % module)

    # check monitor type
    qemu_binary = params.get("qemu_binary", "/usr/libexec/qemu-kvm")
    qemu_binary = utils_misc.get_path(test.bindir, qemu_binary)
    # Probe qemu to verify what is the supported syntax for PCI hotplug
    if vm.monitor.protocol == 'qmp':
        cmd_output = vm.monitor.info("commands")
    else:
        cmd_output = vm.monitor.human_monitor_cmd("help", debug=False)

    cmd_type = utils_test.find_substring(str(cmd_output), "device_add",
                                         "pci_add")
    if not cmd_output:
        raise error.TestError("Could find a suitable method for hotplugging"
                              " device in this version of qemu")

    # Determine syntax of drive hotplug
    # __com.redhat_drive_add == qemu-kvm-0.12 on RHEL 6
    # drive_add == qemu-kvm-0.13 onwards
    drive_cmd_type = utils_test.find_substring(str(cmd_output),
                                               "__com.redhat_drive_add", "drive_add")
    if not drive_cmd_type:
        raise error.TestError("Could find a suitable method for hotplugging"
                              " drive in this version of qemu")

    local_functions = locals()

    pci_num_range = int(params.get("pci_num"))
    queues = int(params.get("queues"))
    rp_times = int(params.get("repeat_times"))
    img_list = params.get("images").split()
    context_msg = "Running sub test '%s' %s"
    for j in range(rp_times):
        # pci_info is a list of list.
        # each element 'i' has 4 members:
        # pci_info[i][0] == device drive id, only used for device_add
        # pci_info[i][1] == device id, only used for device_add
        # pci_info[i][2] == output of device add command
        # pci_info[i][3] == device module name.
        pci_info = []
        for pci_num in xrange(pci_num_range):
            sub_type = params.get("sub_type_before_plug")
            if sub_type:
                error.context(context_msg % (sub_type, "before hotplug"),
                              logging.info)
                utils_test.run_virt_sub_test(test, params, env, sub_type)

            error.context("Start hot-adding pci device, repeat %d" % j)
            add_device(pci_num, queues)

            sub_type = params.get("sub_type_after_plug")
            if sub_type:
                error.context(context_msg % (sub_type, "after hotplug"),
                              logging.info)
                utils_test.run_virt_sub_test(test, params, env, sub_type)
        for pci_num in xrange(pci_num_range):
            sub_type = params.get("sub_type_before_unplug")
            if sub_type:
                error.context(context_msg % (sub_type, "before hotunplug"),
                              logging.info)
                utils_test.run_virt_sub_test(test, params, env, sub_type)

            error.context("start hot-deleting pci device, repeat %d" % j)
            pci_del(-(pci_num + 1))

            sub_type = params.get("sub_type_after_unplug")
            if sub_type:
                error.context(context_msg % (sub_type, "after hotunplug"),
                              logging.info)
                utils_test.run_virt_sub_test(test, params, env, sub_type)

    if params.get("reboot_vm", "no") == "yes":
        vm.reboot()
示例#6
0
def run_pci_hotplug(test, params, env):
    """
    Test hotplug of PCI devices.

    (Elements between [] are configurable test parameters)
    1) PCI add one/multi device (NIC / block) with(or without) repeat
    2) Compare output of monitor command 'info pci'.
    3) Compare output of guest command [reference_cmd].
    4) Verify whether pci_model is shown in [pci_find_cmd].
    5) Check whether the newly added PCI device works fine.
    6) PCI delete the device, verify whether could remove the PCI device.

    @param test:   QEMU test object.
    @param params: Dictionary with the test parameters.
    @param env:    Dictionary with test environment.
    """
    # Select an image file
    def find_image(pci_num):
        image_params = params.object_params("%s" % img_list[pci_num + 1])
        o = storage.get_image_filename(image_params, data_dir.get_data_dir())
        return o


    def pci_add_nic(pci_num):
        pci_add_cmd = "pci_add pci_addr=auto nic model=%s" % pci_model
        return pci_add(pci_add_cmd)


    def pci_add_block(pci_num):
        image_filename = find_image(pci_num)
        pci_add_cmd = ("pci_add pci_addr=auto storage file=%s,if=%s" %
                       (image_filename, pci_model))
        return pci_add(pci_add_cmd)


    def pci_add(pci_add_cmd):
        error.context("Adding pci device with command 'pci_add'")
        add_output = vm.monitor.send_args_cmd(pci_add_cmd, convert=False)
        pci_info.append(['', '' , add_output, pci_model])

        if not "OK domain" in add_output:
            raise error.TestFail("Add PCI device failed. "
                                 "Monitor command is: %s, Output: %r" %
                                 (pci_add_cmd, add_output))
        return  vm.monitor.info("pci")


    def is_supported_device(dev):
        # Probe qemu to verify what is the supported syntax for PCI hotplug
        cmd_output = vm.monitor.human_monitor_cmd("?")
        if len(re.findall("\ndevice_add", cmd_output)) > 0:
            cmd_type = "device_add"
        elif len(re.findall("\npci_add", cmd_output)) > 0:
            cmd_type = "pci_add"
        else:
            raise error.TestError("Unknow version of qemu")

        # Probe qemu for a list of supported devices
        probe_output = vm.monitor.human_monitor_cmd("%s ?" % cmd_type)
        devices_supported = [j.strip('"') for j in
                             re.findall('\"[a-z|0-9|\-|\_|\,|\.]*\"',
                                        probe_output, re.MULTILINE)]
        logging.debug("QEMU reported the following supported devices for "
                      "PCI hotplug: %s", devices_supported)
        return (dev in devices_supported)


    def verify_supported_device(dev):
        if not is_supported_device(dev):
            raise error.TestError("%s doesn't support device: %s" %
                                  (cmd_type, dev))


    def device_add_nic(pci_num, queues=1):
        device_id = pci_type + "-" + utils_misc.generate_random_id()
        pci_info.append([device_id, device_id])

        pci_model = params.get("pci_model")
        if pci_model == "virtio":
            pci_model = "virtio-net-pci"
        verify_supported_device(pci_model)
        pci_add_cmd = "device_add id=%s,driver=%s" % (pci_info[pci_num][1],
                                                      pci_model)
        if queues > 1 and "virtio" in pci_model:
            pci_add_cmd += ",mq=on"
        return device_add(pci_num, pci_add_cmd)


    def device_add_block(pci_num):
        device_id = pci_type + "-" + utils_misc.generate_random_id()
        pci_info.append([device_id, device_id])

        image_format = params.get("image_format_%s" % img_list[pci_num+1])
        if not image_format:
            image_format = params.get("image_format", "qcow2")
        image_filename = find_image(pci_num)

        pci_model = params.get("pci_model")
        controller_model = None
        if pci_model == "virtio":
            pci_model = "virtio-blk-pci"

        if pci_model == "scsi":
            pci_model = "scsi-disk"
            controller_model = "lsi53c895a"
            verify_supported_device(controller_model)
            controller_id = "controller-" + device_id
            controller_add_cmd = ("device_add %s,id=%s" %
                                  (controller_model, controller_id))
            error.context("Adding SCSI controller.")
            vm.monitor.send_args_cmd(controller_add_cmd)

        verify_supported_device(pci_model)
        if drive_cmd_type == "drive_add":
            driver_add_cmd = ("%s auto file=%s,if=none,format=%s,id=%s" %
                              (drive_cmd_type, image_filename, image_format,
                               pci_info[pci_num][0]))
        elif drive_cmd_type == "__com.redhat_drive_add":
            driver_add_cmd = ("%s file=%s,format=%s,id=%s" %
                             (drive_cmd_type, image_filename, image_format,
                              pci_info[pci_num][0]))
        # add driver.
        error.context("Adding driver.")
        vm.monitor.send_args_cmd(driver_add_cmd, convert=False)

        pci_add_cmd = ("device_add id=%s,driver=%s,drive=%s" %
                       (pci_info[pci_num][1], pci_model, pci_info[pci_num][0]))
        return device_add(pci_num, pci_add_cmd)


    def device_add(pci_num, pci_add_cmd):
        error.context("Adding pci device with command 'device_add'")
        if vm.monitor.protocol == 'qmp':
            add_output = vm.monitor.send_args_cmd(pci_add_cmd)
        else:
            add_output = vm.monitor.send_args_cmd(pci_add_cmd, convert=False)
        pci_info[pci_num].append(add_output)
        pci_info[pci_num].append(pci_model)

        after_add = vm.monitor.info("pci")
        if pci_info[pci_num][1] not in after_add:
            logging.error("Could not find matched id in monitor:"
                          " %s" % pci_info[pci_num][1])
            raise error.TestFail("Add device failed. Monitor command is: %s"
                                 ". Output: %r" % (pci_add_cmd, add_output))
        return after_add


    # Hot add a pci device
    def add_device(pci_num, queues=1):
        info_pci_ref = vm.monitor.info("pci")
        reference = session.cmd_output(reference_cmd)

        try:
            # get function for adding device.
            add_fuction = local_functions["%s_%s" % (cmd_type, pci_type)]
        except Exception:
            raise error.TestError("No function for adding '%s' dev with '%s'" %
                                  (pci_type, cmd_type))
        after_add = None
        if add_fuction:
            # Do add pci device.
            after_add = add_fuction(pci_num, queues)

        try:
            # Define a helper function to compare the output
            def _new_shown():
                o = session.cmd_output(reference_cmd)
                return o != reference

            # Define a helper function to catch PCI device string
            def _find_pci():
                output = session.cmd_output(params.get("find_pci_cmd"))
                output = map(string.strip, output.splitlines())
                ref = map(string.strip, reference.splitlines())
                output = [_ for _ in output if _ not in ref]
                output = "\n".join(output)
                if re.search(params.get("match_string"), output, re.I):
                    return True
                return False

            error.context("Start checking new added device")
            # Compare the output of 'info pci'
            if after_add == info_pci_ref:
                raise error.TestFail("No new PCI device shown after executing "
                                     "monitor command: 'info pci'")

            secs = int(params.get("wait_secs_for_hook_up"))
            if not utils_misc.wait_for(_new_shown, test_timeout, secs, 3):
                raise error.TestFail("No new device shown in output of command "
                                     "executed inside the guest: %s" %
                                     reference_cmd)

            if not utils_misc.wait_for(_find_pci, test_timeout, 3, 3):
                raise error.TestFail("PCI %s %s device not found in guest. "
                                     "Command was: %s" %
                                     (pci_model, pci_type,
                                      params.get("find_pci_cmd")))

            # Test the newly added device
            try:
                session.cmd(params.get("pci_test_cmd") % (pci_num+1))
            except aexpect.ShellError, e:
                raise error.TestFail("Check for %s device failed after PCI "
                                     "hotplug. Output: %r" % (pci_type, e.output))

        except Exception:
            pci_del(pci_num, ignore_failure=True)
            raise


    # Hot delete a pci device
    def pci_del(pci_num, ignore_failure=False):
        def _device_removed():
            after_del = vm.monitor.info("pci")
            return after_del != before_del

        before_del = vm.monitor.info("pci")
        if cmd_type == "pci_add":
            slot_id = int(pci_info[pci_num][2].split(",")[2].split()[1])
            cmd = "pci_del pci_addr=%s" % hex(slot_id)
            vm.monitor.send_args_cmd(cmd, convert=False)
        elif cmd_type == "device_add":
            cmd = "device_del id=%s" % pci_info[pci_num][1]
            vm.monitor.send_args_cmd(cmd)

        if (not utils_misc.wait_for(_device_removed, test_timeout, 0, 1)
            and not ignore_failure):
            raise error.TestFail("Failed to hot remove PCI device: %s. "
                                 "Monitor command: %s" %
                                 (pci_info[pci_num][3], cmd))


    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    timeout = int(params.get("login_timeout", 360))
    session = vm.wait_for_login(timeout=timeout)

    test_timeout = int(params.get("hotplug_timeout", 360))
    reference_cmd = params["reference_cmd"]
    # Test if it is nic or block
    pci_type = params["pci_type"]
    pci_model = params["pci_model"]

    # Modprobe the module if specified in config file
    module = params.get("modprobe_module")
    if module:
        session.cmd("modprobe %s" % module)

    # check monitor type
    qemu_binary = params.get("qemu_binary", "/usr/libexec/qemu-kvm")
    qemu_binary = utils_misc.get_path(test.bindir, qemu_binary)
    # Probe qemu to verify what is the supported syntax for PCI hotplug
    if vm.monitor.protocol == 'qmp':
        cmd_output = vm.monitor.info("commands")
    else:
        cmd_output = vm.monitor.human_monitor_cmd("help", debug=False)

    cmd_type = utils_test.find_substring(str(cmd_output), "device_add",
                                         "pci_add")
    if not cmd_output:
        raise error.TestError("Could find a suitable method for hotplugging"
                              " device in this version of qemu")

    # Determine syntax of drive hotplug
    # __com.redhat_drive_add == qemu-kvm-0.12 on RHEL 6
    # drive_add == qemu-kvm-0.13 onwards
    drive_cmd_type = utils_test.find_substring(str(cmd_output),
                                    "__com.redhat_drive_add", "drive_add")
    if not drive_cmd_type:
        raise error.TestError("Could find a suitable method for hotplugging"
                              " drive in this version of qemu")

    local_functions = locals()

    pci_num_range = int(params.get("pci_num"))
    queues = int(params.get("queues"))
    rp_times = int(params.get("repeat_times"))
    img_list = params.get("images").split()
    context_msg = "Running sub test '%s' %s"
    for j in range(rp_times):
        # pci_info is a list of list.
        # each element 'i' has 4 members:
        # pci_info[i][0] == device drive id, only used for device_add
        # pci_info[i][1] == device id, only used for device_add
        # pci_info[i][2] == output of device add command
        # pci_info[i][3] == device module name.
        pci_info = []
        for pci_num in xrange(pci_num_range):
            sub_type = params.get("sub_type_before_plug")
            if sub_type:
                error.context(context_msg % (sub_type, "before hotplug"),
                              logging.info)
                utils_test.run_virt_sub_test(test, params, env, sub_type)

            error.context("Start hot-adding pci device, repeat %d" % j)
            add_device(pci_num, queues)

            sub_type = params.get("sub_type_after_plug")
            if sub_type:
                error.context(context_msg % (sub_type, "after hotplug"),
                              logging.info)
                utils_test.run_virt_sub_test(test, params, env, sub_type)
        for pci_num in xrange(pci_num_range):
            sub_type = params.get("sub_type_before_unplug")
            if sub_type:
                error.context(context_msg % (sub_type, "before hotunplug"),
                              logging.info)
                utils_test.run_virt_sub_test(test, params, env, sub_type)

            error.context("start hot-deleting pci device, repeat %d" % j)
            pci_del(-(pci_num + 1))

            sub_type = params.get("sub_type_after_unplug")
            if sub_type:
                error.context(context_msg % (sub_type, "after hotunplug"),
                              logging.info)
                utils_test.run_virt_sub_test(test, params, env, sub_type)
示例#7
0
def run_sr_iov_hotplug(test, params, env):
    """
    Test hotplug of sr-iov devices.

    (Elements between [] are configurable test parameters)
    1) Set up sr-iov test environment in host.
    2) Start VM.
    3) PCI add one/multi sr-io  deivce with (or without) repeat
    4) Compare output of monitor command 'info pci'.
    5) Compare output of guest command [reference_cmd].
    6) Verify whether pci_model is shown in [pci_find_cmd].
    7) Check whether the newly added PCI device works fine.
    8) Delete the device, verify whether could remove the sr-iov device.

    @param test:   KVM test object.
    @param params: Dictionary with the test parameters.
    @param env:    Dictionary with test environment.
    """


    def pci_add_iov(pci_num):
        pci_add_cmd = ("pci_add pci_addr=auto host host=%s,if=%s" %
                       (pa_pci_ids[pci_num], pci_model))
        if params.get("hotplug_params"):
            assign_param = params.get("hotplug_params").split()
            for param in assign_param:
                value = params.get(param)
                if value:
                    pci_add_cmd += ",%s=%s" % (param, value)

        return pci_add(pci_add_cmd)

    def pci_add(pci_add_cmd):
        error.context("Adding pci device with command 'pci_add'")
        add_output = vm.monitor.send_args_cmd(pci_add_cmd, convert=False)
        pci_info.append(['' , add_output])

        if not "OK domain" in add_output:
            raise error.TestFail("Add PCI device failed. "
                                 "Monitor command is: %s, Output: %r" %
                                 (pci_add_cmd, add_output))
        return  vm.monitor.info("pci")

    def check_support_device(dev):
        if is_qmp_monitor:
            devices_supported = vm.monitor.human_monitor_cmd("%s ?" % cmd_type)
        else:
            devices_supported = vm.monitor.send_args_cmd("%s ?" % cmd_type)
        # Check if the device is support in qemu
        is_support = utils_test.find_substring(devices_supported, dev)
        if not is_support:
            raise error.TestError("%s doesn't support device: %s" %
                                  (cmd_type, dev))


    def device_add_iov(pci_num):
        device_id = "%s" % pci_model + "-" + utils_misc.generate_random_id()
        pci_info.append([device_id])
        check_support_device("pci-assign")
        pci_add_cmd = ("device_add id=%s,driver=pci-assign,host=%s" %
                       (pci_info[pci_num][0], pa_pci_ids[pci_num]))
        if params.get("hotplug_params"):
            assign_param = params.get("hotplug_params").split()
            for param in assign_param:
                value = params.get(param)
                if value:
                    pci_add_cmd += ",%s=%s" % (param, value)
        return device_add(pci_num, pci_add_cmd)

    def device_add(pci_num, pci_add_cmd):
        error.context("Adding pci device with command 'device_add'")
        if is_qmp_monitor:
            add_output = vm.monitor.send_args_cmd(pci_add_cmd)
        else:
            add_output = vm.monitor.send_args_cmd(pci_add_cmd, convert=False)
        pci_info[pci_num].append(add_output)

        after_add = vm.monitor.info("pci")
        if pci_info[pci_num][0] not in after_add:
            logging.debug("Print info pci after add the block: %s" % after_add)
            raise error.TestFail("Add device failed. Monitor command is: %s"
                                 ". Output: %r" % (pci_add_cmd, add_output))
        return after_add

    # Hot add a pci device
    def add_device(pci_num):
        reference_cmd = params.get("reference_cmd")
        find_pci_cmd = params.get("find_pci_cmd")
        info_pci_ref = vm.monitor.info("pci")
        reference = session.cmd_output(reference_cmd)

        try:
            # get function for adding device.
            add_fuction = local_functions["%s_iov" % cmd_type]
        except Exception:
            raise error.TestError("No function for adding sr-iov dev with '%s'" %
                                  cmd_type)
        after_add = None
        if add_fuction:
            # Do add pci device.
            after_add = add_fuction(pci_num)

        try:
            # Define a helper function to compare the output
            def _new_shown():
                o = session.cmd_output(reference_cmd)
                return o != reference

            # Define a helper function to catch PCI device string
            def _find_pci():
                o = session.cmd_output(find_pci_cmd)
                if re.search(match_string, o, re.IGNORECASE):
                    return True
                else:
                    return False

            error.context("Start checking new added device")
            # Compare the output of 'info pci'
            if after_add == info_pci_ref:
                raise error.TestFail("No new PCI device shown after executing "
                                     "monitor command: 'info pci'")

            secs = int(params.get("wait_secs_for_hook_up"))
            if not utils_misc.wait_for(_new_shown, test_timeout, secs, 3):
                raise error.TestFail("No new device shown in output of command "
                                     "executed inside the guest: %s" %
                                     reference_cmd)

            if not utils_misc.wait_for(_find_pci, test_timeout, 3, 3):
                raise error.TestFail("New add sr-iov device not found in guest. "
                                     "Command was: %s" % find_pci_cmd)

            # Test the newly added device
            try:
                session.cmd(params.get("pci_test_cmd") % (pci_num+1))
            except aexpect.ShellError, e:
                raise error.TestFail("Check for sr-iov device failed after PCI "
                                     "hotplug. Output: %r" % e.output)

        except Exception:
            pci_del(pci_num, ignore_failure=True)
            raise

    # Hot delete a pci device
    def pci_del(pci_num, ignore_failure=False):
        def _device_removed():
            after_del = vm.monitor.info("pci")
            return after_del != before_del

        before_del = vm.monitor.info("pci")
        if cmd_type == "pci_add":
            slot_id = "0" + pci_info[pci_num][1].split(",")[2].split()[1]
            cmd = "pci_del pci_addr=%s" % slot_id
            vm.monitor.send_args_cmd(cmd, convert=False)
        elif cmd_type == "device_add":
            cmd = "device_del id=%s" % pci_info[pci_num][0]
            vm.monitor.send_args_cmd(cmd)

        if (not utils_misc.wait_for(_device_removed, test_timeout, 0, 1)
            and not ignore_failure):
            raise error.TestFail("Failed to hot remove PCI device: %s. "
                                 "Monitor command: %s" %
                                 (pci_model, cmd))


    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    timeout = int(params.get("login_timeout", 360))
    session = vm.wait_for_login(timeout=timeout)

    test_timeout = int(params.get("test_timeout", 360))
    # Test if it is nic or block
    pci_num_range = int(params.get("pci_num", 1))
    rp_times = int(params.get("repeat_times", 1))
    pci_model = params.get("pci_model", "pci-assign")
    # Need udpate match_string if you use a card other than 82576
    match_string = params.get("match_string", "82576")
    if vm.pci_assignable is not None:
        pa_pci_ids = vm.pci_assignable.request_devs(pci_num_range)

    # Modprobe the module if specified in config file
    module = params.get("modprobe_module")
    if module:
        error.context("modprobe the module %s" %module, logging.info)
        session.cmd("modprobe %s" % module)

    # check monitor type
    qemu_binary = params.get("qemu_binary", "/usr/bin/qemu-kvm")
    qemu_binary = utils_misc.get_path(test.bindir, qemu_binary)
    is_qmp_monitor = (utils_misc.qemu_has_option("qmp", qemu_binary)
                     and params.get("monitor_type") == "qmp")
    # Probe qemu to verify what is the supported syntax for PCI hotplug
    if is_qmp_monitor:
        cmd_o = vm.monitor.info("commands")
    else:
        cmd_o = vm.monitor.send_args_cmd("help")

    cmd_type = utils_test.find_substring(str(cmd_o), "device_add", "pci_add")
    if not cmd_o:
        raise error.TestError("Unknow version of qemu")


    local_functions = locals()

    for j in range(rp_times):
        # pci_info is a list of list.
        # each element 'i' has 4 members:
        # pci_info[i][0] == device id, only used for device_add
        # pci_info[i][1] == output of device add command
        pci_info = []
        for pci_num in xrange(pci_num_range):
            msg = "Start hot-adding %sth pci device, repeat %d" % (pci_num + 1,
                                                                  j + 1)
            error.context(msg, logging.info)
            add_device(pci_num)
        for pci_num in xrange(pci_num_range):
            msg = "start hot-deleting %sth pci device repeat %d" % (pci_num + 1,
                                                                    j + 1)
            error.context(msg, logging.info)
            pci_del(-(pci_num + 1))
示例#8
0
def run_pci_hotunplug(test, params, env):
    """
    Test hot unplug of PCI devices.

    1) Set up test environment in host if test sr-iov.
    2) Start VM.
    3) Get the device id that want to unplug.
    4) Delete the device, verify whether could remove the PCI device.

    :param test:   QEMU test object.
    :param params: Dictionary with the test parameters.
    :param env:    Dictionary with test environment.
    """

    def find_pci():
        output = vm.monitor.info("qtree")
        devices = re.findall(match_string, output)
        return devices

    # Hot delete a pci device
    def pci_del(device, ignore_failure=False):
        def _device_removed():
            after_del = vm.monitor.info("pci")
            return after_del != before_del

        before_del = vm.monitor.info("pci")
        if cmd_type == "device_del":
            cmd = "device_del id=%s" % device
            vm.monitor.send_args_cmd(cmd)
        else:
            raise error.TestFail("device_del command is not supported")

        if (not utils_misc.wait_for(_device_removed, test_timeout, 0, 1)
                and not ignore_failure):
            raise error.TestFail("Failed to hot remove PCI device: %s. "
                                 "Monitor command: %s" %
                                 (pci_model, cmd))

    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    timeout = int(params.get("login_timeout", 360))
    session = vm.wait_for_login(timeout=timeout)

    test_timeout = int(params.get("test_timeout", 360))
    # Test if it is nic or block
    pci_num = int(params.get("unplug_pci_num", 1))
    pci_model = params.get("pci_model", "pci-assign")
    # Need udpate match_string if you use a card other than 82576
    match_string = params.get("match_string", "dev: %s, id \"(.*)\"")
    match_string = match_string % pci_model

    # Modprobe the module if specified in config file
    module = params.get("modprobe_module")
    if module:
        error.context("modprobe the module %s" % module, logging.info)
        session.cmd("modprobe %s" % module)

    # check monitor type
    is_qmp_monitor = (utils_misc.qemu_has_option("qmp")
                      and params.get("monitor_type") == "qmp")
    # Probe qemu to verify what is the supported syntax for PCI hotplug
    if is_qmp_monitor:
        cmd_o = vm.monitor.info("commands")
    else:
        cmd_o = vm.monitor.send_args_cmd("help")
    if not cmd_o:
        raise error.TestError("Unknow version of qemu")

    cmd_type = utils_test.find_substring(str(cmd_o), "device_del")

    devices = find_pci()
    if devices:
        for device in devices[:pci_num]:
            # (lmr) I think here is the place where pci_info should go
            pci_info = []
            error.context("Hot unplug device %s" % device, logging.info)
            pci_del(device)
示例#9
0
def run_sr_iov_hotplug_negative(test, params, env):
    """
    KVM sr-iov hotplug negatvie test:
    1) Boot up VM.
    2) Try to remove sr-iov device driver module (optional)
    3) Hotplug sr-iov device to VM with negative parameters
    4) Verify that qemu could handle the negative parameters
       check hotplug error message (optional)

    @param test: qemu test object
    @param params: Dictionary with the test parameters
    @param env: Dictionary with test environment.
    """
    def make_pci_add_cmd(pa_pci_id, pci_addr="auto"):
        pci_add_cmd = ("pci_add pci_addr=%s host host=%s,if=%s" %
                       (pci_addr, pa_pci_id, pci_model))
        if params.get("hotplug_params"):
            assign_param = params.get("hotplug_params").split()
            for param in assign_param:
                value = params.get(param)
                if value:
                    pci_add_cmd += ",%s=%s" % (param, value)
        return pci_add_cmd

    def make_device_add_cmd(pa_pci_id, pci_addr=None):
        device_id = "%s" % pci_model + "-" + utils_misc.generate_random_id()
        pci_add_cmd = ("device_add id=%s,driver=pci-assign,host=%s" %
                       (device_id, pa_pci_id))
        if pci_addr is not None:
            pci_add_cmd += ",addr=%s" % pci_addr
        if params.get("hotplug_params"):
            assign_param = params.get("hotplug_params").split()
            for param in assign_param:
                value = params.get(param)
                if value:
                    pci_add_cmd += ",%s=%s" % (param, value)
        return pci_add_cmd

    neg_msg = params.get("negative_msg")
    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    rp_times = int(params.get("repeat_times", 1))
    pci_model = params.get("pci_model", "pci-assign")
    pci_addr = params.get("pci_addr")
    modprobe_cmd = params.get("modprobe_cmd")

    if modprobe_cmd:
        #negative test, both guest and host should still work well.
        msg = "Try to remove sr-iov module in host."
        error.context(msg, logging.info)
        utils.system(modprobe_cmd)
    if vm.pci_assignable is not None:
        pa_pci_ids = vm.pci_assignable.request_devs(1)
    # Probe qemu to verify what is the supported syntax for PCI hotplug
    if vm.monitor.protocol == 'qmp':
        cmd_output = vm.monitor.info("commands")
    else:
        cmd_output = vm.monitor.send_args_cmd("help")

    if not cmd_output:
        raise error.TestError("Unknow version of qemu")

    cmd_type = utils_test.find_substring(str(cmd_output), "pci_add",
                                         "device_add")
    for j in range(rp_times):
        if cmd_type == "pci_add":
            pci_add_cmd = make_pci_add_cmd(pa_pci_ids[0], pci_addr)
        elif cmd_type == "device_add":
            pci_add_cmd = make_device_add_cmd(pa_pci_ids[0], pci_addr)
        try:
            msg = "Adding pci device with command '%s'" % pci_add_cmd
            error.context(msg, logging.info)
            case_fail = False
            add_output = vm.monitor.send_args_cmd(pci_add_cmd, convert=False)
            case_fail = True
        except Exception, e:
            if neg_msg:
                msg = "Check negative hotplug error message"
                error.context(msg, logging.info)
                if neg_msg not in str(e):
                    msg = "Could not find '%s' in error msg '%s'" % (neg_msg,
                                                                     e)
                    raise error.TestFail(msg)
            logging.debug("Could not boot up vm, %s" % e)
        if case_fail:
            raise error.TestFail("Did not raise exception during hotpluging")