Beispiel #1
0
 def test_ping():
     try:
         output = session.cmd_output("lspci -nn | grep %s" % device_name)
         nic_id = str(output).split(' ', 1)[0]
         nic_name = str(utils_misc.get_interface_from_pci_id(nic_id,
                                                             session))
         session.cmd("ip addr flush dev %s" % nic_name)
         session.cmd("ip addr add %s/%s dev %s"
                     % (net_ip, netmask, nic_name))
         session.cmd("ip link set %s up" % nic_name)
         s_ping, o_ping = utils_net.ping(dest=server_ip, count=5,
                                         interface=net_ip)
         logging.info(s_ping)
         logging.info(o_ping)
         if s_ping:
             test.fail("Ping test failed")
     except aexpect.ShellError, detail:
         test.error("Succeed to set ip on guest, but failed "
                    "to bring up interface.\n"
                    "Detail: %s." % detail)
 def test_ping():
     try:
         output = session.cmd_output("lspci -nn | grep %s" % device_name)
         nic_id = str(output).split(' ', 1)[0]
         nic_name = str(utils_misc.get_interface_from_pci_id(nic_id,
                                                             session))
         session.cmd("ip addr flush dev %s" % nic_name)
         session.cmd("ip addr add %s/%s dev %s"
                     % (net_ip, netmask, nic_name))
         session.cmd("ip link set %s up" % nic_name)
         s_ping, o_ping = utils_net.ping(dest=server_ip, count=5,
                                         interface=net_ip)
         logging.info(s_ping)
         logging.info(o_ping)
         if s_ping:
             test.fail("Ping test failed")
     except aexpect.ShellError, detail:
         test.error("Succeed to set ip on guest, but failed "
                    "to bring up interface.\n"
                    "Detail: %s." % detail)
Beispiel #3
0
def run(test, params, env):
    """
    Test for PCI device passthrough to libvirt guest.

    a). NIC:
        1. Get params.
        2. Get the pci device for specific net_name.
        3. Attach Physical Function's/Virtual Function's to single guest
        4. Start guest and set the ip to all the functions.
        5. Ping to server_ip from each function
           to verify the new network device.
    b). STORAGE:
        1. Get params.
        2. Get the pci device for specific storage_dev_name.
        3. Store the result of 'fdisk -l' on guest.
        3. Attach pci device to guest.
        4. Start guest and get the result of 'fdisk -l' on guest.
        5. Compare the result of 'fdisk -l' before and after
            attaching storage pci device to guest.
    """

    # get the params from params
    vm_name = params.get("main_vm")
    vm = env.get_vm(vm_name)
    sriov = ('yes' == params.get("libvirt_pci_SRIOV", 'no'))
    device_type = params.get("libvirt_pci_device_type", "NIC")
    vm_vfs = int(params.get("number_vfs", 2))
    pci_dev = None
    pci_address = None
    bus_info = []
    if device_type == "NIC":
        pf_filter = params.get("pf_filter", "0000:01:00.0")
        vf_filter = params.get("vf_filter", "Virtual Function")
    else:
        pci_dev = params.get("libvirt_pci_storage_dev_label")

    net_ip = params.get("libvirt_pci_net_ip", "ENTER.YOUR.IP")
    server_ip = params.get("libvirt_pci_server_ip", "ENTER.YOUR.SERVER.IP")
    netmask = params.get("libvirt_pci_net_mask", "ENTER.YOUR.Mask")

    # Check the parameters from configuration file.
    if (device_type == "NIC"):
        if (pf_filter.count("ENTER")):
            test.cancel("Please enter your NIC Adapter details for test.")
        if (net_ip.count("ENTER") or server_ip.count("ENTER")
                or netmask.count("ENTER")):
            test.cancel("Please enter the ips and netmask for NIC "
                        "test in config file")
    elif (pci_dev.count("ENTER")):
        test.cancel("Please enter your Storage Adapter details for test.")
    fdisk_list_before = None
    vmxml = VMXML.new_from_inactive_dumpxml(vm_name)
    backup_xml = vmxml.copy()
    if device_type == "NIC":
        if not vm.is_alive():
            vm.start()
        session = vm.wait_for_login()
        nic_list_before = vm.get_pci_devices()
        obj = PciAssignable(pf_filter_re=pf_filter, vf_filter_re=vf_filter)
        # get all functions id's
        pci_ids = obj.get_same_group_devs(pf_filter)
        pci_devs = []
        for val in pci_ids:
            temp = val.replace(":", "_")
            pci_devs.extend(["pci_" + temp])
        if sriov:
            # The SR-IOV setup of the VF's should be done by test_setup
            # PciAssignable class.

            for pf in pci_ids:
                obj.set_vf(pf, vm_vfs)
                cont = obj.get_controller_type()
                if cont == "Infiniband controller":
                    obj.set_linkvf_ib()
            for val in pci_devs:
                val = val.replace(".", "_")
                # Get the virtual functions of the pci devices
                # which was generated above.
                pci_xml = NodedevXML.new_from_dumpxml(val)
                virt_functions = pci_xml.cap.virt_functions
                if not virt_functions:
                    test.fail("No Virtual Functions found.")
                for val in virt_functions:
                    pci_dev = utils_test.libvirt.pci_label_from_address(
                        val, radix=16)
                    pci_xml = NodedevXML.new_from_dumpxml(pci_dev)
                    pci_address = pci_xml.cap.get_address_dict()
                    vmxml.add_hostdev(pci_address)
        else:
            for val in pci_devs:
                val = val.replace(".", "_")
                pci_xml = NodedevXML.new_from_dumpxml(val)
                pci_address = pci_xml.cap.get_address_dict()
                vmxml.add_hostdev(pci_address)

    elif device_type == "STORAGE":
        # Store the result of "fdisk -l" in guest.
        if not vm.is_alive():
            vm.start()
        session = vm.wait_for_login()
        output = session.cmd_output("fdisk -l|grep \"Disk identifier:\"")
        fdisk_list_before = output.splitlines()

        pci_xml = NodedevXML.new_from_dumpxml(pci_dev)
        pci_address = pci_xml.cap.get_address_dict()
        vmxml.add_hostdev(pci_address)
    try:
        vmxml.sync()
        vm.start()
        session = vm.wait_for_login()
        # The Network configuration is generic irrespective of PF or SRIOV VF
        if device_type == "NIC":
            nic_list_after = vm.get_pci_devices()
            net_ip = netaddr.IPAddress(net_ip)
            if sorted(nic_list_after) == sorted(nic_list_before):
                test.fail("Passthrough Adapter not found in guest.")
            else:
                logging.debug("Adapter passthroughed to guest successfully")
            nic_list = list(
                set(nic_list_after).difference(set(nic_list_before)))
            for val in range(len(nic_list)):
                bus_info.append(str(nic_list[val]).split(' ', 1)[0])
                nic_list[val] = str(nic_list[val]).split(' ', 1)[0][:-2]
            bus_info.sort()
            if not sriov:
                # check all functions get same iommu group
                if len(set(nic_list)) != 1:
                    test.fail("Multifunction Device passthroughed but "
                              "functions are in different iommu group")
            # ping to server from each function
            for val in bus_info:
                nic_name = str(
                    utils_misc.get_interface_from_pci_id(val, session))
                session.cmd("ip addr flush dev %s" % nic_name)
                session.cmd("ip addr add %s/%s dev %s" %
                            (net_ip, netmask, nic_name))
                session.cmd("ip link set %s up" % nic_name)
                # Pinging using nic_name is having issue,
                # hence replaced with IPAddress
                s_ping, o_ping = utils_test.ping(server_ip,
                                                 count=5,
                                                 interface=net_ip,
                                                 timeout=30,
                                                 session=session)
                logging.info(o_ping)
                if s_ping != 0:
                    err_msg = "Ping test fails, error info: '%s'"
                    test.fail(err_msg % o_ping)
                # Each interface should have unique IP
                net_ip = net_ip + 1

        elif device_type == "STORAGE":
            # Get the result of "fdisk -l" in guest, and
            # compare the result with fdisk_list_before.
            output = session.cmd_output("fdisk -l|grep \"Disk identifier:\"")
            fdisk_list_after = output.splitlines()
            if fdisk_list_after == fdisk_list_before:
                test.fail("Didn't find the disk attached to guest.")
    finally:
        backup_xml.sync()
        # For SR-IOV , VF's should be cleaned up in the post-processing.
        if sriov:
            if obj.get_vfs_count() != 0:
                for pci_pf in pci_ids:
                    obj.set_vf(pci_pf, vf_no="0")
Beispiel #4
0
def run(test, params, env):
    """
    SR-IOV devices sanity test:
    1) Bring up VFs by following instructions How To in Setup.
    2) Configure all VFs in host.
    3) Check whether all VFs get ip in host.
    4) Unbind PFs/VFs from host kernel driver to sr-iov driver.
    5) Bind PFs/VFs back to host kernel driver.
    6) Repeat step 4, 5.
    7) Try to boot up guest(s) with VF(s).

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

    device_driver = params.get("device_driver", "pci-assign")
    repeat_time = int(params.get("bind_repeat_time", 1))
    configure_on_host = int(params.get("configure_on_host", 0))
    static_ip = int(params.get("static_ip", 1))
    serial_login = params.get("serial_login", "no")
    pci_assignable = test_setup.PciAssignable(
        driver=params.get("driver"),
        driver_option=params.get("driver_option"),
        host_set_flag=params.get("host_set_flag", 1),
        kvm_params=params.get("kvm_default"),
        vf_filter_re=params.get("vf_filter_re"),
        pf_filter_re=params.get("pf_filter_re"),
        device_driver=device_driver,
        pa_type=params.get("pci_assignable"),
        static_ip=static_ip,
        net_mask=params.get("net_mask"),
        start_addr_PF=params.get("start_addr_PF"))

    devices = []
    device_type = params.get("device_type", "vf")
    if device_type == "vf":
        device_num = pci_assignable.get_vfs_count()
        if device_num == 0:
            msg = " No VF device found even after running SR-IOV setup"
            test.cancel(msg)
    elif device_type == "pf":
        device_num = len(pci_assignable.get_pf_vf_info())
    else:
        msg = "Unsupport device type '%s'." % device_type
        msg += " Please set device_type to 'vf' or 'pf'."
        test.error(msg)

    for i in range(device_num):
        device = {}
        device["type"] = device_type
        if device_type == "vf":
            device['mac'] = utils_net.generate_mac_address_simple()
        if params.get("device_name"):
            device["name"] = params.get("device_name")
        devices.append(device)

    pci_assignable.devices = devices
    vf_pci_id = []
    pf_vf_dict = pci_assignable.get_pf_vf_info()
    for pf_dict in pf_vf_dict:
        vf_pci_id.extend(pf_dict["vf_ids"])

    ethname_dict = []
    ips = {}

    # Not all test environments would have a dhcp server to serve IP for
    # all mac addresses. So configure_on_host param has been
    # introduced to choose whether configure VFs on host or not
    if configure_on_host:
        msg = "Configure all VFs in host."
        error_context.context(msg, logging.info)
        for pci_id in vf_pci_id:
            ethname = utils_misc.get_interface_from_pci_id(pci_id)
            mac = utils_net.generate_mac_address_simple()
            ethname_dict.append(ethname)
            # TODO:cleanup of the network scripts
            try:
                utils_net.create_network_script(ethname, mac, "dhcp",
                                                "255.255.255.0", on_boot="yes")
            except Exception as info:
                test.error("Network script creation failed - %s" % info)

        msg = "Check whether VFs could get ip in host."
        error_context.context(msg, logging.info)
        for ethname in ethname_dict:
            utils_net.bring_down_ifname(ethname)
            _ip = check_network_interface_ip(ethname)
            if not _ip:
                msg = "Interface '%s' could not get IP." % ethname
                logging.error(msg)
            else:
                ips[ethname] = _ip
                logging.info("Interface '%s' get IP '%s'", ethname, _ip)

    for i in range(repeat_time):
        msg = "Bind/unbind device from host. Repeat %s/%s" % (i + 1,
                                                              repeat_time)
        error_context.context(msg, logging.info)
        bind_device_num = random.randint(1, device_num)
        pci_assignable.request_devs(devices[:bind_device_num])
        logging.info("Sleep 3s before releasing vf to host.")
        time.sleep(3)
        pci_assignable.release_devs()
        logging.info("Sleep 3s after releasing vf to host.")
        time.sleep(3)
        if device_type == "vf":
            post_device_num = pci_assignable.get_vfs_count()
        else:
            post_device_num = len(pci_assignable.get_pf_vf_info())
        if post_device_num != device_num:
            msg = "lspci cannot report the correct PF/VF number."
            msg += " Correct number is '%s'" % device_num
            msg += " lspci report '%s'" % post_device_num
            test.fail(msg)
    dmesg = process.system_output("dmesg")
    file_name = "host_dmesg_after_unbind_device.txt"
    logging.info("Log dmesg after bind/unbing device to '%s'.", file_name)
    if configure_on_host:
        msg = "Check whether VFs still get ip in host."
        error_context.context(msg, logging.info)
        for ethname in ips:
            utils_net.bring_up_ifname(ethname, action="up")
            _ip = utils_net.get_ip_address_by_interface(ethname, ip_ver="ipv4")
            if not _ip:
                msg = "Interface '%s' could not get IP." % ethname
                msg += "Before bind/unbind it have IP '%s'." % ips[ethname]
                logging.error(msg)
            else:
                logging.info("Interface '%s' get IP '%s'", ethname, _ip)

    msg = "Try to boot up guest(s) with VF(s)."
    error_context.context(msg, logging.info)
    regain_ip_cmd = params.get("regain_ip_cmd", None)
    timeout = int(params.get("login_timeout", 30))

    for vm_name in params["vms"].split(" "):
        params["start_vm"] = "yes"
        vm = env.get_vm(vm_name)
        # User can opt for dhcp IP or a static IP configuration for probed
        # interfaces inside guest. Added option for static IP configuration
        # below
        if static_ip:
            if 'IP_addr_VF' not in locals():
                IP_addr_VF = netaddr.IPAddress(params.get("start_addr_VF"))
                net_mask = params.get("net_mask")
            if not IP_addr_VF:
                test.fail("No IP address found, please"
                          "populate starting IP address in "
                          "configuration file")
            session = vm.wait_for_serial_login(
                timeout=int(params.get("login_timeout", 720)))
            rc, output = session.cmd_status_output(
                "ip li| grep -i 'BROADCAST'|awk '{print $2}'| sed 's/://'")
            if not rc:
                iface_probed = output.splitlines()
                logging.info("probed VF Interface(s) in guest: %s",
                             iface_probed)
                for iface in iface_probed:
                    mac = utils_net.get_linux_mac(session, iface)
                    utils_net.set_guest_ip_addr(session, mac, IP_addr_VF)
                    rc, output = utils_test.ping(
                        str(IP_addr_VF), 30, timeout=60)
                    if rc != 0:
                        test.fail("New nic failed ping test"
                                  "with output:\n %s" % output)
                    IP_addr_VF = IP_addr_VF + 1
            else:
                test.fail("Fail to locate probed interfaces"
                          "for VFs, please check on respective"
                          "drivers in guest image")
        else:
            # User has opted for DHCP IP inside guest
            vm.verify_alive()
            vm.wait_for_login(timeout=int(params.get("login_timeout", 360)))
Beispiel #5
0
def run(test, params, env):
    """
    SR-IOV devices sanity test:
    1) Bring up VFs by following instructions How To in Setup.
    2) Configure all VFs in host.
    3) Check whether all VFs get ip in host.
    4) Unbind PFs/VFs from host kernel driver to sr-iov driver.
    5) Bind PFs/VFs back to host kernel driver.
    6) Repeat step 4, 5.
    7) Try to boot up guest(s) with VF(s).

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

    device_driver = params.get("device_driver", "pci-assign")
    repeat_time = int(params.get("bind_repeat_time", 1))
    configure_on_host = int(params.get("configure_on_host", 0))
    static_ip = int(params.get("static_ip", 1))
    serial_login = params.get("serial_login", "no")
    pci_assignable = test_setup.PciAssignable(
        driver=params.get("driver"),
        driver_option=params.get("driver_option"),
        host_set_flag=params.get("host_set_flag", 1),
        kvm_params=params.get("kvm_default"),
        vf_filter_re=params.get("vf_filter_re"),
        pf_filter_re=params.get("pf_filter_re"),
        device_driver=device_driver,
        pa_type=params.get("pci_assignable"),
        static_ip=static_ip,
        net_mask=params.get("net_mask"),
        start_addr_PF=params.get("start_addr_PF"))

    devices = []
    device_type = params.get("device_type", "vf")
    if device_type == "vf":
        device_num = pci_assignable.get_vfs_count()
        if device_num == 0:
            msg = " No VF device found even after running SR-IOV setup"
            test.cancel(msg)
    elif device_type == "pf":
        device_num = len(pci_assignable.get_pf_vf_info())
    else:
        msg = "Unsupport device type '%s'." % device_type
        msg += " Please set device_type to 'vf' or 'pf'."
        test.error(msg)

    for i in range(device_num):
        device = {}
        device["type"] = device_type
        if device_type == "vf":
            device['mac'] = utils_net.generate_mac_address_simple()
        if params.get("device_name"):
            device["name"] = params.get("device_name")
        devices.append(device)

    pci_assignable.devices = devices
    vf_pci_id = []
    pf_vf_dict = pci_assignable.get_pf_vf_info()
    for pf_dict in pf_vf_dict:
        vf_pci_id.extend(pf_dict["vf_ids"])

    ethname_dict = []
    ips = {}

    # Not all test environments would have a dhcp server to serve IP for
    # all mac addresses. So configure_on_host param has been
    # introduced to choose whether configure VFs on host or not
    if configure_on_host:
        msg = "Configure all VFs in host."
        error_context.context(msg, logging.info)
        for pci_id in vf_pci_id:
            ethname = utils_misc.get_interface_from_pci_id(pci_id)
            mac = utils_net.generate_mac_address_simple()
            ethname_dict.append(ethname)
            # TODO:cleanup of the network scripts
            try:
                utils_net.create_network_script(ethname,
                                                mac,
                                                "dhcp",
                                                "255.255.255.0",
                                                on_boot="yes")
            except Exception as info:
                test.error("Network script creation failed - %s" % info)

        msg = "Check whether VFs could get ip in host."
        error_context.context(msg, logging.info)
        for ethname in ethname_dict:
            utils_net.bring_down_ifname(ethname)
            _ip = check_network_interface_ip(ethname)
            if not _ip:
                msg = "Interface '%s' could not get IP." % ethname
                logging.error(msg)
            else:
                ips[ethname] = _ip
                logging.info("Interface '%s' get IP '%s'", ethname, _ip)

    for i in range(repeat_time):
        msg = "Bind/unbind device from host. Repeat %s/%s" % (i + 1,
                                                              repeat_time)
        error_context.context(msg, logging.info)
        bind_device_num = random.randint(1, device_num)
        pci_assignable.request_devs(devices[:bind_device_num])
        logging.info("Sleep 3s before releasing vf to host.")
        time.sleep(3)
        pci_assignable.release_devs()
        logging.info("Sleep 3s after releasing vf to host.")
        time.sleep(3)
        if device_type == "vf":
            post_device_num = pci_assignable.get_vfs_count()
        else:
            post_device_num = len(pci_assignable.get_pf_vf_info())
        if post_device_num != device_num:
            msg = "lspci cannot report the correct PF/VF number."
            msg += " Correct number is '%s'" % device_num
            msg += " lspci report '%s'" % post_device_num
            test.fail(msg)
    dmesg = process.system_output("dmesg")
    file_name = "host_dmesg_after_unbind_device.txt"
    logging.info("Log dmesg after bind/unbing device to '%s'.", file_name)
    if configure_on_host:
        msg = "Check whether VFs still get ip in host."
        error_context.context(msg, logging.info)
        for ethname in ips:
            utils_net.bring_up_ifname(ethname, action="up")
            _ip = utils_net.get_ip_address_by_interface(ethname, ip_ver="ipv4")
            if not _ip:
                msg = "Interface '%s' could not get IP." % ethname
                msg += "Before bind/unbind it have IP '%s'." % ips[ethname]
                logging.error(msg)
            else:
                logging.info("Interface '%s' get IP '%s'", ethname, _ip)

    msg = "Try to boot up guest(s) with VF(s)."
    error_context.context(msg, logging.info)
    regain_ip_cmd = params.get("regain_ip_cmd", None)
    timeout = int(params.get("login_timeout", 30))

    for vm_name in params["vms"].split(" "):
        params["start_vm"] = "yes"
        vm = env.get_vm(vm_name)
        # User can opt for dhcp IP or a static IP configuration for probed
        # interfaces inside guest. Added option for static IP configuration
        # below
        if static_ip:
            if 'IP_addr_VF' not in locals():
                IP_addr_VF = netaddr.IPAddress(params.get("start_addr_VF"))
                net_mask = params.get("net_mask")
            if not IP_addr_VF:
                test.fail("No IP address found, please"
                          "populate starting IP address in "
                          "configuration file")
            session = vm.wait_for_serial_login(
                timeout=int(params.get("login_timeout", 720)))
            rc, output = session.cmd_status_output(
                "ip li| grep -i 'BROADCAST'|awk '{print $2}'| sed 's/://'")
            if not rc:
                iface_probed = output.splitlines()
                logging.info("probed VF Interface(s) in guest: %s",
                             iface_probed)
                for iface in iface_probed:
                    mac = utils_net.get_linux_mac(session, iface)
                    utils_net.set_guest_ip_addr(session, mac, IP_addr_VF)
                    rc, output = utils_test.ping(str(IP_addr_VF),
                                                 30,
                                                 timeout=60)
                    if rc != 0:
                        test.fail("New nic failed ping test"
                                  "with output:\n %s" % output)
                    IP_addr_VF = IP_addr_VF + 1
            else:
                test.fail("Fail to locate probed interfaces"
                          "for VFs, please check on respective"
                          "drivers in guest image")
        else:
            # User has opted for DHCP IP inside guest
            vm.verify_alive()
            vm.wait_for_login(timeout=int(params.get("login_timeout", 360)))
def run(test, params, env):
    """
    Test for PCI device passthrough to libvirt guest.

    a). NIC:
        1. Get params.
        2. Get the pci device for specific net_name.
        3. Attach pci device to guest.
        4. Start guest and set the ip to all the physical functions.
        5. Ping to server_ip from each physical function
           to verify the new network device.
    b). STORAGE:
        1. Get params.
        2. Get the pci device for specific storage_dev_name.
        3. Store the result of 'fdisk -l' on guest.
        3. Attach pci device to guest.
        4. Start guest and get the result of 'fdisk -l' on guest.
        5. Compare the result of 'fdisk -l' before and after
            attaching storage pci device to guest.
    """

    # get the params from params
    vm_name = params.get("main_vm")
    vm = env.get_vm(vm_name)
    sriov = ('yes' == params.get("libvirt_pci_SRIOV", 'no'))
    device_type = params.get("libvirt_pci_device_type", "NIC")
    pci_dev = None
    device_name = None
    pci_address = None
    bus_info = []
    if device_type == "NIC":
        pci_dev = params.get("libvirt_pci_net_dev_label")
        device_name = params.get("libvirt_pci_net_dev_name", "None")
    else:
        pci_dev = params.get("libvirt_pci_storage_dev_label")

    net_ip = params.get("libvirt_pci_net_ip", "ENTER.YOUR.IP")
    server_ip = params.get("libvirt_pci_server_ip",
                           "ENTER.YOUR.SERVER.IP")
    netmask = params.get("libvirt_pci_net_mask", "ENTER.YOUR.Mask")

    # Check the parameters from configuration file.
    if (pci_dev.count("ENTER")):
        test.cancel("Please enter your device name for test.")
    if (device_type == "NIC" and (net_ip.count("ENTER") or
                                  server_ip.count("ENTER") or
                                  netmask.count("ENTER"))):
        test.cancel("Please enter the ips and netmask for NIC "
                    "test in config file")
    fdisk_list_before = None
    vmxml = VMXML.new_from_inactive_dumpxml(vm_name)
    backup_xml = vmxml.copy()
    if device_type == "NIC":
        if not vm.is_alive():
            vm.start()
        session = vm.wait_for_login()
        output = session.cmd_output("lspci -nn")
        nic_list_before = output.splitlines()
        if sriov:
            # The SR-IOV setup of the VF's should be done by test_setup
            # based on the driver options.
            # Usage of the PciAssignable for setting up of the VF's
            # is generic, and eliminates the need to hardcode the driver
            # and number of VF's to be created.

            sriov_setup = PciAssignable(
                driver=params.get("driver"),
                driver_option=params.get("driver_option"),
                host_set_flag=params.get("host_set_flag", 1),
                vf_filter_re=params.get("vf_filter_re"),
                pf_filter_re=params.get("pf_filter_re"),
                pa_type=params.get("pci_assignable"))

            # For Infiniband Controllers, we have to set the link
            # for the VF's before pass-through.
            cont = sriov_setup.get_controller_type()
            if cont == "Infiniband controller":
                sriov_setup.set_linkvf_ib()

            # Based on the PF Device specified, all the VF's
            # belonging to the same iommu group, will be
            # pass-throughed to the guest.
            pci_id = pci_dev.replace("_", ".").strip("pci.").replace(".", ":", 2)
            pci_ids = sriov_setup.get_same_group_devs(pci_id)
            pci_devs = []
            for val in pci_ids:
                temp = val.replace(":", "_")
                pci_devs.extend(["pci_"+temp])
            pci_id = re.sub('[:.]', '_', pci_id)
            for val in pci_devs:
                val = val.replace(".", "_")
                # Get the virtual functions of the pci devices
                # which was generated above.
                pci_xml = NodedevXML.new_from_dumpxml(val)
                virt_functions = pci_xml.cap.virt_functions
                if not virt_functions:
                    test.fail("No Virtual Functions found.")
                for val in virt_functions:
                    pci_dev = utils_test.libvirt.pci_label_from_address(val,
                                                                        radix=16)
                    pci_xml = NodedevXML.new_from_dumpxml(pci_dev)
                    pci_address = pci_xml.cap.get_address_dict()
                    vmxml.add_hostdev(pci_address)
        else:
            pci_id = pci_dev.replace("_", ".").strip("pci.").replace(".", ":", 2)
            obj = PciAssignable()
            # get all functions id's
            pci_ids = obj.get_same_group_devs(pci_id)
            pci_devs = []
            for val in pci_ids:
                temp = val.replace(":", "_")
                pci_devs.extend(["pci_"+temp])
            pci_id = re.sub('[:.]', '_', pci_id)
            for val in pci_devs:
                val = val.replace(".", "_")
                pci_xml = NodedevXML.new_from_dumpxml(val)
                pci_address = pci_xml.cap.get_address_dict()
                vmxml.add_hostdev(pci_address)

    elif device_type == "STORAGE":
        # Store the result of "fdisk -l" in guest.
        if not vm.is_alive():
            vm.start()
        session = vm.wait_for_login()
        output = session.cmd_output("fdisk -l|grep \"Disk identifier:\"")
        fdisk_list_before = output.splitlines()

        pci_xml = NodedevXML.new_from_dumpxml(pci_dev)
        pci_address = pci_xml.cap.get_address_dict()
        vmxml.add_hostdev(pci_address)
    try:
        vmxml.sync()
        vm.start()
        session = vm.wait_for_login()
        # The Network configuration is generic irrespective of PF or SRIOV VF
        if device_type == "NIC":
            output = session.cmd_output("lspci -nn")
            nic_list_after = output.splitlines()
            net_ip = netaddr.IPAddress(net_ip)
            if nic_list_after == nic_list_before:
                test.fail("passthrough Adapter not found in guest.")
            else:
                logging.debug("Adapter passthorughed to guest successfully")
            output = session.cmd_output("lspci -nn | grep %s" % device_name)
            nic_list = output.splitlines()
            for val in range(len(nic_list)):
                bus_info.append(str(nic_list[val]).split(' ', 1)[0])
                nic_list[val] = str(nic_list[val]).split(' ', 1)[0][:-2]
            bus_info.sort()
            if not sriov:
                # check all functions get same iommu group
                if len(set(nic_list)) != 1:
                    test.fail("Multifunction Device passthroughed but "
                              "functions are in different iommu group")
            # ping to server from each function
            for val in bus_info:
                nic_name = str(utils_misc.get_interface_from_pci_id(val, session))
                session.cmd("ip addr flush dev %s" % nic_name)
                session.cmd("ip addr add %s/%s dev %s"
                            % (net_ip, netmask, nic_name))
                session.cmd("ip link set %s up" % nic_name)
                # Pinging using nic_name is having issue,
                # hence replaced with IPAddress
                s_ping, o_ping = utils_test.ping(server_ip, count=5,
                                                 interface=net_ip, timeout=30,
                                                 session=session)
                logging.info(o_ping)
                if s_ping != 0:
                    err_msg = "Ping test fails, error info: '%s'"
                    test.fail(err_msg % o_ping)
                # Each interface should have unique IP
                net_ip = net_ip + 1

        elif device_type == "STORAGE":
            # Get the result of "fdisk -l" in guest, and
            # compare the result with fdisk_list_before.
            output = session.cmd_output("fdisk -l|grep \"Disk identifier:\"")
            fdisk_list_after = output.splitlines()
            if fdisk_list_after == fdisk_list_before:
                test.fail("Didn't find the disk attached to guest.")
    finally:
        backup_xml.sync()
        # For SR-IOV , VF's should be cleaned up in the post-processing.
        if sriov:
            sriov_setup.release_devs()
def run(test, params, env):
    """
    Test for PCI device passthrough to libvirt guest.

    a). NIC:
        1. Get params.
        2. Get the pci device for specific net_name.
        3. Attach pci device to guest.
        4. Start guest and set the ip to all the physical functions.
        5. Ping to server_ip from each physical function
           to verify the new network device.
    b). STORAGE:
        1. Get params.
        2. Get the pci device for specific storage_dev_name.
        3. Store the result of 'fdisk -l' on guest.
        3. Attach pci device to guest.
        4. Start guest and get the result of 'fdisk -l' on guest.
        5. Compare the result of 'fdisk -l' before and after
            attaching storage pci device to guest.
    """
    # get the params from params
    vm_name = params.get("main_vm")
    vm = env.get_vm(vm_name)
    sriov = ('yes' == params.get("libvirt_pci_SRIOV", 'no'))
    device_type = params.get("libvirt_pci_device_type", "NIC")
    pci_dev = None
    device_name = None
    pci_address = None
    bus_info = []
    if device_type == "NIC":
        pci_dev = params.get("libvirt_pci_net_dev_label")
        device_name = params.get("libvirt_pci_net_dev_name", "None")
    else:
        pci_dev = params.get("libvirt_pci_storage_dev_label")

    net_ip = params.get("libvirt_pci_net_ip", "ENTER.YOUR.IP")
    server_ip = params.get("libvirt_pci_server_ip",
                           "ENTER.YOUR.SERVER.IP")
    netmask = params.get("libvirt_pci_net_mask", "ENTER.YOUR.Mask")

    # Check the parameters from configuration file.
    if (pci_dev.count("ENTER")):
        test.cancel("Please enter your device name for test.")
    if (device_type == "NIC" and (net_ip.count("ENTER") or
                                  server_ip.count("ENTER") or
                                  netmask.count("ENTER"))):
        test.cancel("Please enter the ips and netmask for NIC test in config file")
    fdisk_list_before = None
    vmxml = VMXML.new_from_inactive_dumpxml(vm_name)
    backup_xml = vmxml.copy()
    if device_type == "NIC":
        if not vm.is_alive():
            vm.start()
        session = vm.wait_for_login()
        output = session.cmd_output("lspci -nn")
        nic_list_before = output.splitlines()
        if sriov:
            # set the parameter max_vfs of igb module to 7. Then we can use
            # the virtual function pci device for network device.

            # command 'modprobe -r igb' to unload igb module
            # command '&& modprobe igb max_vfs=7' to load it again
            #          with max_vfs=7
            # command '|| echo 'FAIL' > output_file' is a flag to mean
            #          modprobe igb with max_vfs=7 failed.
            # command '|| modprobe igb' is a handler of error occured
            #          when we load igb again. If command 2 failed,
            #          this command will be executed to recover network.
            output_file = os.path.join(test.tmpdir, "output")
            if os.path.exists(output_file):
                os.remove(output_file)
            mod_cmd = ("modprobe -r igb && modprobe igb max_vfs=7 ||"
                       "echo 'FAIL' > %s && modprobe igb &" % output_file)
            result = process.run(mod_cmd, ignore_status=True, shell=True)
            if os.path.exists(output_file):
                test.error("Failed to modprobe igb with max_vfs=7.")
            # Get the virtual function pci device which was generated above.
            pci_xml = NodedevXML.new_from_dumpxml(pci_dev)
            virt_functions = pci_xml.cap.virt_functions
            if not virt_functions:
                test.error("Init virtual function failed.")
            pci_address = virt_functions[0]
            pci_dev = utils_test.libvirt.pci_label_from_address(pci_address,
                                                                radix=16)
            # Find the network name (ethX) is using this pci device.
            distro_details = distro.detect()
            if distro_details.name == 'Ubuntu':
                network_service = service.Factory.create_service("networking")
            else:
                network_service = service.Factory.create_service("network")
            network_service.restart()
            result = virsh.nodedev_list("net")
            nodedev_nets = result.stdout.strip().splitlines()
            device = None
            for nodedev in nodedev_nets:
                netxml = NodedevXML.new_from_dumpxml(nodedev)
                if netxml.parent == pci_dev:
                    device = nodedev
                    break
            if not device:
                test.error("There is no network name is using "
                           "Virtual Function PCI device %s." %
                           pci_dev)
            pci_xml = NodedevXML.new_from_dumpxml(pci_dev)
            pci_address = pci_xml.cap.get_address_dict()
            vmxml.add_hostdev(pci_address)
        else:
            pci_id = pci_dev.replace("_", ".").strip("pci.").replace(".", ":", 2)
            obj = PciAssignable()
            # get all functions id's
            pci_ids = obj.get_same_group_devs(pci_id)
            pci_devs = []
            for val in pci_ids:
                temp = val.replace(":", "_")
                pci_devs.extend(["pci_"+temp])
            pci_id = re.sub('[:.]', '_', pci_id)
            for val in pci_devs:
                val = val.replace(".", "_")
                pci_xml = NodedevXML.new_from_dumpxml(val)
                pci_address = pci_xml.cap.get_address_dict()
                vmxml.add_hostdev(pci_address)

    elif device_type == "STORAGE":
        # Store the result of "fdisk -l" in guest.
        if not vm.is_alive():
            vm.start()
        session = vm.wait_for_login()
        output = session.cmd_output("fdisk -l|grep \"Disk identifier:\"")
        fdisk_list_before = output.splitlines()

        pci_xml = NodedevXML.new_from_dumpxml(pci_dev)
        pci_address = pci_xml.cap.get_address_dict()
        vmxml.add_hostdev(pci_address)
    try:
        vmxml.sync()
        vm.start()
        session = vm.wait_for_login()
        if device_type == "NIC":
            output = session.cmd_output("lspci -nn")
            nic_list_after = output.splitlines()
            if nic_list_after == nic_list_before:
                test.fail("passthrough Adapter not found in guest.")
            else:
                logging.debug("Adapter passthorughed to guest successfully")
            if sriov:
                try:
                    output = session.cmd_output("lspci -nn | grep %s" % device_name)
                    nic_id = str(output).split(' ', 1)[0]
                    nic_name = str(utils_misc.get_interface_from_pci_id(nic_id, session))
                    session.cmd("ip addr flush dev %s" % nic_name)
                    session.cmd("ip addr add %s/%s dev %s"
                                % (net_ip, netmask, nic_name))
                    session.cmd("ip link set %s up" % nic_name)
                    session.cmd("ping -I %s %s -c 5" % (nic_name, server_ip))
                except aexpect.ShellError, detail:
                    test.error("Succeed to set ip on guest, but failed "
                               "to ping server ip from guest. %s \n" % detail)
            else:
                output = session.cmd_output("lspci -nn | grep %s" % device_name)
                nic_list = output.splitlines()
                for val in range(len(nic_list)):
                    bus_info.append(str(nic_list[val]).split(' ', 1)[0])
                    nic_list[val] = str(nic_list[val]).split(' ', 1)[0][:-2]
                # check all functions get same iommu group
                if len(set(nic_list)) != 1:
                    test.fail("Multifunction Device passthroughed but "
                              "functions are in different iommu group")
                # ping to server from each function
                bus_info.sort()
                for val in bus_info:
                    nic_name = str(utils_misc.get_interface_from_pci_id(val, session))
                    try:
                        session.cmd("ip addr flush dev %s" % nic_name)
                        session.cmd("ip addr add %s/%s dev %s"
                                    % (net_ip, netmask, nic_name))
                        session.cmd("ip link set %s up" % nic_name)
                        session.cmd("ping -I %s %s -c 5" % (nic_name, server_ip))
                    except aexpect.ShellError, detail:
                        test.error("Succeed to set ip on guest, but failed "
                                   "to ping server ip from guest. %s\n" % detail)
Beispiel #8
0
    def add_device(pci_num):
        global iface_scripts
        reference_cmd = params["reference_cmd"]
        info_pci_ref = vm.monitor.info("pci")
        session = vm.wait_for_serial_login(timeout=timeout)
        reference = session.cmd_output(reference_cmd)
        active_nics = get_active_network_device(session, nic_filter)
        logging.debug("Active nics before hotplug - %s", active_nics)

        # Stop the VM monitor and try hot adding SRIOV dev
        if params.get("vm_stop", "no") == "yes":
            logging.debug("stop the monitor of the VM before hotplug")
            vm.pause()
        try:
            # get function for adding device.
            add_function = local_functions["%s_iov" % cmd_type]
        except Exception:
            test.error("No function for adding sr-iov dev with '%s'" %
                       cmd_type)
        after_add = None
        if add_function:
            # Do add pci device.
            after_add = add_function(pci_num)

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

            # Define a helper function to make sure new nic could get ip.
            def _check_ip():
                post_nics = get_active_network_device(session, nic_filter)
                logging.debug("Active nics after hotplug - %s", post_nics)
                return (len(active_nics) <= len(post_nics)
                        and active_nics != post_nics)

            # Define a helper function to catch PCI device string
            def _find_pci():
                output = session.cmd_output("lspci -nn")
                if re.search(vf_filter, output, re.IGNORECASE):
                    return True
                else:
                    return False

            # Resume the VM
            if params.get("vm_resume", "no") == "yes":
                logging.debug("resuming the VM after hotplug")
                vm.resume()

            # Reboot the VM
            if params.get("vm_reboot", "no") == "yes":
                logging.debug("Rebooting the VM after hotplug")
                vm.reboot()
            session = vm.wait_for_serial_login(timeout=timeout)

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

            secs = int(params["wait_secs_for_hook_up"])
            if not utils_misc.wait_for(_new_shown, test_timeout, secs, 3):
                test.fail("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):
                test.fail("New add device not found in guest. "
                          "Command was: lspci -nn")

            # Assign static IP to the hotplugged interface
            if params.get("assign_static_ip", "no") == "yes":
                cmd = "service networking restart"
                static_ip = next(ip_gen)
                net_mask = params.get("static_net_mask", "255.255.255.0")
                broadcast = params.get("static_broadcast", "10.10.10.255")
                pci_id = utils_misc.get_pci_id_using_filter(vf_filter, session)
                logging.debug("PCIs associated with %s - %s", vf_filter,
                              ', '.join(map(str, pci_id)))
                for each_pci in pci_id:
                    iface_name = utils_misc.get_interface_from_pci_id(
                        each_pci, session)
                    logging.debug("Interface associated with PCI %s - %s",
                                  each_pci, iface_name)
                    mac = session.cmd_output("ethtool -P %s" % iface_name)
                    mac = mac.split("Permanent address:")[-1].strip()
                    logging.debug("mac address of %s: %s", iface_name, mac)
                    # backup the network script for other distros
                    if "ubuntu" not in vm.get_distro().lower():
                        cmd = "service network restart"
                        iface_scripts.append(
                            utils_net.get_network_cfg_file(iface_name))
                    if not check_interface(str(iface_name), nic_filter):
                        utils_net.create_network_script(iface_name,
                                                        mac,
                                                        boot_proto="static",
                                                        net_mask=net_mask,
                                                        vm=vm,
                                                        ip_addr=static_ip)
                        status, output = session.cmd_status_output(cmd)
                        if status:
                            test.error("Failed to set static ip in guest: "
                                       "%s" % output)
            # Test the newly added device
            if not utils_misc.wait_for(_check_ip, 120, 3, 3):
                ifconfig = session.cmd_output("ifconfig -a")
                test.fail("New hotpluged device could not get ip "
                          "after 120s in guest. guest ifconfig "
                          "output: \n%s" % ifconfig)
            try:
                session.cmd(params["pci_test_cmd"] % (pci_num + 1))
            except aexpect.ShellError as e:
                test.fail("Check device failed after PCI "
                          "hotplug. Output: %r" % e.output)

        except Exception:
            pci_del(pci_num, ignore_failure=True)
            raise
Beispiel #9
0
    def add_device(pci_num):
        reference_cmd = params["reference_cmd"]
        find_pci_cmd = params["find_pci_cmd"]
        info_pci_ref = vm.monitor.info("pci")
        reference = session.cmd_output(reference_cmd)
        active_nics = get_active_network_device(session, nic_filter)
        logging.debug("Active nics before hotplug - %s", active_nics)
        try:
            # get function for adding device.
            add_fuction = local_functions["%s_iov" % cmd_type]
        except Exception:
            test.error("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():
                output = session.cmd_output(reference_cmd)
                return output != reference

            # Define a helper function to make sure new nic could get ip.
            def _check_ip():
                post_nics = get_active_network_device(session, nic_filter)
                logging.debug("Active nics after hotplug - %s", post_nics)
                return (len(active_nics) <= len(post_nics) and
                        active_nics != post_nics)

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

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

            secs = int(params["wait_secs_for_hook_up"])
            if not utils_misc.wait_for(_new_shown, test_timeout, secs, 3):
                test.fail("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):
                test.fail("New add device not found in guest. "
                          "Command was: %s" % find_pci_cmd)

            # Assign static IP to the hotplugged interface
            if params.get("assign_static_ip", "no") == "yes":
                cmd = []
                static_ip = ip_gen.next()
                net_mask = params.get("static_net_mask", "255.255.255.0")
                broadcast = params.get("static_broadcast", "10.10.10.255")
                pci_id = utils_misc.get_pci_id_using_filter(match_string,
                                                            session)
                logging.debug("PCIs associated with %s - %s", match_string,
                              ', '.join(map(str, pci_id)))
                for each_pci in pci_id:
                    iface_name = utils_misc.get_interface_from_pci_id(each_pci,
                                                                      session)
                    logging.debug("Interface associated with PCI %s - %s",
                                  each_pci, iface_name)
                    if not check_interface(str(iface_name), nic_filter):
                        cmd.append("ifconfig %s %s" % (iface_name, static_ip))
                        cmd.append("ifconfig %s netmask %s" % (iface_name,
                                                               net_mask))
                        cmd.append("ifconfig %s broadcast %s" % (iface_name,
                                                                 broadcast))
                        cmd.append("ifconfig %s up" % iface_name)
                        for each_cmd in cmd:
                            status, output = session.cmd_status_output(each_cmd)
                            if status:
                                test.error("Failed to set static ip in guest: "
                                           "%s" % output)

            # Test the newly added device
            if not utils_misc.wait_for(_check_ip, 120, 3, 3):
                ifconfig = session.cmd_output("ifconfig -a")
                test.fail("New hotpluged device could not get ip "
                          "after 120s in guest. guest ifconfig "
                          "output: \n%s" % ifconfig)
            try:
                session.cmd(params["pci_test_cmd"] % (pci_num + 1))
            except aexpect.ShellError, e:
                test.fail("Check device failed after PCI "
                          "hotplug. Output: %r" % e.output)

        except Exception:
            pci_del(pci_num, ignore_failure=True)
            raise
Beispiel #10
0
    def add_device(pci_num):
        global iface_scripts
        reference_cmd = params["reference_cmd"]
        info_pci_ref = vm.monitor.info("pci")
        session = vm.wait_for_serial_login(timeout=timeout)
        reference = session.cmd_output(reference_cmd)
        active_nics = get_active_network_device(session, nic_filter)
        logging.debug("Active nics before hotplug - %s", active_nics)

        # Stop the VM monitor and try hot adding SRIOV dev
        if params.get("vm_stop", "no") == "yes":
            logging.debug("stop the monitor of the VM before hotplug")
            vm.pause()
        try:
            # get function for adding device.
            add_function = local_functions["%s_iov" % cmd_type]
        except Exception:
            test.error("No function for adding sr-iov dev with '%s'" %
                       cmd_type)
        after_add = None
        if add_function:
            # Do add pci device.
            after_add = add_function(pci_num)

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

            # Define a helper function to make sure new nic could get ip.
            def _check_ip():
                post_nics = get_active_network_device(session, nic_filter)
                logging.debug("Active nics after hotplug - %s", post_nics)
                return (len(active_nics) <= len(post_nics) and
                        active_nics != post_nics)

            # Define a helper function to catch PCI device string
            def _find_pci():
                output = session.cmd_output("lspci -nn")
                if re.search(vf_filter, output, re.IGNORECASE):
                    return True
                else:
                    return False

            # Resume the VM
            if params.get("vm_resume", "no") == "yes":
                logging.debug("resuming the VM after hotplug")
                vm.resume()

            # Reboot the VM
            if params.get("vm_reboot", "no") == "yes":
                logging.debug("Rebooting the VM after hotplug")
                vm.reboot()
            session = vm.wait_for_serial_login(timeout=timeout)

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

            secs = int(params["wait_secs_for_hook_up"])
            if not utils_misc.wait_for(_new_shown, test_timeout, secs, 3):
                test.fail("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):
                test.fail("New add device not found in guest. "
                          "Command was: lspci -nn")

            # Assign static IP to the hotplugged interface
            if params.get("assign_static_ip", "no") == "yes":
                cmd = "service networking restart"
                static_ip = next(ip_gen)
                net_mask = params.get("static_net_mask", "255.255.255.0")
                broadcast = params.get("static_broadcast", "10.10.10.255")
                pci_id = utils_misc.get_pci_id_using_filter(vf_filter,
                                                            session)
                logging.debug("PCIs associated with %s - %s", vf_filter,
                              ', '.join(map(str, pci_id)))
                for each_pci in pci_id:
                    iface_name = utils_misc.get_interface_from_pci_id(each_pci,
                                                                      session)
                    logging.debug("Interface associated with PCI %s - %s",
                                  each_pci, iface_name)
                    mac = session.cmd_output("ethtool -P %s" % iface_name)
                    mac = mac.split("Permanent address:")[-1].strip()
                    logging.debug("mac address of %s: %s", iface_name, mac)
                    # backup the network script for other distros
                    if "ubuntu" not in vm.get_distro().lower():
                        cmd = "service network restart"
                        iface_scripts.append(utils_net.get_network_cfg_file(iface_name))
                    if not check_interface(str(iface_name), nic_filter):
                        utils_net.create_network_script(iface_name, mac,
                                                        boot_proto="static",
                                                        net_mask=net_mask,
                                                        vm=vm,
                                                        ip_addr=static_ip)
                        status, output = session.cmd_status_output(cmd)
                        if status:
                            test.error("Failed to set static ip in guest: "
                                       "%s" % output)
            # Test the newly added device
            if not utils_misc.wait_for(_check_ip, 120, 3, 3):
                ifconfig = session.cmd_output("ifconfig -a")
                test.fail("New hotpluged device could not get ip "
                          "after 120s in guest. guest ifconfig "
                          "output: \n%s" % ifconfig)
            try:
                session.cmd(params["pci_test_cmd"] % (pci_num + 1))
            except aexpect.ShellError as e:
                test.fail("Check device failed after PCI "
                          "hotplug. Output: %r" % e.output)

        except Exception:
            pci_del(pci_num, ignore_failure=True)
            raise
Beispiel #11
0
    def add_device(pci_num):
        reference_cmd = params["reference_cmd"]
        find_pci_cmd = params["find_pci_cmd"]
        info_pci_ref = vm.monitor.info("pci")
        reference = session.cmd_output(reference_cmd)
        active_nics = get_active_network_device(session, nic_filter)
        logging.debug("Active nics before hotplug - %s", active_nics)
        try:
            # get function for adding device.
            add_fuction = local_functions["%s_iov" % cmd_type]
        except Exception:
            test.error("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():
                output = session.cmd_output(reference_cmd)
                return output != reference

            # Define a helper function to make sure new nic could get ip.
            def _check_ip():
                post_nics = get_active_network_device(session, nic_filter)
                logging.debug("Active nics after hotplug - %s", post_nics)
                return (len(active_nics) <= len(post_nics)
                        and active_nics != post_nics)

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

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

            secs = int(params["wait_secs_for_hook_up"])
            if not utils_misc.wait_for(_new_shown, test_timeout, secs, 3):
                test.fail("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):
                test.fail("New add device not found in guest. "
                          "Command was: %s" % find_pci_cmd)

            # Assign static IP to the hotplugged interface
            if params.get("assign_static_ip", "no") == "yes":
                cmd = []
                static_ip = ip_gen.next()
                net_mask = params.get("static_net_mask", "255.255.255.0")
                broadcast = params.get("static_broadcast", "10.10.10.255")
                pci_id = utils_misc.get_pci_id_using_filter(
                    match_string, session)
                logging.debug("PCIs associated with %s - %s", match_string,
                              ', '.join(map(str, pci_id)))
                for each_pci in pci_id:
                    iface_name = utils_misc.get_interface_from_pci_id(
                        each_pci, session)
                    logging.debug("Interface associated with PCI %s - %s",
                                  each_pci, iface_name)
                    if not check_interface(str(iface_name), nic_filter):
                        cmd.append("ifconfig %s %s" % (iface_name, static_ip))
                        cmd.append("ifconfig %s netmask %s" %
                                   (iface_name, net_mask))
                        cmd.append("ifconfig %s broadcast %s" %
                                   (iface_name, broadcast))
                        cmd.append("ifconfig %s up" % iface_name)
                        for each_cmd in cmd:
                            status, output = session.cmd_status_output(
                                each_cmd)
                            if status:
                                test.error("Failed to set static ip in guest: "
                                           "%s" % output)

            # Test the newly added device
            if not utils_misc.wait_for(_check_ip, 120, 3, 3):
                ifconfig = session.cmd_output("ifconfig -a")
                test.fail("New hotpluged device could not get ip "
                          "after 120s in guest. guest ifconfig "
                          "output: \n%s" % ifconfig)
            try:
                session.cmd(params["pci_test_cmd"] % (pci_num + 1))
            except aexpect.ShellError, e:
                test.fail("Check device failed after PCI "
                          "hotplug. Output: %r" % e.output)

        except Exception:
            pci_del(pci_num, ignore_failure=True)
            raise
def run(test, params, env):
    """
    Test for PCI device passthrough to libvirt guest.

    a). NIC:
        1. Get params.
        2. Get the pci device for specific net_name.
        3. Attach pci device to guest.
        4. Start guest and set the ip to all the physical functions.
        5. Ping to server_ip from each physical function
           to verify the new network device.
    b). STORAGE:
        1. Get params.
        2. Get the pci device for specific storage_dev_name.
        3. Store the result of 'fdisk -l' on guest.
        3. Attach pci device to guest.
        4. Start guest and get the result of 'fdisk -l' on guest.
        5. Compare the result of 'fdisk -l' before and after
            attaching storage pci device to guest.
    """
    # get the params from params
    vm_name = params.get("main_vm")
    vm = env.get_vm(vm_name)
    sriov = ('yes' == params.get("libvirt_pci_SRIOV", 'no'))
    device_type = params.get("libvirt_pci_device_type", "NIC")
    pci_dev = None
    device_name = None
    pci_address = None
    bus_info = []
    if device_type == "NIC":
        pci_dev = params.get("libvirt_pci_net_dev_label")
        device_name = params.get("libvirt_pci_net_dev_name", "None")
    else:
        pci_dev = params.get("libvirt_pci_storage_dev_label")

    net_ip = params.get("libvirt_pci_net_ip", "ENTER.YOUR.IP")
    server_ip = params.get("libvirt_pci_server_ip",
                           "ENTER.YOUR.SERVER.IP")
    netmask = params.get("libvirt_pci_net_mask", "ENTER.YOUR.Mask")

    # Check the parameters from configuration file.
    if (pci_dev.count("ENTER")):
        test.cancel("Please enter your device name for test.")
    if (device_type == "NIC" and (net_ip.count("ENTER") or
                                  server_ip.count("ENTER") or
                                  netmask.count("ENTER"))):
        test.cancel("Please enter the ips and netmask for NIC test in config file")
    fdisk_list_before = None
    vmxml = VMXML.new_from_inactive_dumpxml(vm_name)
    backup_xml = vmxml.copy()
    if device_type == "NIC":
        if not vm.is_alive():
            vm.start()
        session = vm.wait_for_login()
        output = session.cmd_output("lspci -nn")
        nic_list_before = output.splitlines()
        if sriov:
            # set the parameter max_vfs of igb module to 7. Then we can use
            # the virtual function pci device for network device.

            # command 'modprobe -r igb' to unload igb module
            # command '&& modprobe igb max_vfs=7' to load it again
            #          with max_vfs=7
            # command '|| echo 'FAIL' > output_file' is a flag to mean
            #          modprobe igb with max_vfs=7 failed.
            # command '|| modprobe igb' is a handler of error occured
            #          when we load igb again. If command 2 failed,
            #          this command will be executed to recover network.
            output_file = os.path.join(test.tmpdir, "output")
            if os.path.exists(output_file):
                os.remove(output_file)
            mod_cmd = ("modprobe -r igb && modprobe igb max_vfs=7 ||"
                       "echo 'FAIL' > %s && modprobe igb &" % output_file)
            result = process.run(mod_cmd, ignore_status=True, shell=True)
            if os.path.exists(output_file):
                test.error("Failed to modprobe igb with max_vfs=7.")
            # Get the virtual function pci device which was generated above.
            pci_xml = NodedevXML.new_from_dumpxml(pci_dev)
            virt_functions = pci_xml.cap.virt_functions
            if not virt_functions:
                test.error("Init virtual function failed.")
            pci_address = virt_functions[0]
            pci_dev = utils_test.libvirt.pci_label_from_address(pci_address,
                                                                radix=16)
            # Find the network name (ethX) is using this pci device.
            distro_details = distro.detect()
            if distro_details.name == 'Ubuntu':
                network_service = service.Factory.create_service("networking")
            else:
                network_service = service.Factory.create_service("network")
            network_service.restart()
            result = virsh.nodedev_list("net")
            nodedev_nets = result.stdout.strip().splitlines()
            device = None
            for nodedev in nodedev_nets:
                netxml = NodedevXML.new_from_dumpxml(nodedev)
                if netxml.parent == pci_dev:
                    device = nodedev
                    break
            if not device:
                test.error("There is no network name is using "
                           "Virtual Function PCI device %s." %
                           pci_dev)
            pci_xml = NodedevXML.new_from_dumpxml(pci_dev)
            pci_address = pci_xml.cap.get_address_dict()
            vmxml.add_hostdev(pci_address)
        else:
            pci_id = pci_dev.replace("_", ".").strip("pci.").replace(".", ":", 2)
            obj = PciAssignable()
            # get all functions id's
            pci_ids = obj.get_same_group_devs(pci_id)
            pci_devs = []
            for val in pci_ids:
                temp = val.replace(":", "_")
                pci_devs.extend(["pci_"+temp])
            pci_id = re.sub('[:.]', '_', pci_id)
            for val in pci_devs:
                val = val.replace(".", "_")
                pci_xml = NodedevXML.new_from_dumpxml(val)
                pci_address = pci_xml.cap.get_address_dict()
                vmxml.add_hostdev(pci_address)

    elif device_type == "STORAGE":
        # Store the result of "fdisk -l" in guest.
        if not vm.is_alive():
            vm.start()
        session = vm.wait_for_login()
        output = session.cmd_output("fdisk -l|grep \"Disk identifier:\"")
        fdisk_list_before = output.splitlines()

        pci_xml = NodedevXML.new_from_dumpxml(pci_dev)
        pci_address = pci_xml.cap.get_address_dict()
        vmxml.add_hostdev(pci_address)
    try:
        vmxml.sync()
        vm.start()
        session = vm.wait_for_login()
        if device_type == "NIC":
            output = session.cmd_output("lspci -nn")
            nic_list_after = output.splitlines()
            if nic_list_after == nic_list_before:
                test.fail("passthrough Adapter not found in guest.")
            else:
                logging.debug("Adapter passthorughed to guest successfully")
            if sriov:
                try:
                    output = session.cmd_output("lspci -nn | grep %s" % device_name)
                    nic_id = str(output).split(' ', 1)[0]
                    nic_name = str(utils_misc.get_interface_from_pci_id(nic_id, session))
                    session.cmd("ip addr flush dev %s" % nic_name)
                    session.cmd("ip addr add %s/%s dev %s"
                                % (net_ip, netmask, nic_name))
                    session.cmd("ip link set %s up" % nic_name)
                    session.cmd("ping -I %s %s -c 5" % (nic_name, server_ip))
                except aexpect.ShellError as detail:
                    test.error("Succeed to set ip on guest, but failed "
                               "to ping server ip from guest. %s \n" % detail)
            else:
                output = session.cmd_output("lspci -nn | grep %s" % device_name)
                nic_list = output.splitlines()
                for val in range(len(nic_list)):
                    bus_info.append(str(nic_list[val]).split(' ', 1)[0])
                    nic_list[val] = str(nic_list[val]).split(' ', 1)[0][:-2]
                # check all functions get same iommu group
                if len(set(nic_list)) != 1:
                    test.fail("Multifunction Device passthroughed but "
                              "functions are in different iommu group")
                # ping to server from each function
                bus_info.sort()
                for val in bus_info:
                    nic_name = str(utils_misc.get_interface_from_pci_id(val, session))
                    try:
                        session.cmd("ip addr flush dev %s" % nic_name)
                        session.cmd("ip addr add %s/%s dev %s"
                                    % (net_ip, netmask, nic_name))
                        session.cmd("ip link set %s up" % nic_name)
                        session.cmd("ping -I %s %s -c 5" % (nic_name, server_ip))
                    except aexpect.ShellError as detail:
                        test.error("Succeed to set ip on guest, but failed "
                                   "to ping server ip from guest. %s\n" % detail)
        elif device_type == "STORAGE":
            # Get the result of "fdisk -l" in guest, and compare the result with
            # fdisk_list_before.
            output = session.cmd_output("fdisk -l|grep \"Disk identifier:\"")
            fdisk_list_after = output.splitlines()
            if fdisk_list_after == fdisk_list_before:
                test.fail("Didn't find the disk attached to guest.")
    finally:
        backup_xml.sync()