示例#1
0
def run(test, params, env):
    """
    Test virsh iface-bridge and iface-unbridge commands.

    (1) Bridge an existing network device(iface-bridge).
    (2) Unbridge a network device(iface-unbridge).
    """

    iface_name = params.get("iface_name")
    bridge_name = params.get("bridge_name")
    ping_ip = params.get("ping_ip", "")
    ping_count = int(params.get("ping_count", "3"))
    ping_timeout = int(params.get("ping_timeout", "5"))
    bridge_option = params.get("bridge_option")
    unbridge_option = params.get("unbridge_option")
    bridge_delay = "yes" == params.get("bridge_delay", "no")
    delay_num = params.get("delay_num", "0")
    create_bridge = "yes" == params.get("create_bridge", "yes")
    bridge_status_error = "yes" == params.get("bridge_status_error", "no")
    unbridge_status_error = "yes" == params.get("unbridge_status_error", "no")
    iface_script = NETWORK_SCRIPT + iface_name
    iface_script_bk = os.path.join(test.tmpdir, "iface-%s.bk" % iface_name)
    check_iface = "yes" == params.get("check_iface", "yes")
    if check_iface:
        # Make sure the interface exists
        if not libvirt.check_iface(iface_name, "exists", "--all"):
            raise error.TestNAError("Interface '%s' not exists" % iface_name)

        net_iface = utils_net.Interface(name=iface_name)
        iface_is_up = net_iface.is_up()
        iface_ip = net_iface.get_ip()

        # Back up the interface script
        utils.run("cp %s %s" % (iface_script, iface_script_bk))

    # Make sure the bridge name not exists
    net_bridge = utils_net.Bridge()
    if bridge_name in net_bridge.list_br():
        raise error.TestNAError("Bridge '%s' already exists" % bridge_name)

    # Stop NetworkManager service
    try:
        NM = utils_path.find_command("NetworkManager")
    except utils_path.CmdNotFoundError:
        logging.debug("No NetworkManager service.")
        NM = None
    NM_is_running = False
    if NM is not None:
        NM_service = service.Factory.create_service("NetworkManager")
        NM_is_running = NM_service.status()
        if NM_is_running:
            NM_service.stop()

    def unbridge_check():
        """
        Check the result after do unbridge.
        """
        list_option = "--all"
        if libvirt.check_iface(bridge_name, "exists", list_option):
            raise error.TestFail("%s is still present." % bridge_name)
        if "no-start" in unbridge_option:
            list_option = "--inactive"
        if not libvirt.check_iface(iface_name, "exists", list_option):
            raise error.TestFail("%s is not present." % iface_name)

    if bridge_delay:
        bridge_option += " --delay %s" % delay_num
    # Run test
    try:
        if create_bridge:
            # Create bridge
            result = virsh.iface_bridge(iface_name, bridge_name, bridge_option)
            libvirt.check_exit_status(result, bridge_status_error)
            if not bridge_status_error:
                # Get the new create bridge IP address
                try:
                    br_ip = utils_net.get_ip_address_by_interface(bridge_name)
                except:
                    br_ip = ""
                # check IP of new bridge
                if check_iface and br_ip and br_ip != iface_ip:
                    raise error.Testfail("bridge IP(%s) isn't the same as iface IP(%s)."
                                         % (br_ip, iface_ip))
                # check the status of STP feature
                if "no-start" not in bridge_option:
                    if "no-stp" not in bridge_option:
                        if "yes" != net_bridge.get_stp_status(bridge_name):
                            raise error.Testfail("Fail to enable STP.")
                # Do ping test only bridge has IP address and ping_ip not empty
                if br_ip and ping_ip:
                    if not libvirt.check_iface(bridge_name, "ping", ping_ip,
                                               count=ping_count, timeout=ping_timeout):
                        raise error.TestFail("Fail to ping %s from %s."
                                             % (ping_ip, bridge_name))
                else:
                    # Skip ping test
                    logging.debug("Skip ping test as %s has no IP address",
                                  bridge_name)
                list_option = ""
                if "no-start" in bridge_option:
                    list_option = "--inactive"
                if libvirt.check_iface(bridge_name, "exists", list_option):
                    # Unbridge
                    result = virsh.iface_unbridge(bridge_name, unbridge_option)
                    libvirt.check_exit_status(result, unbridge_status_error)
                    if not unbridge_status_error:
                        unbridge_check()
                else:
                    raise error.TestFail("%s is not present." % bridge_name)
        else:
            # Unbridge without creating bridge, only for negative test now
            result = virsh.iface_unbridge(bridge_name, unbridge_option)
            libvirt.check_exit_status(result, unbridge_status_error)
            if not unbridge_status_error:
                unbridge_check()
    finally:
        if create_bridge and check_iface:
            if libvirt.check_iface(bridge_name, "exists", "--all"):
                virsh.iface_unbridge(bridge_name)
            if os.path.exists(iface_script_bk):
                utils.run("mv %s %s" % (iface_script_bk, iface_script))
            if iface_is_up:
                # Need reload script
                utils.run("ifdown %s" % iface_name)
                utils.run("ifup %s" % iface_name)
            else:
                net_iface.down()
            # Clear the new create bridge if it exists
            try:
                utils_net.bring_down_ifname(bridge_name)
                utils.run("brctl delbr %s" % bridge_name)
            except utils_net.TAPBringDownError:
                pass
        if NM_is_running:
            NM_service.start()
示例#2
0
def run(test, params, env):
    """
    Test failover by team driver

    1) Boot a vm with 4 nics.
    2) inside guest, configure the team driver.
    3) inside guest, ping host
    4) inside guest, repeated down the slaves one by one.
    5) check ping_result.

    :param test: Kvm test object.
    :param params: Dictionary with the test parameters.
    :param env: Dictionary with test environment.
    """
    def team_port_add(ifnames, team_if):
        """Team0 add ports and return the ip link result for debuging"""
        for port in ifnames:
            session_serial.cmd_output_safe(params["clearip_cmd"] % port)
            session_serial.cmd_output_safe(params["setdown_cmd"] % port)
            session_serial.cmd_output_safe(params["addport_cmd"] % port)
        output_teamnl = session_serial.cmd_output_safe(params["portchk_cmd"])
        ports = re.findall(r"%s" % params["ptn_teamnl"], output_teamnl)
        for port in ifnames:
            if port not in ports:
                raise error.TestFail("Add %s to %s failed." % (port, team_if))
        session_serial.cmd_output_safe(params["killdhclient_cmd"])
        output = session_serial.cmd_output_safe(params["getip_cmd"],
                                                timeout=300)
        team_ip = re.search(r"%s" % params["ptn_ipv4"], output).group()
        if not team_ip:
            raise error.TestFail("Failed to get ip address of %s" % team_if)
        return ports, team_ip

    def failover(ifnames, timeout):
        """func for failover"""
        time.sleep(3)
        starttime = time.time()
        while True:
            pid_ping = session_serial.cmd_output_safe("pidof ping")
            pid = re.findall(r"(\d+)", pid_ping)
            if not pid:
                break
                # if ping finished, will break the loop.
            for port in ifnames:
                session_serial.cmd_output_safe(params["setdown_cmd"] % port)
                time.sleep(random.randint(5, 30))
                session_serial.cmd_output_safe(params["setup_cmd"] % port)
            endtime = time.time()
            timegap = endtime - starttime
            if timegap > timeout:
                break

    def check_ping(status, output):
        """ ratio <5% is acceptance."""
        if status != 0:
            raise error.TestFail("Ping failed, staus:%s, output:%s"
                                 % (status, output))
        # if status != 0 the ping process seams hit issue.
        ratio = utils_test.get_loss_ratio(output)
        if ratio == -1:
            raise error.TestFail('''The ratio is %s, and status is %s,
                                    output is %s''' % (ratio, status, output))
        elif ratio > int(params["failed_ratio"]):
            raise error.TestFail("The loss raito is %s, test failed" % ratio)
        logging.info("ping pass with loss raito:%s, that less than %s" %
                     (ratio, params["failed_ratio"]))

    def team_if_exist():
        """ judge if team is alive well."""
        team_exists_cmd = params.get("team_if_exists_cmd")
        return session_serial.cmd_status(team_exists_cmd) == 0

    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    timeout = int(params.get("login_timeout", 1200))
    session_serial = vm.wait_for_serial_login(timeout=timeout)
    ifnames = [utils_net.get_linux_ifname(session_serial,
                                          vm.get_mac_address(vlan))
               for vlan, nic in enumerate(vm.virtnet)]
    session_serial.cmd_output_safe(params["nm_stop_cmd"])
    team_if = params.get("team_if")
    # initial

    error.context("Step1: Configure the team environment", logging.info)
    # steps of building the teaming environment starts
    modprobe_cmd = "modprobe team"
    session_serial.cmd_output_safe(modprobe_cmd)
    session_serial.cmd_output_safe(params["createteam_cmd"])
    # this cmd is to create the team0 and correspoding userspace daemon
    if not team_if_exist():
        raise error.TestFail("Interface %s is not created." % team_if)
    # check if team0 is created successfully
    ports, team_ip = team_port_add(ifnames, team_if)
    logging.debug("The list of the ports that added to %s : %s"
                  % (team_if, ports))
    logging.debug("The ip address of %s : %s" % (team_if, team_ip))
    output = session_serial.cmd_output_safe(params["team_debug_cmd"])
    logging.debug("team interface configuration: %s" % output)
    route_cmd = session_serial.cmd_output_safe(params["route_cmd"])
    logging.debug("The route table of guest: %s" % route_cmd)
    # this is not this case checkpoint, just to check if route works fine
    # steps of building finished

    try:
        error.context("Login in guest via ssh", logging.info)
        # steps of testing this case starts
        session = vm.wait_for_login(timeout=timeout)
        dest = utils_net.get_ip_address_by_interface(params["netdst"])
        count = params.get("count")
        timeout = float(count) * 2
        error.context("Step2: Check if guest can ping out:", logging.info)
        status, output = utils_test.ping(dest=dest, count=10,
                                         interface=team_if,
                                         timeout=30,
                                         session=session)
        check_ping(status, output)
        # small ping check if the team0 works w/o failover
        error.context("Step3: Start failover testing until ping finished",
                      logging.info)
        failover_thread = utils.InterruptedThread(failover, (ifnames, timeout))
        failover_thread.start()
        # start failover loop until ping finished
        error.context("Step4: Start ping host for %s counts"
                      % count, logging.info)
        if failover_thread.is_alive():
            status, output = utils_test.ping(dest=dest, count=count,
                                             interface=team_if,
                                             timeout=float(count) * 1.5,
                                             session=session)
            error.context("Step5: Check if ping succeeded", logging.info)
            check_ping(status, output)
        else:
            raise error.TestWarn("The failover thread is not alive")
        time.sleep(3)
        try:
            timeout = timeout * 1.5
            failover_thread.join(timeout)
        except Exception:
            raise error.TestWarn("Failed to join the failover thread")
        # finish the main steps and check the result
        session_serial.cmd_output_safe(params["killteam_cmd"])
        if team_if_exist():
            raise error.TestFail("Remove %s failed" % team_if)
        logging.info("%s removed" % team_if)
        # remove the team0 and the daemon, check if succeed
    finally:
        if session:
            session.close()
示例#3
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)))
示例#4
0
def run_netperf_udp(test, params, env):
    """
    Run netperf on server and client side, we need run this case on two
    machines. If dsthost is not set will start netperf server on local
    host and log a error message.:
    1) Start one vm guest os as client.
    2) Start a reference machine (dsthost) as server.
    3) Setup netperf on guest and reference machine (dsthost).
    4) Run netserver on server using control.server.
    5) Run netperf client command in guest several time with different
       message size.
    6) Compare UDP performance to make sure it is acceptable.

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

    def get_remote_host_session():
        dsthostssh = remote.remote_login("ssh", dsthost, 22, "root",
                                         passwd, "#", timeout=30)
        if dsthostssh:
            dsthostssh.set_status_test_command("echo $?")
            return dsthostssh
        else:
            return None

    def scp_to_remote(local_path="", remote_path=""):
        remote.scp_to_remote(dsthost, 22, "root", passwd, local_path,
                             remote_path)
        vm.copy_files_to(local_path, remote_path)

    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()

    session = vm.wait_for_login(timeout=int(params.get("login_timeout", 360)))

    dsthost = params.get("dsthost")
    if not dsthost:
        dsthost = utils_net.get_ip_address_by_interface(params.get("netdst"))
        logging.error("dsthost is not set, use localhost ip %s" % dsthost)
    else:
        logging.info("Dest host is %s" % dsthost)
    passwd = params.get("hostpasswd")
    test_timeout = float(params.get("test_timeout", "1200"))

    error.context("Create session connection to remote machine")
    dsthostssh = utils_misc.wait_for(get_remote_host_session, 120, 0, 2)
    if not dsthostssh:
        raise error.TestError("Could not login into remote host %s " % dsthost)

    # Get range of message size.
    message_size_range = params.get("message_size_range")
    message_size = message_size_range.split()
    start_size = int(message_size[0])
    end_size = int(message_size[1])
    step = int(message_size[2])
    m_size = start_size

    error.context("Copy netperf to dsthost and guest vm.")
    netperf_links = params["netperf_links"].split()
    remote_dir = params.get("remote_dir", "/var/tmp")
    for netperf_link in netperf_links:
        if utils.is_url(netperf_link):
            download_dir = data_dir.get_download_dir()
            md5sum = params.get("pkg_md5sum")
            netperf_dir = utils.unmap_url_cache(download_dir,
                                                netperf_link, md5sum)
        elif netperf_link:
            netperf_dir = os.path.join(test.virtdir, netperf_link)
        scp_to_remote(netperf_dir, remote_dir)

    # Setup netpref.
    error.context("Set up netperf on reference machine.", logging.info)
    cmd = params.get("setup_cmd")
    (status, output) = dsthostssh.cmd_status_output(cmd % remote_dir,
                                                    timeout=test_timeout)
    if status != 0:
        raise error.TestError("Fail to setup netperf on reference machine.")
    error.context("Setup netperf on guest os.", logging.info)
    (status, output) = session.cmd_status_output(cmd % remote_dir,
                                                 timeout=test_timeout)
    if status != 0:
        raise error.TestError("Fail to setup netperf on guest os.")

    # Start netperf server in dsthost.
    cmd = "killall netserver"
    dsthostssh.cmd_status_output(cmd)
    cmd = params.get("netserver_cmd")
    txt = "Run netserver on server (dsthost) using control.server."
    error.context(txt, logging.info)
    (status, output) = dsthostssh.cmd_status_output(cmd)
    if status != 0:
        txt = "Fail to start netperf server on remote machine."
        txt += " Command output: %s" % output
        raise error.TestError(txt)

    throughput = []

    # Run netperf with message size defined in range.
    msg = "Detail result for netperf udp test with different message size.\n"
    while(m_size <= end_size):
        test_protocol = params.get("test_protocol", "UDP_STREAM")
        cmd = params.get("netperf_cmd") % (dsthost, test_protocol, m_size)
        txt = "Run netperf client command in guest: %s" % cmd
        error.context(txt, logging.info)
        (status, output) = session.cmd_status_output(cmd)
        if status != 0:
            txt = "Fail to execute netperf client side command in guest."
            txt += " Command output: %s" % output
            raise error.TestError(txt)
        if test_protocol == "UDP_STREAM":
            speed_index = 6
        elif test_protocol == "UDP_RR":
            speed_index = 7
        else:
            error.TestNAError("Protocol %s is not support" % test_protocol)

        line_tokens = output.splitlines()[speed_index].split()
        if not line_tokens:
            raise error.TestError("Output format is not expected")
        throughput.append(float(line_tokens[5]))

        msg += output
        m_size += step
    file(os.path.join(test.debugdir, "udp_results"), "w").write(msg)

    failratio = float(params.get("failratio", 0.3))
    error.context("Compare UDP performance.", logging.info)
    for i in range(len(throughput) - 1):
        if abs(throughput[i] - throughput[i + 1]) > throughput[i] * failratio:
            txt = "The gap between adjacent throughput is greater than"
            txt += "%f." % failratio
            txt += "Please refer to log file for details:\n %s" % msg
            raise error.TestFail(txt)
    logging.info("The UDP performance as measured via netperf is ok.")
    logging.info("Throughput of netperf command: %s" % throughput)
    logging.debug("Output of netperf command:\n %s" % msg)
    error.context("Kill netperf server on server (dsthost).")

    try:
        remote_files = "%s/netperf*" % remote_dir
        dsthostssh.cmd("killall -9 netserver", ignore_all_errors=True)
        dsthostssh.cmd("rm -rf %s" % remote_files, ignore_all_errors=True)
        session.cmd("rm -rf %s" % remote_files, ignore_all_errors=True)
        session.close()
        dsthostssh.close()
    except Exception:
        pass
示例#5
0
    def __init__(self, test, params, vm):
        """
        Sets class atributes from test parameters.

        @param test: QEMU test object.
        @param params: Dictionary with test parameters.
        """
        root_dir = data_dir.get_data_dir()
        self.deps_dir = os.path.join(test.virtdir, "deps")
        self.unattended_dir = os.path.join(test.virtdir, "unattended")
        self.params = params

        self.attributes = [
            "kernel_args",
            "finish_program",
            "cdrom_cd1",
            "unattended_file",
            "medium",
            "url",
            "kernel",
            "initrd",
            "nfs_server",
            "nfs_dir",
            "install_virtio",
            "floppy_name",
            "cdrom_unattended",
            "boot_path",
            "kernel_params",
            "extra_params",
            "qemu_img_binary",
            "cdkey",
            "finish_program",
            "vm_type",
            "process_check",
            "vfd_size",
        ]

        for a in self.attributes:
            setattr(self, a, params.get(a, ""))

        if self.install_virtio == "yes":
            v_attributes = [
                "virtio_floppy",
                "virtio_storage_path",
                "virtio_network_path",
                "virtio_oemsetup_id",
                "virtio_network_installer",
            ]
            for va in v_attributes:
                setattr(self, va, params.get(va, ""))

        self.tmpdir = test.tmpdir

        if getattr(self, "unattended_file"):
            self.unattended_file = os.path.join(test.virtdir, self.unattended_file)

        if getattr(self, "finish_program"):
            self.finish_program = os.path.join(test.virtdir, self.finish_program)

        if getattr(self, "qemu_img_binary"):
            if not os.path.isfile(getattr(self, "qemu_img_binary")):
                qemu_img_base_dir = os.path.join(data_dir.get_root_dir(), self.params.get("vm_type"))
                self.qemu_img_binary = os.path.join(qemu_img_base_dir, self.qemu_img_binary)

        if getattr(self, "cdrom_cd1"):
            self.cdrom_cd1 = os.path.join(root_dir, self.cdrom_cd1)
        self.cdrom_cd1_mount = tempfile.mkdtemp(prefix="cdrom_cd1_", dir=self.tmpdir)
        if getattr(self, "cdrom_unattended"):
            self.cdrom_unattended = os.path.join(root_dir, self.cdrom_unattended)
        if getattr(self, "kernel"):
            self.kernel = os.path.join(root_dir, self.kernel)
        if getattr(self, "initrd"):
            self.initrd = os.path.join(root_dir, self.initrd)

        if self.medium == "nfs":
            self.nfs_mount = tempfile.mkdtemp(prefix="nfs_", dir=self.tmpdir)

        setattr(self, "floppy", self.floppy_name)
        if getattr(self, "floppy"):
            self.floppy = os.path.join(root_dir, self.floppy)
            if not os.path.isdir(os.path.dirname(self.floppy)):
                os.makedirs(os.path.dirname(self.floppy))

        self.image_path = os.path.dirname(self.kernel)

        # Content server params
        # lookup host ip address for first nic by interface name
        try:
            auto_ip = utils_net.get_ip_address_by_interface(vm.virtnet[0].netdst)
        except utils_net.NetError:
            auto_ip = None

        self.url_auto_content_ip = params.get("url_auto_ip", auto_ip)
        self.url_auto_content_port = None

        # Kickstart server params
        # use the same IP as url_auto_content_ip, but a different port
        self.unattended_server_port = None

        # Embedded Syslog Server
        self.syslog_server_enabled = params.get("syslog_server_enabled", "no")
        self.syslog_server_ip = params.get("syslog_server_ip", auto_ip)
        self.syslog_server_port = int(params.get("syslog_server_port", 5140))
        self.syslog_server_tcp = params.get("syslog_server_proto", "tcp") == "tcp"

        self.vm = vm
示例#6
0
def run(test, params, env):
    """
    Qemu guest irqbalance inactive/active test:
    1) Setup host for sr-iov test.
    2) Boot VM with sr-iov vf/pf assigned and multi vcpu.
    3) Update irqbalance service status in guest. stop/start this server
       according to request.
    4) Get available network interface name in guest.
    5) Start background network stress in guest.
    6) Get irq number assigned to attached vfs/pfs.
    7) Get the cpu number the irq running.
    8) Check specified IRQ count grow on specified cpu.
    9) Repeat step 7 for every 10s.
    10) Balance IRQs generated by vfs/pfs to different vcpus (optional)
       e.g.
       echo 4 > /proc/irq/num/smp_affinity
    11) Repeat step 6, 7
    12) Check that specified IRQ count grow on every cpu. (optional)

    :param test: QEMU test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    """
    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    timeout = int(params.get("login_timeout", 360))
    session = vm.wait_for_login(timeout=timeout)
    irqbalance_check_count = int(params.get("irqbalance_check_count", 36))
    nic_interface_filter = params["nic_interface_filter"]

    error_context.context("Make sure that guest have at least 2 vCPUs.",
                          logging.info)
    cpu_count = vm.get_cpu_count()
    if cpu_count < 2:
        test.cancel("Test requires at least 2 vCPUs.")

    msg = "Update irqbalance service status in guest if not match request."
    error_context.context(msg, logging.info)
    irqbalance_status = params.get("irqbalance_status", "active")
    status = utils_misc.get_guest_service_status(session=session,
                                                 service="irqbalance")
    service_cmd = ""
    if status == "active" and irqbalance_status == "inactive":
        service_cmd = "service irqbalance stop"
    elif status == "inactive" and irqbalance_status == "active":
        service_cmd = "service irqbalance start"
    if service_cmd:
        status, output = session.cmd_status_output(service_cmd)
        if status:
            msg = "Fail to update irqbalance service status in guest."
            msg += " Command output in guest: %s" % output
            test.error(msg)

    error_context.context("Get first network interface name in guest.",
                          logging.info)
    devname = get_first_network_devname(test, session, nic_interface_filter)

    error_context.context("Start background network stress in guest.",
                          logging.info)
    host_ip = utils_net.get_ip_address_by_interface(params.get('netdst'))
    ping_cmd = "ping %s  -f -q" % host_ip
    ping_timeout = irqbalance_check_count * 10 + 100
    ping_session = vm.wait_for_login(timeout=timeout)
    bg_stress = utils_misc.InterruptedThread(utils_test.raw_ping,
                                             kwargs={'command': ping_cmd,
                                                     'timeout': ping_timeout,
                                                     'session': ping_session,
                                                     'output_func': None})
    bg_stress.start()
    try:
        error_context.context("Get irq number assigned to attached "
                              "VF/PF in guest", logging.info)
        irq_nums_dict = get_guest_irq_info(test, session, devname, cpu_count)
        if irq_nums_dict:
            irqs = irq_nums_dict.keys()

        msg = "Check specified IRQ count grow on specified cpu."
        error_context.context(msg, logging.info)
        check_irqbalance(test, session, devname, cpu_count, irqs)
        irq_cpus_dict = {}
        for irq in irqs:
            cpus = get_irq_smp_affinity(test, session, irq)
            irq_cpus_dict[irq] = cpus

        if irqbalance_status == "inactive":
            msg = "balance IRQs generated by vfs/pfs to different vcpus."
            error_context.context(msg, logging.info)
            post_irq_cpus_dict = {}
            for irq in irq_cpus_dict:
                balance_cpu_count = 1
                cpus = []
                for cpu in range(cpu_count):
                    if cpu not in irq_cpus_dict[irq]:
                        cpus.append(cpu)
                        if len(cpus) == balance_cpu_count:
                            break
                set_irq_smp_affinity(test, session, irq, cpus)
                post_irq_cpus_dict[irq] = cpus

            for irq in irqs:
                cpus = get_irq_smp_affinity(test, session, irq)
                msg = "Fail to balance IRQs generated by vf/pf to different cpu"
                if cpus != post_irq_cpus_dict[irq]:
                    test.fail(msg)

        msg = "Check specified IRQ count grow on specified cpu."
        error_context.context(msg, logging.info)
        check_irqbalance(test, session, devname,
                         cpu_count, irqs,
                         count=irqbalance_check_count)

        if irqbalance_status == "active":
            msg = "Check that specified IRQ count grow on every cpu."
            error_context.context(msg, logging.info)
            post_irq_nums_dict = get_guest_irq_info(test, session, devname,
                                                    cpu_count)

            for irq in irqs:
                if irq not in post_irq_nums_dict.keys():
                    post_irqs = post_irq_nums_dict.keys()
                    msg = "Different irq detected: '%s' and '%s'." % (irqs,
                                                                      post_irqs)
                    test.error(msg)
                for cpu in range(cpu_count):
                    if (int(irq_nums_dict[irq][cpu]) >=
                            int(post_irq_nums_dict[irq][cpu])):
                        msg = "'Cpu%s' did not handle more interrupt" % cpu
                        msg += "for irq '%s'." % irq
                        msg += "IRQ balance information for IRQ '%s'\n" % irq
                        msg += "First time: %s\n" % irq_nums_dict
                        msg += "Just now: %s" % post_irq_nums_dict
                        test.fail(msg)
    finally:
        if bg_stress.isAlive():
            bg_stress.join(suppress_exception=True)
        else:
            logging.warn("Background stress test already finished")
示例#7
0
def run(test, params, env):
    """
    Expose host MTU to guest test

    1) Boot up guest with param 'host_mtu=4000' in nic part
    2) Disable NetworkManager in guest
    3) set mtu of guest tap (eg: tap0) and physical nic (eg: eno1) to
       4000 in host
    4) check the mtu in guest
    5) ping from guest to external host with packet size 3972

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

    def get_ovs_ports(ovs):
        """
        Get ovs ports

        :param ovs: ovs bridge name
        """

        cmd = "ovs-vsctl list-ports %s" % ovs
        return process.system_output(cmd, shell=True).decode()

    def is_ovs_backend(netdst):
        """
        Check whether the host is OVS backend

        :param netdst: netdst get from command line
        """

        return netdst in process.system_output("ovs-vsctl list-br",
                                               ignore_status=True,
                                               shell=True).decode()

    def cleanup_ovs_ports(netdst, ports):
        """
        Clean up created ovs ports in this case

        :param netdst: netdst get from command line
        :param ports: existing ports need to be remain before this test
        """

        if is_ovs_backend(netdst) is True:
            ports = set(get_ovs_ports(netdst).splitlines()) - \
                    set(ports.splitlines())
            for p in ports:
                process.system("ovs-vsctl del-port %s %s" % (netdst, p))

    netdst = params.get("netdst", "switch")
    if netdst in utils_net.Bridge().list_br():
        host_hw_interface = utils_net.Bridge().list_iface()[0]
    elif is_ovs_backend(netdst) is True:
        host_hw_interface = get_ovs_ports(netdst)
        tmp_ports = re.findall(r"t[0-9]-[a-zA-Z0-9]{6}", host_hw_interface)
        if tmp_ports:
            for p in tmp_ports:
                process.system_output("ovs-vsctl del-port %s %s" %
                                      (netdst, p))
            host_hw_interface = get_ovs_ports(netdst)
    else:
        test.cancel("The host is using Macvtap backend, which is not"
                    " supported by now!")

    params["start_vm"] = "yes"
    env_process.preprocess_vm(test, params, env, params["main_vm"])

    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()

    vm_iface = vm.get_ifname()
    # TODO, will support windows later
    process.system_output(params["set_mtu_cmd"] % host_hw_interface)
    process.system_output(params["set_mtu_cmd"] % vm_iface)

    os_type = params.get("os_type", "linux")
    login_timeout = float(params.get("login_timeout", 360))
    session = vm.wait_for_login(timeout=login_timeout)

    host_ip = utils_net.get_ip_address_by_interface(params["netdst"])
    if os_type == "linux":  # TODO, will support windows later
        session.cmd_output_safe(params["nm_stop_cmd"])
        guest_ifname = utils_net.get_linux_ifname(session,
                                                  vm.get_mac_address())
        output = session.cmd_output_safe(
                params["check_guest_mtu_cmd"] % guest_ifname)
        error_context.context(output, logging.info)
        match_string = "mtu %s" % params["mtu_value"]
        if match_string in output:
            logging.info("Host mtu %s exposed to guest as expected!" %
                         params["mtu_value"])
            logging.info("Ping from guest to host with packet size 3972")
            status, output = utils_test.ping(host_ip, 10, packetsize=3972,
                                             timeout=30, session=session)
            ratio = utils_test.get_loss_ratio(output)
            if ratio != 0:
                test.fail("Loss ratio is %s", ratio)
        else:
            test.fail("host mtu %s not exposed to guest" % params["mtu_value"])
    cleanup_ovs_ports(netdst, host_hw_interface)
    session.close()
示例#8
0
def run(test, params, env):
    """
    Test bridge support from network

    1) create a linux bridge and connect a physical interface to it
    2) define nwfilter with "vdsm-no-mac-spoofing"
    3) redefine the vm with the new create bridge and filter
    4) check if guest can get public ip after vm start
    5) check if guest and host can ping each other
    6) check if guest and host can ping outside
    7) start another vm connected to the same bridge
    8) check if the 2 guests can ping each other
    """
    def create_bridge(br_name, iface_name):
        """
        Create a linux bridge by virsh cmd:
        1. Stop NetworkManager and Start network service
        2. virsh iface-bridge <iface> <name> [--no-stp]

        :param br_name: bridge name
        :param iface_name: physical interface name
        :return: bridge created or raise exception
        """
        # Make sure the bridge not exist
        if libvirt.check_iface(br_name, "exists", "--all"):
            test.cancel("The bridge %s already exist" % br_name)

        # Create bridge
        # This cmd run a long time, so set timeout=240
        result = virsh.iface_bridge(iface_name,
                                    br_name,
                                    "--no-stp",
                                    debug=True,
                                    timeout=240)
        if result.exit_status:
            test.fail("Failed to create bridge:\n%s" % result.stderr)

    def define_nwfilter(filter_name):
        """
        Define nwfilter vdsm-no-mac-spoofing with content like:
        <filter name='vdsm-no-mac-spoofing' chain='root'>
            <filterref filter='no-mac-spoofing'/>
            <filterref filter='no-arp-mac-spoofing'/>
        </filter>

        :param filter_name: the name of nwfilter
        :return: filter created or raise exception
        """
        filter_uuid = params.get("filter_uuid",
                                 "11111111-b071-6127-b4ec-111111111111")
        filter_params = {
            "filter_name": "vdsm-no-mac-spoofing",
            "filter_chain": "root",
            "filter_uuid": filter_uuid,
            "filterref_name_1": "no-mac-spoofing",
            "filterref_name_2": "no-arp-mac-spoofing"
        }
        filter_xml = libvirt.create_nwfilter_xml(filter_params).xml
        # Run command
        result = virsh.nwfilter_define(filter_xml,
                                       ignore_status=True,
                                       debug=True)
        if result.exit_status:
            test.fail("Failed to define nwfilter with %s" % filter_xml)

    def modify_iface_xml(br_name, nwfilter, vm_name):
        """
        Modify interface xml with the new bridge and the nwfilter

        :param br_name: bridge name
        :param nwfilter: nwfilter name
        :param vm_name: vm name
        """
        vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name)
        iface_xml = vmxml.get_devices('interface')[0]
        vmxml.del_device(iface_xml)
        iface_xml.source = {'bridge': br_name}
        iface_xml.filterref = iface_xml.new_filterref(name=nwfilter)
        logging.debug("new interface xml is: %s" % iface_xml)
        vmxml.add_device(iface_xml)
        vmxml.sync()

    def ping(src_ip, dest_ip, ping_count, timeout, session=None):
        """
        Wrap of ping

        :param src_ip: source address
        :param dest_ip: destination address
        :param ping_count: count of icmp packet
        :param timeout: timeout for the ping command
        :param session: local execution or session to execute the ping command
        :return: ping succeed or raise exception
        """
        status, output = utils_net.ping(dest=dest_ip,
                                        count=ping_count,
                                        interface=src_ip,
                                        timeout=timeout,
                                        session=session)
        if status:
            test.fail("Fail to ping %s from %s" % (dest_ip, src_ip))

    # Get test params
    bridge_name = params.get("bridge_name", "br0")
    filter_name = params.get("filter_name", "vdsm-no-mac-spoofing")
    ping_count = params.get("ping_count", "5")
    ping_timeout = float(params.get("ping_timeout", "10"))
    iface_name = utils_net.get_net_if(state="UP")[0]
    bridge_script = NETWORK_SCRIPT + bridge_name
    iface_script = NETWORK_SCRIPT + iface_name
    iface_script_bk = os.path.join(data_dir.get_tmp_dir(),
                                   "iface-%s.bk" % iface_name)

    vms = params.get("vms").split()
    if len(vms) <= 1:
        test.cancel("Need two VMs to test")
    else:
        vm1_name = vms[0]
        vm2_name = vms[1]

    vm1 = env.get_vm(vm1_name)
    vm2 = env.get_vm(vm2_name)

    # Back up the interface script
    process.run("cp %s %s" % (iface_script, iface_script_bk), shell=True)
    # Back up vm xml
    vm1_xml_bak = vm_xml.VMXML.new_from_dumpxml(vm1_name)
    vm2_xml_bak = vm_xml.VMXML.new_from_dumpxml(vm2_name)

    # Stop NetworkManager service
    NM_service = service.Factory.create_service("NetworkManager")
    NM_status = NM_service.status()
    if NM_status is True:
        NM_service.stop()

    # Start network service
    NW_service = service.Factory.create_service("network")
    NW_status = NW_service.status()
    if NW_status is None:
        logging.debug("network service not found")
        if not utils_package.package_install('network-scripts') or \
                not utils_package.package_install('initscripts'):
            test.cancel("Failed to install network service")
    if NW_status is not True:
        logging.debug("network service is not running")
        NW_service.start()

    try:
        create_bridge(bridge_name, iface_name)
        define_nwfilter(filter_name)
        modify_iface_xml(bridge_name, filter_name, vm1_name)

        if vm1.is_alive():
            vm1.destroy()

        vm1.start()
        # Check if vm can get ip with the new create bridge
        session1 = session2 = None
        try:
            utils_net.update_mac_ip_address(vm1, timeout=120)
            vm1_ip = vm1.get_address()
        except Exception as errs:
            test.fail("vm1 can't get IP with the new create bridge: %s" % errs)

        # Check guest and host can ping each other
        host_ip = utils_net.get_ip_address_by_interface(bridge_name)
        remote_ip = params.get("remote_ip", "www.baidu.com")
        ping(host_ip, vm1_ip, ping_count, ping_timeout)
        ping(host_ip, remote_ip, ping_count, ping_timeout)
        session1 = vm1.wait_for_login()
        ping(vm1_ip, host_ip, ping_count, ping_timeout, session=session1)
        ping(vm1_ip, remote_ip, ping_count, ping_timeout, session=session1)

        # Start vm2 connect to the same bridge
        modify_iface_xml(bridge_name, filter_name, vm2_name)
        if vm2.is_alive():
            vm2.destroy()
        vm2.start()

        # Check if vm1 and vm2 can ping each other
        try:
            utils_net.update_mac_ip_address(vm2, timeout=120)
            vm2_ip = vm2.get_address()
        except Exception as errs:
            test.fail("vm2 can't get IP with the new create bridge: %s" % errs)
        session2 = vm2.wait_for_login()
        ping(vm2_ip, vm1_ip, ping_count, ping_timeout, session=session2)
        ping(vm1_ip, vm2_ip, ping_count, ping_timeout, session=session1)
    finally:
        logging.debug("Start to restore")
        vm1_xml_bak.sync()
        vm2_xml_bak.sync()
        virsh.nwfilter_undefine(filter_name, ignore_status=True)
        if libvirt.check_iface(bridge_name, "exists", "--all"):
            virsh.iface_unbridge(bridge_name, timeout=60, debug=True)
        if os.path.exists(iface_script_bk):
            process.run("mv %s %s" % (iface_script_bk, iface_script),
                        shell=True)
        if os.path.exists(bridge_script):
            process.run("rm -rf %s" % bridge_script, shell=True)
        # reload network configuration
        NW_service.restart()
        # recover NetworkManager
        if NM_status is True:
            NM_service.start()
示例#9
0
def run(test, params, env):
    """
    Test virsh iface-bridge and iface-unbridge commands.

    (1) Bridge an existing network device(iface-bridge).
    (2) Unbridge a network device(iface-unbridge).
    """

    bridge_name = params.get("bridge_name")
    ping_ip = params.get("ping_ip", "")
    ping_count = int(params.get("ping_count", "3"))
    ping_timeout = int(params.get("ping_timeout", "5"))
    bridge_option = params.get("bridge_option")
    unbridge_option = params.get("unbridge_option")
    bridge_delay = "yes" == params.get("bridge_delay", "no")
    delay_num = params.get("delay_num", "0")
    create_bridge = "yes" == params.get("create_bridge", "yes")
    bridge_status_error = "yes" == params.get("bridge_status_error", "no")
    unbridge_status_error = "yes" == params.get("unbridge_status_error", "no")
    iface_name = params.get("iface_name")
    if iface_name == "HOST_INTERFACE":
        # Get the first active nic to test
        iface_name = utils_net.get_net_if(state="UP")[0]
        iface_ip = utils_net.get_ip_address_by_interface(iface_name)

    iface_script = NETWORK_SCRIPT + iface_name
    iface_script_bk = os.path.join(data_dir.get_tmp_dir(),
                                   "iface-%s.bk" % iface_name)
    bridge_script = NETWORK_SCRIPT + bridge_name
    check_iface = "yes" == params.get("check_iface", "yes")

    if check_iface:
        # Make sure the interface exists
        if not libvirt.check_iface(iface_name, "exists", "--all"):
            test.cancel("Interface '%s' not exists" % iface_name)

        # Back up the interface script
        process.run("cp %s %s" % (iface_script, iface_script_bk), shell=True)

    # Make sure the bridge name not exists
    net_bridge = utils_net.Bridge()
    if bridge_name in net_bridge.list_br():
        test.cancel("Bridge '%s' already exists" % bridge_name)

    # Stop NetworkManager service
    NM_service = None
    try:
        NM = utils_path.find_command("NetworkManager")
    except utils_path.CmdNotFoundError:
        logging.debug("No NetworkManager service.")
        NM = None
    if NM is not None:
        NM_service = service.Factory.create_service("NetworkManager")
        NM_is_running = NM_service.status()
        if NM_is_running:
            logging.debug("NM_is_running:%s", NM_is_running)
            logging.debug("Stop NetworkManager...")
            NM_service.stop()

    # Start network service
    NW_service = service.Factory.create_service("network")
    NW_status = NW_service.status()
    if NW_status is None:
        logging.debug("network service not found")
        if (not utils_package.package_install('network-scripts')
                or not utils_package.package_install('initscripts')):
            test.cancel("Failed to install network service")
    if NW_status is not True:
        logging.debug("network service is not running")
        logging.debug("Start network service...")
        NW_service.start()

    def unbridge_check():
        """
        Check the result after do unbridge.
        """
        list_option = "--all"
        if libvirt.check_iface(bridge_name, "exists", list_option):
            test.fail("%s is still present." % bridge_name)
        if "no-start" in unbridge_option:
            list_option = "--inactive"
        if not libvirt.check_iface(iface_name, "exists", list_option):
            test.fail("%s is not present." % iface_name)

    if bridge_delay:
        bridge_option += " --delay %s" % delay_num
    # Run test
    try:
        if create_bridge:
            # Create bridge
            # Set timeout as the cmd run a long time
            result = virsh.iface_bridge(iface_name,
                                        bridge_name,
                                        bridge_option,
                                        timeout=240,
                                        debug=True)
            libvirt.check_exit_status(result, bridge_status_error)
            if not bridge_status_error:
                # Get the new create bridge IP address
                try:
                    br_ip = utils_net.get_ip_address_by_interface(bridge_name)
                except Exception:
                    br_ip = ""
                # check IP of new bridge
                if check_iface and br_ip and br_ip != iface_ip:
                    test.fail("bridge IP(%s) isn't the same as iface IP(%s)." %
                              (br_ip, iface_ip))
                # check the status of STP feature
                if "no-start" not in bridge_option:
                    if "no-stp" not in bridge_option:
                        if "yes" != net_bridge.get_stp_status(bridge_name):
                            test.fail("Fail to enable STP.")
                # Do ping test only bridge has IP address and ping_ip not empty
                if br_ip and ping_ip:
                    if not libvirt.check_iface(bridge_name,
                                               "ping",
                                               ping_ip,
                                               count=ping_count,
                                               timeout=ping_timeout):
                        test.fail("Fail to ping %s from %s." %
                                  (ping_ip, bridge_name))
                else:
                    # Skip ping test
                    logging.debug("Skip ping test as %s has no IP address",
                                  bridge_name)
                list_option = ""
                if "no-start" in bridge_option:
                    list_option = "--inactive"
                if libvirt.check_iface(bridge_name, "exists", list_option):
                    # Unbridge
                    result = virsh.iface_unbridge(bridge_name,
                                                  unbridge_option,
                                                  timeout=60)
                    libvirt.check_exit_status(result, unbridge_status_error)
                    if not unbridge_status_error:
                        unbridge_check()
                else:
                    test.fail("%s is not present." % bridge_name)
        else:
            # Unbridge without creating bridge, only for negative test now
            result = virsh.iface_unbridge(bridge_name, unbridge_option)
            libvirt.check_exit_status(result, unbridge_status_error)
            if not unbridge_status_error:
                unbridge_check()
    finally:
        if create_bridge and check_iface:
            if libvirt.check_iface(bridge_name, "exists", "--all"):
                virsh.iface_unbridge(bridge_name, timeout=60)
            if os.path.exists(iface_script_bk):
                process.run("mv %s %s" % (iface_script_bk, iface_script),
                            shell=True)
            if os.path.exists(bridge_script):
                process.run("rm -rf %s" % bridge_script, shell=True)
            # Clear the new create bridge if it still exists
            try:
                utils_net.bring_down_ifname(bridge_name)
                process.run("ip link del dev %s" % bridge_name, shell=True)
            except utils_net.TAPBringDownError:
                pass
            # Reload network configuration
            NW_service.restart()
            # Recover NetworkManager
            if NM_is_running:
                NM_service.start()
示例#10
0
def run_multi_vms_nics(test, params, env):
    """
    KVM multi test:
    1) Log into guests
    2) Check all the nics available or not
    3) Ping among guest nic and host
       3.1) Ping with different packet size
       3.2) Flood ping test
       3.3) Final ping test
    4) Transfer files among guest nics and host
       4.1) Create file by dd command in guest
       4.2) Transfer file between nics
       4.3) Compare original file and transferred file
    5) ping among different nics
       5.1) Ping with different packet size
       5.2) Flood ping test
       5.3) Final ping test
    6) Transfer files among different nics
       6.1) Create file by dd command in guest
       6.2) Transfer file between nics
       6.3) Compare original file and transferred file
    7) Repeat step 3 - 6 on every nic.

    :param test: QEMU test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    """
    def ping(session, nic, dst_ip, strick_check, flood_minutes):
        d_packet_size = [
            1, 4, 48, 512, 1440, 1500, 1505, 4054, 4055, 4096, 4192, 8878,
            9000, 32767, 65507
        ]
        packet_size = params.get("packet_size", "").split() or d_packet_size
        for size in packet_size:
            error.context("Ping with packet size %s" % size, logging.info)
            status, output = utils_test.ping(dst_ip,
                                             10,
                                             interface=nic,
                                             packetsize=size,
                                             timeout=30,
                                             session=session)
            if strict_check:
                ratio = utils_test.get_loss_ratio(output)
                if ratio != 0:
                    raise error.TestFail("Loss ratio is %s for packet size"
                                         " %s" % (ratio, size))
            else:
                if status != 0:
                    raise error.TestFail("Ping returns non-zero value %s" %
                                         output)

        error.context("Flood ping test", logging.info)
        utils_test.ping(dst_ip,
                        None,
                        interface=nic,
                        flood=True,
                        output_func=None,
                        timeout=flood_minutes * 60,
                        session=session)
        error.context("Final ping test", logging.info)
        counts = params.get("ping_counts", 100)
        status, output = utils_test.ping(dst_ip,
                                         counts,
                                         interface=nic,
                                         timeout=float(counts) * 1.5,
                                         session=session)
        if strick_check == "yes":
            ratio = utils_test.get_loss_ratio(output)
            if ratio != 0:
                raise error.TestFail("Packet loss ratio is %s after flood" %
                                     ratio)
        else:
            if status != 0:
                raise error.TestFail("Ping returns non-zero value %s" % output)

    def file_transfer(session, src, dst):
        username = params.get("username", "")
        password = params.get("password", "")
        src_path = "/tmp/1"
        dst_path = "/tmp/2"
        port = int(params["file_transfer_port"])

        cmd = "dd if=/dev/urandom of=%s bs=100M count=1" % src_path
        cmd = params.get("file_create_cmd", cmd)

        error.context("Create file by dd command, cmd: %s" % cmd, logging.info)
        session.cmd(cmd)

        transfer_timeout = int(params.get("transfer_timeout"))
        log_filename = "scp-from-%s-to-%s.log" % (src, dst)
        error.context("Transfer file from %s to %s" % (src, dst), logging.info)
        remote.scp_between_remotes(src,
                                   dst,
                                   port,
                                   password,
                                   password,
                                   username,
                                   username,
                                   src_path,
                                   dst_path,
                                   log_filename=log_filename,
                                   timeout=transfer_timeout)
        src_path = dst_path
        dst_path = "/tmp/3"
        log_filename = "scp-from-%s-to-%s.log" % (dst, src)
        error.context("Transfer file from %s to %s" % (dst, src), logging.info)
        remote.scp_between_remotes(dst,
                                   src,
                                   port,
                                   password,
                                   password,
                                   username,
                                   username,
                                   src_path,
                                   dst_path,
                                   log_filename=log_filename,
                                   timeout=transfer_timeout)
        error.context("Compare original file and transferred file",
                      logging.info)

        cmd1 = "md5sum /tmp/1"
        cmd2 = "md5sum /tmp/3"
        md5sum1 = session.cmd(cmd1).split()[0]
        md5sum2 = session.cmd(cmd2).split()[0]
        if md5sum1 != md5sum2:
            raise error.TestError("File changed after transfer")

    vm_list = []
    session_list = []
    vms = params["vms"].split()
    timeout = float(params.get("login_timeout", 360))
    mac_ip_filter = params["mac_ip_filter"]
    strict_check = params.get("strick_check", "no")
    host_ip = utils_net.get_ip_address_by_interface(params.get("netdst"))
    host_ip = params.get("srchost", host_ip)
    flood_minutes = float(params["flood_minutes"])
    for vm_name in vms:
        vm = utils_test.get_living_vm(env, vm_name)
        vm_list.append(vm)
        session_list.append(vm.wait_for_login(timeout=timeout))

    ip_list = []

    error.context("Check all the nics available or not", logging.info)
    count_nics = len(params.get("nics").split())
    for i in session_list:
        ips = []
        cmd = params.get("net_check_cmd")
        end_time = time.time() + timeout
        while time.time() < end_time:
            status, output = i.get_command_status_output(cmd)
            if status:
                err_msg = "Can not get ip from guest."
                err_msg += " Cmd '%s' fail with output: %s" % (cmd, output)
                logging.error(err_msg)
            ips = re.findall(mac_ip_filter, output, re.S)
            if count_nics == len(ips):
                break
            time.sleep(2)
        else:
            err_log = "Not all nics get ip.  Set '%s' nics." % count_nics
            err_log += " Guest only get '%s' ip(s). " % len(ips)
            err_log += " Command '%s' output in guest:\n%s" % (cmd, output)
            raise error.TestFail(err_log)
        for ip in ips:
            ip_list.append(ip + (i, ))
    ip_list_len = len(ip_list)
    # ping and file transfer test
    for src_ip_index in range(ip_list_len):
        error.context("Ping test from guest to host", logging.info)
        src_ip_info = ip_list[src_ip_index]
        ping(src_ip_info[3], src_ip_info[0], host_ip, strict_check,
             flood_minutes)
        error.context("File transfer test between guest and host",
                      logging.info)
        file_transfer(src_ip_info[3], src_ip_info[2], host_ip)
        for dst_ip in ip_list[src_ip_index:]:
            txt = "Ping test between %s and %s" % (src_ip_info[2], dst_ip[2])
            error.context(txt, logging.info)
            ping(src_ip_info[3], src_ip_info[0], dst_ip[2], strict_check,
                 flood_minutes)
            txt = "File transfer test between %s " % src_ip_info[2]
            txt += "and %s" % dst_ip[2]
            error.context(txt, logging.info)
            file_transfer(src_ip_info[3], src_ip_info[2], dst_ip[2])
示例#11
0
def run(test, params, env):
    """
    KVM multi test:
    1) Log into guests
    2) Check all the nics available or not
    3) Ping among guest nic and host
       3.1) Ping with different packet size
       3.2) Flood ping test
       3.3) Final ping test
    4) Transfer files among guest nics and host
       4.1) Create file by dd command in guest
       4.2) Transfer file between nics
       4.3) Compare original file and transferred file
    5) ping among different nics
       5.1) Ping with different packet size
       5.2) Flood ping test
       5.3) Final ping test
    6) Transfer files among different nics
       6.1) Create file by dd command in guest
       6.2) Transfer file between nics
       6.3) Compare original file and transferred file
    7) Repeat step 3 - 6 on every nic.

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

    def ping(session, nic, dst_ip, strick_check, flood_minutes):
        d_packet_size = [1, 4, 48, 512, 1440, 1500, 1505, 4054, 4055, 4096,
                         4192, 8878, 9000, 32767, 65507]
        packet_size = params.get("packet_size", "").split() or d_packet_size
        for size in packet_size:
            error.context("Ping with packet size %s" % size, logging.info)
            status, output = utils_test.ping(dst_ip, 10, interface=nic,
                                             packetsize=size,
                                             timeout=30, session=session)
            if strict_check:
                ratio = utils_test.get_loss_ratio(output)
                if ratio != 0:
                    raise error.TestFail("Loss ratio is %s for packet size"
                                         " %s" % (ratio, size))
            else:
                if status != 0:
                    raise error.TestFail("Ping returns non-zero value %s" %
                                         output)

        error.context("Flood ping test", logging.info)
        utils_test.ping(dst_ip, None, interface=nic, flood=True,
                        output_func=None, timeout=flood_minutes * 60,
                        session=session)
        error.context("Final ping test", logging.info)
        counts = params.get("ping_counts", 100)
        status, output = utils_test.ping(dst_ip, counts, interface=nic,
                                         timeout=float(counts) * 1.5,
                                         session=session)
        if strick_check == "yes":
            ratio = utils_test.get_loss_ratio(output)
            if ratio != 0:
                raise error.TestFail("Packet loss ratio is %s after flood"
                                     % ratio)
        else:
            if status != 0:
                raise error.TestFail("Ping returns non-zero value %s" %
                                     output)

    def file_transfer(session, src, dst):
        username = params.get("username", "")
        password = params.get("password", "")
        src_path = "/tmp/1"
        dst_path = "/tmp/2"
        port = int(params["file_transfer_port"])

        cmd = "dd if=/dev/urandom of=%s bs=100M count=1" % src_path
        cmd = params.get("file_create_cmd", cmd)

        error.context("Create file by dd command, cmd: %s" % cmd, logging.info)
        session.cmd(cmd)

        transfer_timeout = int(params.get("transfer_timeout"))
        log_filename = "scp-from-%s-to-%s.log" % (src, dst)
        error.context("Transfer file from %s to %s" % (src, dst), logging.info)
        remote.scp_between_remotes(src, dst, port, password, password,
                                   username, username, src_path, dst_path,
                                   log_filename=log_filename,
                                   timeout=transfer_timeout)
        src_path = dst_path
        dst_path = "/tmp/3"
        log_filename = "scp-from-%s-to-%s.log" % (dst, src)
        error.context("Transfer file from %s to %s" % (dst, src), logging.info)
        remote.scp_between_remotes(dst, src, port, password, password,
                                   username, username, src_path, dst_path,
                                   log_filename=log_filename,
                                   timeout=transfer_timeout)
        error.context("Compare original file and transferred file",
                      logging.info)

        cmd1 = "md5sum /tmp/1"
        cmd2 = "md5sum /tmp/3"
        md5sum1 = session.cmd(cmd1).split()[0]
        md5sum2 = session.cmd(cmd2).split()[0]
        if md5sum1 != md5sum2:
            raise error.TestError("File changed after transfer")

    nic_interface_list = []
    vms = params["vms"].split()
    timeout = float(params.get("login_timeout", 360))
    strict_check = params.get("strick_check", "no")
    host_ip = utils_net.get_ip_address_by_interface(params.get("netdst"))
    host_ip = params.get("srchost", host_ip)
    flood_minutes = float(params["flood_minutes"])
    nic_interface = []
    for vm_name in vms:
        guest_ifname = ""
        guest_ip = ""
        vm = env.get_vm(vm_name)
        session = vm.wait_for_serial_login(timeout=timeout)
        error.context("Check all the nics available or not", logging.info)
        for index, nic in enumerate(vm.virtnet):
            guest_ifname = utils_net.get_linux_ifname(session, nic.mac)
            guest_ip = vm.get_address(index)
            if not (guest_ifname and guest_ip):
                err_log = "vms %s get ip or ifname failed." % vm_name
                err_log = "ifname: %s, ip: %s." % (guest_ifname, guest_ip)
                raise error.TestFail(err_log)
            nic_interface = [guest_ifname, guest_ip, session]
            nic_interface_list.append(nic_interface)

    nic_interface_list_len = len(nic_interface_list)
    # ping and file transfer test
    for src_ip_index in range(nic_interface_list_len):
        error.context("Ping test from guest to host", logging.info)
        src_ip_info = nic_interface_list[src_ip_index]
        ping(src_ip_info[2], src_ip_info[0], host_ip, strict_check,
             flood_minutes)
        error.context("File transfer test between guest and host",
                      logging.info)
        file_transfer(src_ip_info[2], src_ip_info[1], host_ip)
        for dst_ip in nic_interface_list[src_ip_index:]:
            txt = "Ping test between %s and %s" % (src_ip_info[1], dst_ip[1])
            error.context(txt, logging.info)
            ping(src_ip_info[2], src_ip_info[0], dst_ip[1], strict_check,
                 flood_minutes)
            txt = "File transfer test between %s " % src_ip_info[1]
            txt += "and %s" % dst_ip[1]
            error.context(txt, logging.info)
            file_transfer(src_ip_info[2], src_ip_info[1], dst_ip[1])
示例#12
0
def run(test, params, env):
    """
    Test port mirror between guests in one ovs backend

    1) Boot the three vms.
    2) Set tap device of vm1 to mirror (input, output, input & output)
       of tap device of vm2 in openvswith.
    3) Start two tcpdump threads to dump icmp packet from vm2 and vm3.
    4) Ping host from vm2 and vm3.
    5) Stop ping in vm2 and vm3
    6) Check tcmpdump result in vm1.

    :param test: Kvm test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    """
    def make_mirror_cmd(mirror_port,
                        target_port,
                        direction="all",
                        netdst="ovs0"):
        """
        Generate create ovs port mirror command.

        :parm mirror_port: port name in ovs in mirror status.
        :parm target_port: port name in ovs be mirroring.
        :parm direction: mirror direction, all, only input or output.
        :parm netdst: ovs port name.

        :return: string of ovs port mirror command.
        """
        cmd = ["ovs-vsctl set Bridge %s mirrors=@m " % netdst]
        fun = lambda x: "-- --id=@%s get Port %s " % (x, x)
        cmd += map(fun, [mirror_port, target_port])
        if direction == "input":
            cmd.append("-- --id=@m create Mirror name=input_of_%s" %
                       target_port)
            cmd.append("select-dst-port=@%s" % target_port)
        elif direction == "output":
            cmd.append("-- --id=@m create Mirror name=output_of_%s" %
                       target_port)
            cmd.append("select-src-port=@%s" % target_port)
        else:
            cmd.append("-- --id=@m create Mirror name=mirror_%s" % target_port)
            cmd.append("select-src-port=@%s" % target_port)
            cmd.append("select-dst-port=@%s" % target_port)
        cmd.append("output-port=@%s" % mirror_port)
        return " ".join(cmd)

    def create_mirror_port(mirror_port, target_port, direction, netdst):
        """
        Execute ovs port mirror command and check port really in mirror status.

        :parm mirror_port: port name in ovs in mirror status.
        :parm target_port: port name in ovs be mirroring.
        :parm direction: mirror direction, all, only input or output.
        :parm netdst: ovs port name.
        """
        mirror_cmd = make_mirror_cmd(mirror_port, target_port, direction,
                                     netdst)
        uuid = utils.system_output(mirror_cmd)
        output = utils.system_output("ovs-vsctl list mirror")
        if uuid not in output:
            logging.debug("Create OVS Mirror CMD: %s " % mirror_cmd)
            logging.debug("Ovs Info: %s " % output)
            raise error.TestFail("Setup mirorr port failed")

    def checkTcpdump(output, target_ip, host_ip, direction):
        """
        Check tcpdump result file and report unexpect packet to debug log.

        :parm output: string of tcpdump output.
        :parm target_p: ip of port in ovs be mirroring.
        :parm host_ip: ip of ovs port.
        :parm direction: mirror direction, all, only input or output.

        :return: bool type result.
        """
        rex = r".*IP (%s|%s) > " % (host_ip, target_ip)
        rex += "(%s|%s).*ICMP echo.*" % (target_ip, host_ip)
        if direction == "input":
            rex = r".*IP %s > %s.*ICMP echo reply.*" % (host_ip, target_ip)
        if direction == "output":
            rex = r".*IP %s > %s.*ICMP echo request.*" % (target_ip, host_ip)
        for idx, _ in enumerate(output.splitlines()):
            if not re.match(rex, _):
                logging.debug("Unexpect packet in line %d: %s" % (idx, _))
                return False
        return True

    os_dep.command("ovs-vsctl")
    if params.get("netdst") not in utils.system_output("ovs-vsctl show"):
        raise error.TestError("This is a openvswitch only test")

    netdst = params.get("netdst", "ovs0")
    direction = params.get("direction", "all")
    mirror_vm = params.get("mirror_vm", "vm1")
    target_vm = params.get("target_vm", "vm2")
    refer_vm = params.get("refer_vm", "vm3")
    login_timeout = int(params.get("login_timeout", "600"))
    ip_version = params.get("ip_version", "ipv4")
    host_ip = utils_net.get_ip_address_by_interface(netdst)
    try:
        vms_info = {}
        for p_vm in params.get("vms").split():
            o_vm = env.get_vm(p_vm)
            o_vm.verify_alive()
            session = o_vm.wait_for_serial_login(timeout=login_timeout)
            ifname = o_vm.get_ifname()
            ip = o_vm.wait_for_get_address(0,
                                           timeout=login_timeout,
                                           ip_version=ip_version)
            vms_info[p_vm] = [o_vm, ifname, ip, session]

        mirror_ifname = vms_info[mirror_vm][1]
        target_ifname = vms_info[target_vm][1]
        target_ip = vms_info[target_vm][2]
        refer_ip = vms_info[refer_vm][2]
        session = vms_info[mirror_vm][3]

        error.context("Create mirror port in ovs", logging.info)
        create_mirror_port(mirror_ifname, target_ifname, direction, netdst)
        ping_cmd = "ping -c 10 %s" % host_ip
        status, output = session.cmd_status_output(ping_cmd, timeout=60)
        if status == 0:
            ifcfg = session.cmd_output_safe("ifconfig")
            logging.debug("Guest network info: %s" % ifcfg)
            logging.debug("Ping results: %s" % output)
            raise error.TestFail("All packets from %s to host should lost" %
                                 mirror_vm)

        error.context("Start tcpdump threads in %s" % mirror_vm, logging.info)
        session.cmd("ifconfig eth0 0 up", timeout=60)
        for vm, ip in [(target_vm, target_ip), (refer_vm, refer_ip)]:
            tcpdump_cmd = "tcpdump -l -n host %s and icmp >" % ip
            tcpdump_cmd += "/tmp/tcpdump-%s.txt &" % vm
            session.sendline(tcpdump_cmd)
            time.sleep(0.5)

        error.context("Start ping threads in %s %s" % (target_vm, refer_vm),
                      logging.info)
        for vm in [target_vm, refer_vm]:
            ses = vms_info[vm][3]
            ses.cmd("ping %s -c 100" % host_ip, timeout=150)

        error.context("Check tcpdump results", logging.info)
        session.cmd_output_safe("pkill tcpdump")
        utils.system("ovs-vsctl clear bridge %s mirrors" % netdst)
        session.cmd("service network restart", timeout=60)
        for vm in [target_vm, refer_vm]:
            src_file = "/tmp/tcpdump-%s.txt" % vm
            dst_file = os.path.join(test.resultsdir, "tcpdump-%s.txt" % vm)
            vms_info[mirror_vm][0].copy_files_from(src_file, dst_file)
            fd = open(dst_file, "r")
            content = fd.read().strip()
            fd.close()
            if vm == refer_vm and content:
                raise error.TestFail("should not packet from %s dumped in %s" %
                                     (refer_vm, mirror_vm))
            elif not checkTcpdump(content, target_ip, host_ip, direction):
                raise error.TestFail("Unexpect packages from %s dumped in %s" %
                                     (vm, mirror_vm))
    finally:
        for f in glob.glob("/var/log/openvswith/*.log"):
            dst = os.path.join(test.resultsdir, os.path.basename(f))
            shutil.copy(f, dst)
示例#13
0
def run(test, params, env):
    """
    Expose host MTU to guest test

    1) Boot up guest with param 'host_mtu=4000' in nic part
    2) Disable NetworkManager in guest
    3) set mtu of guest tap (eg: tap0) and physical nic (eg: eno1) to
       4000 in host
    4) check the mtu in guest
    5) ping from guest to external host with packet size 3972

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

    def cleanup_ovs_ports(netdst, ports):
        """
        Clean up created ovs ports in this case

        :param netdst: netdst get from command line
        :param ports: existing ports need to be remain before this test
        """

        host_bridge = utils_net.find_bridge_manager(netdst)
        if utils_net.ovs_br_exists(netdst) is True:
            ports = set(host_bridge.list_ports(netdst)) - set(ports)
            for p in ports:
                utils_net.find_bridge_manager(netdst).del_port(netdst, p)

    netdst = params.get("netdst", "switch")
    host_bridge = utils_net.find_bridge_manager(netdst)
    if netdst in utils_net.Bridge().list_br():
        host_hw_interface = utils_net.Bridge().list_iface(netdst)[0]
    else:
        host_hw_interface = host_bridge.list_ports(netdst)
        tmp_ports = re.findall(r"t[0-9]{1,}-[a-zA-Z0-9]{6}",
                               ' '.join(host_hw_interface))
        if tmp_ports:
            for p in tmp_ports:
                host_bridge.del_port(netdst, p)
            host_hw_interface = host_bridge.list_ports(netdst)

    params["start_vm"] = "yes"
    env_process.preprocess_vm(test, params, env, params["main_vm"])

    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()

    vm_iface = vm.get_ifname()
    # Get host interface original mtu value before setting
    if netdst in utils_net.Bridge().list_br():
        host_hw_iface = utils_net.Interface(host_hw_interface)
    elif utils_net.ovs_br_exists(netdst) is True:
        host_hw_iface = utils_net.Interface(' '.join(host_hw_interface))
    host_mtu_origin = host_hw_iface.get_mtu()

    utils_net.Interface(vm_iface).set_mtu(int(params["mtu_value"]))
    host_hw_iface.set_mtu(int(params["mtu_value"]))

    os_type = params.get("os_type", "linux")
    login_timeout = float(params.get("login_timeout", 360))
    session = vm.wait_for_login(timeout=login_timeout)

    host_ip = utils_net.get_ip_address_by_interface(params["netdst"])
    if os_type == "linux":
        session.cmd_output_safe(params["nm_stop_cmd"])
        guest_ifname = utils_net.get_linux_ifname(session,
                                                  vm.get_mac_address())
        output = session.cmd_output_safe(
            params["check_linux_mtu_cmd"] % guest_ifname)
        error_context.context(output, logging.info)
        match_string = "mtu %s" % params["mtu_value"]
        if match_string not in output:
            test.fail("host mtu %s not exposed to guest" % params["mtu_value"])
    elif os_type == "windows":
        connection_id = utils_net.get_windows_nic_attribute(
            session, "macaddress", vm.get_mac_address(), "netconnectionid")
        output = session.cmd_output_safe(
            params["check_win_mtu_cmd"] % connection_id)
        error_context.context(output, logging.info)
        lines = output.strip().splitlines()
        lines_len = len(lines)

        line_table = lines[0].split('  ')
        line_value = lines[2].split('  ')
        while '' in line_table:
            line_table.remove('')
        while '' in line_value:
            line_value.remove('')
        index = 0
        for name in line_table:
            if re.findall("MTU", name):
                break
            index += 1
        mtu_value = line_value[index]
        logging.info("MTU is %s", mtu_value)
        if not int(mtu_value) == int(params["mtu_value"]):
            test.fail("Host mtu %s is not exposed to "
                      "guest!" % params["mtu_value"])

    logging.info("Ping from guest to host with packet size 3972")
    status, output = utils_test.ping(host_ip, 10, packetsize=3972,
                                     timeout=30, session=session)
    ratio = utils_test.get_loss_ratio(output)
    if ratio != 0:
        test.fail("Loss ratio is %s", ratio)

    # Restore host mtu after finish testing
    utils_net.Interface(vm_iface).set_mtu(host_mtu_origin)
    host_hw_iface.set_mtu(host_mtu_origin)

    if netdst not in utils_net.Bridge().list_br():
        cleanup_ovs_ports(netdst, host_hw_interface)
    session.close()
示例#14
0
def run(test, params, env):
    """
    Expose host MTU to guest test

    1) Boot up guest with param 'host_mtu=4000' in nic part
    2) Disable NetworkManager in guest
    3) set mtu of guest tap (eg: tap0) and physical nic (eg: eno1) to
       4000 in host
    4) check the mtu in guest
    5) ping from guest to external host with packet size 3972

    :param test: kvm test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment
    """
    def get_ovs_ports(ovs):
        """
        Get ovs ports

        :param ovs: ovs bridge name
        """

        cmd = "ovs-vsctl list-ports %s" % ovs
        return process.system_output(cmd, shell=True).decode()

    def is_ovs_backend(netdst):
        """
        Check whether the host is OVS backend

        :param netdst: netdst get from command line
        """

        return netdst in process.system_output("ovs-vsctl list-br",
                                               ignore_status=True,
                                               shell=True).decode()

    def cleanup_ovs_ports(netdst, ports):
        """
        Clean up created ovs ports in this case

        :param netdst: netdst get from command line
        :param ports: existing ports need to be remain before this test
        """

        if is_ovs_backend(netdst) is True:
            ports = set(get_ovs_ports(netdst).splitlines()) - \
                set(ports.splitlines())
            for p in ports:
                process.system("ovs-vsctl del-port %s %s" % (netdst, p))

    netdst = params.get("netdst", "switch")
    if netdst in utils_net.Bridge().list_br():
        host_hw_interface = utils_net.Bridge().list_iface(netdst)[0]
    elif is_ovs_backend(netdst) is True:
        host_hw_interface = get_ovs_ports(netdst)
        tmp_ports = re.findall(r"t[0-9]{1,}-[a-zA-Z0-9]{6}", host_hw_interface)
        if tmp_ports:
            for p in tmp_ports:
                process.system_output("ovs-vsctl del-port %s %s" % (netdst, p))
            host_hw_interface = get_ovs_ports(netdst)
    else:
        test.cancel("The host is using Macvtap backend, which is not"
                    " supported by now!")

    params["start_vm"] = "yes"
    env_process.preprocess_vm(test, params, env, params["main_vm"])

    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()

    vm_iface = vm.get_ifname()
    # TODO, will support windows later
    process.system_output(params["set_mtu_cmd"] % host_hw_interface)
    process.system_output(params["set_mtu_cmd"] % vm_iface)

    os_type = params.get("os_type", "linux")
    login_timeout = float(params.get("login_timeout", 360))
    session = vm.wait_for_login(timeout=login_timeout)

    host_ip = utils_net.get_ip_address_by_interface(params["netdst"])
    if os_type == "linux":  # TODO, will support windows later
        session.cmd_output_safe(params["nm_stop_cmd"])
        guest_ifname = utils_net.get_linux_ifname(session,
                                                  vm.get_mac_address())
        output = session.cmd_output_safe(params["check_guest_mtu_cmd"] %
                                         guest_ifname)
        error_context.context(output, logging.info)
        match_string = "mtu %s" % params["mtu_value"]
        if match_string in output:
            logging.info("Host mtu %s exposed to guest as expected!" %
                         params["mtu_value"])
            logging.info("Ping from guest to host with packet size 3972")
            status, output = utils_test.ping(host_ip,
                                             10,
                                             packetsize=3972,
                                             timeout=30,
                                             session=session)
            ratio = utils_test.get_loss_ratio(output)
            if ratio != 0:
                test.fail("Loss ratio is %s", ratio)
        else:
            test.fail("host mtu %s not exposed to guest" % params["mtu_value"])
    cleanup_ovs_ports(netdst, host_hw_interface)
    session.close()
def run(test, params, env):
    """
    KVM migration test:
    1) Get a live VM and clone it.
    2) Verify that the source VM supports migration. If it does, proceed with
       the test.
    3) Hotplug a nic.
    4) Disable the primary link of guest.
    5) Check if new interface gets ip address.
    6) Ping guest's new ip from host.
    7) Re-enabling the primary link.
    8) Send a migration command to the source VM and wait until it's finished.
    9) Disable the primary link again.
    10) Ping guest's new ip from host.
    11) Re-enabling the primary link.

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

    def set_link(nic_name, up=False):
        for nic in vm.virtnet:
            if nic.nic_name != nic_name:
                vm.set_link(nic.device_id, up=up)

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

    guest_is_not_windows = (params.get("os_type") != 'windows')
    run_dhclient = params.get("run_dhclient", "no")
    mig_timeout = float(params.get("mig_timeout", "3600"))
    nettype = params.get("nettype", "bridge")
    netdst = params.get("netdst", "virbr0")
    mig_protocol = params.get("migration_protocol", "tcp")
    mig_cancel_delay = int(params.get("mig_cancel") == "yes") * 2
    pci_model = params.get("pci_model")

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

    error.context("Add network devices through monitor cmd", logging.info)
    nic_name = 'hotadded'
    enable_msix_vectors = params.get("enable_msix_vectors")
    nic_info = vm.hotplug_nic(nic_model=pci_model, nic_name=nic_name,
                              netdst=netdst, nettype=nettype,
                              queues=params.get('queues'),
                              enable_msix_vectors=enable_msix_vectors)
    nic_mac = nic_info['mac']
    vm.params['nics'] += " %s" % nic_name
    vm.params['nic_model_%s' % nic_name] = nic_info['nic_model']

    # Only run dhclient if explicitly set and guest is not running Windows.
    # Most modern Linux guests run NetworkManager, and thus do not need this.
    if run_dhclient == "yes" and guest_is_not_windows:
        session_serial = vm.wait_for_serial_login(timeout=timeout)
        ifname = utils_net.get_linux_ifname(session, nic_mac)
        utils_net.restart_guest_network(session_serial, ifname)
        # Guest need to take quite a long time to set the ip addr, sleep a
        # while to wait for guest done.
        time.sleep(60)

    error.context("Disable the primary link of guest", logging.info)
    set_link(nic_name, up=False)

    error.context("Check if new interface gets ip address", logging.info)
    try:
        ip = vm.wait_for_get_address(nic_name)
    except virt_vm.VMIPAddressMissingError:
        raise error.TestFail("Could not get or verify ip address of nic")
    logging.info("Got the ip address of new nic: %s", ip)

    error.context("Ping guest's new ip from host", logging.info)
    s, o = utils_test.ping(ip, 10, timeout=15)
    if s != 0:
        raise error.TestFail("New nic failed ping test with output:\n %s" % o)

    error.context("Re-enabling the primary link", logging.info)
    set_link(nic_name, up=True)

    error.context("Migrate from source VM to Destination VM", logging.info)
    vm.migrate(mig_timeout, mig_protocol, mig_cancel_delay, env=env)

    error.context("Disable the primary link", logging.info)
    set_link(nic_name, up=False)

    error.context("Ping guest's new ip from host", logging.info)
    s, o = utils_test.ping(ip, 10, timeout=15)
    if s != 0:
        raise error.TestFail("New nic failed ping test with output:\n %s" % o)

    error.context("Re-enabling the primary link", logging.info)
    set_link(nic_name, up=True)

    error.context("Reboot guest and verify new nic works", logging.info)
    host_ip = utils_net.get_ip_address_by_interface(netdst)
    session = vm.reboot(session=session)
    status, output = utils_test.ping(dest=host_ip, count=100,
                                     timeout=240, session=session)
    if status != 0:
        raise error.TestFail("Fail to ping host form guest")
示例#16
0
文件: kdump.py 项目: Zhanghm/tp-qemu
def kdump_enable(vm, vm_name, crash_kernel_prob_cmd, kernel_param_cmd,
                 kdump_enable_cmd, timeout):
    """
    Check, configure and enable the kdump in guest.

    :param vm_name: vm name
    :param crash_kernel_prob_cmd: check kdume loaded
    :param kernel_param_cmd: the param add into kernel line for kdump
    :param kdump_enable_cmd: enable kdump command
    :param timeout: Timeout in seconds
    """
    kdump_cfg_path = vm.params.get("kdump_cfg_path", "/etc/kdump.conf")
    kdump_config = vm.params.get("kdump_config")
    vmcore_path = vm.params.get("vmcore_path", "/var/crash")
    kdump_method = vm.params.get("kdump_method", "basic")
    kdump_propagate_cmd = vm.params.get("kdump_propagate_cmd")
    kdump_enable_timeout = int(vm.params.get("kdump_enable_timeout", 360))

    error.context("Try to log into guest '%s'." % vm_name, logging.info)
    session = vm.wait_for_login(timeout=timeout)

    error.context("Checking the existence of crash kernel in %s" % vm_name,
                  logging.info)
    try:
        session.cmd(crash_kernel_prob_cmd)
    except Exception:
        error.context("Crash kernel is not loaded. Trying to load it",
                      logging.info)
        session.cmd(kernel_param_cmd)
        session = vm.reboot(session, timeout=timeout)

    if kdump_config:
        if kdump_method == "ssh":
            host_ip = utils_net.get_ip_address_by_interface(
                vm.params.get('netdst'))
            kdump_config = kdump_config % (host_ip, vmcore_path)

        error.context("Configuring the Core Collector...", logging.info)

        session.cmd("cat /dev/null > %s" % kdump_cfg_path)
        for config_line in kdump_config.split(";"):
            config_cmd = "echo -e '%s' >> %s "
            config_con = config_line.strip()
            session.cmd(config_cmd % (config_con, kdump_cfg_path))

    if kdump_method == "ssh":
        host_pwd = vm.params.get("host_pwd", "redhat")
        guest_pwd = vm.params.get("guest_pwd", "redhat")
        guest_ip = vm.get_address()

        error.context("Setup ssh login without password...", logging.info)
        session.cmd("rm -rf /root/.ssh/*")

        ssh_connection = utils_conn.SSHConnection(server_ip=host_ip,
                                                  server_pwd=host_pwd,
                                                  client_ip=guest_ip,
                                                  client_pwd=guest_pwd)
        try:
            ssh_connection.conn_check()
        except utils_conn.ConnectionError:
            ssh_connection.conn_setup()
            ssh_connection.conn_check()

        logging.info("Trying to propagate with command '%s'" %
                     kdump_propagate_cmd)
        session.cmd(kdump_propagate_cmd, timeout=120)

    error.context("Enabling kdump service...", logging.info)
    # the initrd may be rebuilt here so we need to wait a little more
    session.cmd(kdump_enable_cmd, timeout=kdump_enable_timeout)

    return session
示例#17
0
def run(test, params, env):
    """
    Test bridge support from network

    1) create a linux bridge and connect a physical interface to it
    2) define nwfilter with "vdsm-no-mac-spoofing"
    3) redefine the vm with the new create bridge and filter
    4) check if guest can get public ip after vm start
    5) check if guest and host can ping each other
    6) check if guest and host can ping outside
    7) start another vm connected to the same bridge
    8) check if the 2 guests can ping each other
    """

    def create_bridge(br_name, iface_name):
        """
        Create a linux bridge by virsh cmd:
        1. Stop NetworkManager and Start network service
        2. virsh iface-bridge <iface> <name> [--no-stp]

        :param br_name: bridge name
        :param iface_name: physical interface name
        :return: bridge created or raise exception
        """
        # Make sure the bridge not exist
        if libvirt.check_iface(br_name, "exists", "--all"):
            test.cancel("The bridge %s already exist" % br_name)

        # Create bridge
        utils_package.package_install('tmux')
        cmd = 'tmux -c "ip link add name {0} type bridge; ip link set {1} up;' \
              ' ip link set {1} master {0}; ip link set {0} up;' \
              ' pkill dhclient; sleep 6; dhclient {0}; ifconfig {1} 0"'.format(br_name, iface_name)
        process.run(cmd, shell=True, verbose=True)

    def define_nwfilter(filter_name):
        """
        Define nwfilter vdsm-no-mac-spoofing with content like:
        <filter name='vdsm-no-mac-spoofing' chain='root'>
            <filterref filter='no-mac-spoofing'/>
            <filterref filter='no-arp-mac-spoofing'/>
        </filter>

        :param filter_name: the name of nwfilter
        :return: filter created or raise exception
        """
        filter_uuid = params.get("filter_uuid", "11111111-b071-6127-b4ec-111111111111")
        filter_params = {"filter_name": "vdsm-no-mac-spoofing",
                         "filter_chain": "root",
                         "filter_uuid": filter_uuid,
                         "filterref_name_1": "no-mac-spoofing",
                         "filterref_name_2": "no-arp-mac-spoofing"}
        filter_xml = libvirt.create_nwfilter_xml(filter_params).xml
        # Run command
        result = virsh.nwfilter_define(filter_xml, ignore_status=True, debug=True)
        if result.exit_status:
            test.fail("Failed to define nwfilter with %s" % filter_xml)

    def ping(src_ip, dest_ip, ping_count, timeout, session=None):
        """
        Wrap of ping

        :param src_ip: source address
        :param dest_ip: destination address
        :param ping_count: count of icmp packet
        :param timeout: timeout for the ping command
        :param session: local execution or session to execute the ping command
        :return: ping succeed or raise exception
        """
        status, output = utils_net.ping(dest=dest_ip, count=ping_count,
                                        interface=src_ip, timeout=timeout,
                                        session=session, force_ipv4=True)
        if status:
            test.fail("Fail to ping %s from %s" % (dest_ip, src_ip))

    def check_net_functions(guest_ip, ping_count, ping_timeout, guest_session, host_ip, remote_url, endpoint_ip):
        # make sure host network works well
        # host ping remote url
        ping(host_ip, remote_url, ping_count, ping_timeout)
        # host ping guest
        ping(host_ip, guest_ip, ping_count, ping_timeout)
        # guest ping host
        ping(guest_ip, host_ip, ping_count, ping_timeout, session=guest_session)
        # guest ping remote url
        ping(guest_ip, remote_url, ping_count, ping_timeout, session=guest_session)
        # guest ping endpoint
        ping(guest_ip, endpoint_ip, ping_count, ping_timeout, session=guest_session)

    # Get test params
    bridge_name = params.get("bridge_name", "test_br0")
    filter_name = params.get("filter_name", "vdsm-no-mac-spoofing")
    ping_count = params.get("ping_count", "5")
    ping_timeout = float(params.get("ping_timeout", "10"))
    iface_name = utils_net.get_net_if(state="UP")[0]
    bridge_script = NETWORK_SCRIPT + bridge_name
    iface_script = NETWORK_SCRIPT + iface_name
    iface_script_bk = os.path.join(data_dir.get_tmp_dir(), "iface-%s.bk" % iface_name)
    attach_interface = "yes" == params.get("attach_interface", "no")
    iface_model = params.get("iface_model", "virtio")
    iface_source = eval(params.get("iface_source", "{'bridge':'test_br0'}"))
    iface_type = params.get("iface_type", None)
    iface_target = params.get("iface_target", None)
    iface_alias = params.get("iface_alias", None)
    hotplug = "yes" == params.get("hotplug", "no")

    vms = params.get("vms").split()
    if len(vms) <= 1:
        test.cancel("Need two VMs to test")
    else:
        vm1_name = vms[0]
        vm2_name = vms[1]

    vm1 = env.get_vm(vm1_name)
    vm2 = env.get_vm(vm2_name)

    # Back up the interface script
    process.run("cp %s %s" % (iface_script, iface_script_bk),
                shell=True, verbose=True)
    # Back up vm xml
    vm1_xml_bak = vm_xml.VMXML.new_from_dumpxml(vm1_name)
    vm2_xml_bak = vm_xml.VMXML.new_from_dumpxml(vm2_name)

    # Stop NetworkManager service
    NM_service = service.Factory.create_service("NetworkManager")
    NM_status = NM_service.status()
    if not NM_status:
        NM_service.start()
    mac = utils_net.generate_mac_address_simple()

    try:
        create_bridge(bridge_name, iface_name)
        define_nwfilter(filter_name)
        if hotplug:
            err_msgs = ("No more available PCI slots",
                        "No more available PCI addresses")
            # delete the original interface on the vm before hot-plug
            if vm1.is_alive():
                vm1.destroy()
            vmxml = vm_xml.VMXML.new_from_dumpxml(vm1_name)
            iface_xml = vmxml.get_devices('interface')[0]
            logging.debug("Delete the original interface")
            vmxml.del_device(iface_xml)
            vmxml.sync()
            vm1.start()
            # do hot-plug
            if attach_interface:
                logging.info("Try to hot-plug interface")
                options = ("%s %s --model %s --mac %s" %
                           (iface_type, iface_source['bridge'],
                            iface_model, mac))
                ret = virsh.attach_interface(vm1_name, options,
                                             ignore_status=True)
            else:
                logging.info("Try to hot-plug device")
                target = str({'dev': iface_target})
                iface_alias = str({'name': iface_alias})
                vm_iface_source = str(iface_source)
                iface_params = {"type": "bridge", "source": vm_iface_source, "filter": filter_name, "mac": mac,
                                'alias': iface_alias, 'target': target, 'model': iface_model}
                attach_xml = interface.Interface(iface_params['type'])
                attach_xml.xml = libvirt.modify_vm_iface(vm1_name, 'get_xml', iface_params)
                ret = virsh.attach_device(vm1_name, attach_xml.xml,
                                          ignore_status=True,
                                          debug=True)
            if ret.exit_status:
                if any([msg in ret.stderr for msg in err_msgs]):
                    test.error("No more pci slots, can't attach more devices")
                else:
                    test.fail("Failed to attach-interface: %s" % ret.stderr.strip())
            else:
                logging.debug("Hot-plug interface or device pass")

        else:
            vm_iface_source = str(iface_source)
            vm1_iface_params = {"type": "bridge", "source": vm_iface_source, "filter": filter_name, "mac": mac}
            libvirt.modify_vm_iface(vm1_name, "update_iface", vm1_iface_params)

            if vm1.is_alive():
                vm1.destroy()

            vm1.start()
        # apply ip address as it may not be initialized
        session1 = session2 = None
        session1 = vm1.wait_for_serial_login()
        utils_net.restart_guest_network(session1)
        output = session1.cmd_output("ifconfig || ip a")
        logging.debug("guest1 ip info %s" % output)

        # Check guest's network function
        host_ip = utils_net.get_ip_address_by_interface(bridge_name)
        remote_url = params.get("remote_ip", "www.google.com")

        try:
            vm1_ip = utils_net.get_guest_ip_addr(session1, mac)
        except Exception as errs:
            test.fail("vm1 can't get IP with the new create bridge: %s" % errs)
        if hotplug:
            # reboot vm1 then check network function to ensure the interface still there and works fine
            logging.info("reboot the vm")
            virsh.reboot(vm1)
            if session1 is None:
                session1 = vm1.wait_for_serial_login()
            ping(vm1_ip, remote_url, ping_count, ping_timeout, session=session1)
            # restart libvirtd service then check the interface still works fine
            libvirtd = utils_libvirtd.Libvirtd()
            libvirtd.restart()
            vm1.cleanup_serial_console()
            vm1.create_serial_console()
            session1 = vm1.wait_for_serial_login()
            ping(vm1_ip, remote_url, ping_count, ping_timeout, session=session1)
            logging.info("after reboot and restart libvirtd, the network works fine")
            # hot-unplug interface/device
            if attach_interface:
                ret = virsh.detach_interface(vm1_name, "bridge",
                                             ignore_status=True)
            else:
                ret = virsh.detach_device(vm1_name, attach_xml.xml,
                                          ignore_status=True,
                                          debug=True)
            if ret.exit_status:
                test.fail("Hot-unplug interface/device fail")
            else:
                logging.info("hot-unplug interface/device succeed")

        else:
            # Start vm2 connect to the same bridge
            mac2 = utils_net.generate_mac_address_simple()
            vm2_iface_params = {"type": "bridge", "source": vm_iface_source, "filter": filter_name, "mac": mac2}
            libvirt.modify_vm_iface(vm2_name, "update_iface", vm2_iface_params)
            if vm2.is_alive():
                vm2.destroy()
            vm2.start()

            # Check if vm1 and vm2 can ping each other
            try:
                utils_net.update_mac_ip_address(vm2, timeout=120)
                vm2_ip = vm2.get_address()
            except Exception as errs:
                test.fail("vm2 can't get IP with the new create bridge: %s" % errs)
            session2 = vm2.wait_for_login()
            # make sure guest has got ip address
            utils_net.restart_guest_network(session2)
            output2 = session2.cmd_output("ifconfig || ip a")
            logging.debug("guest ip info %s" % output2)
            # check 2 guests' network functions
            check_net_functions(vm1_ip, ping_count, ping_timeout, session1,
                                host_ip, remote_url, vm2_ip)
            check_net_functions(vm2_ip, ping_count, ping_timeout, session2,
                                host_ip, remote_url, vm1_ip)

    finally:
        logging.debug("Start to restore")
        vm1_xml_bak.sync()
        vm2_xml_bak.sync()
        virsh.nwfilter_undefine(filter_name, ignore_status=True)
        if libvirt.check_iface(bridge_name, "exists", "--all"):
            virsh.iface_unbridge(bridge_name, timeout=60, debug=True)
        if os.path.exists(iface_script_bk):
            process.run("mv %s %s" % (iface_script_bk, iface_script),
                        shell=True, verbose=True)
        if os.path.exists(bridge_script):
            process.run("rm -rf %s" % bridge_script, shell=True, verbose=True)
        cmd = 'tmux -c "ip link set {1} nomaster;  ip link delete {0};' \
              'pkill dhclient; sleep 6; dhclient {1}"'.format(bridge_name, iface_name)
        process.run(cmd, shell=True, verbose=True)
        # reload network configuration
        NM_service.restart()
        # recover NetworkManager
        if NM_status is True:
            NM_service.start()
示例#18
0
def run(test, params, env):
    """
    Test start domain with nwfilter rules.

    1) Prepare parameters.
    2) Prepare nwfilter rule and update domain interface to apply.
    3) Start domain and check rule.
    4) Clean env
    """
    # Prepare parameters
    filter_name = params.get("filter_name", "testcase")
    exist_filter = params.get("exist_filter", "no-mac-spoofing")
    status_error = "yes" == params.get("status_error", "no")
    mount_noexec_tmp = "yes" == params.get("mount_noexec_tmp", "no")
    kill_libvirtd = "yes" == params.get("kill_libvirtd", "no")
    bug_url = params.get("bug_url", "")
    ipset_command = params.get("ipset_command")
    vm_name = params.get("main_vm")
    vm = env.get_vm(vm_name)
    username = params.get("username")
    password = params.get("password")
    need_vm2 = "yes" == params.get("need_vm2", "no")
    add_vm_name = params.get("add_vm_name", "vm2")
    vms = [vm]
    dst_outside = params.get("dst_outside", "www.google.com")
    ping_timeout = int(params.get("ping_timeout", "10"))

    # Prepare vm filterref parameters dict list
    filter_param_list = []
    params_key = []
    for i in params.keys():
        if 'parameter_name_' in i:
            params_key.append(i)
    params_key.sort()
    for i in range(len(params_key)):
        params_dict = {}
        params_dict['name'] = params[params_key[i]]
        params_dict['value'] = params['parameter_value_%s' % i]
        if params_dict['value'] == "MAC_of_virbr0":
            virbr0_info = process.run("ip a | grep virbr0: -A1",
                                      shell=True).stdout_text.strip()
            virbr0_mac = re.search(
                r'link/ether\s+(\w{2}:\w{2}:\w{2}:\w{2}:\w{2}:\w{2})',
                virbr0_info, re.M | re.I).group(1)
            params_dict['value'] = virbr0_mac
            logging.debug("params_dict['value'] is %s " % params_dict['value'])
        filter_param_list.append(params_dict)
    filterref_dict = {}
    filterref_dict['name'] = filter_name
    filterref_dict['parameters'] = filter_param_list
    params['filter_uuid'] = process.run("uuidgen",
                                        ignore_status=True,
                                        shell=True).stdout_text.strip()

    # get all the check commands and corresponding expected results form config file and make a dictionary
    cmd_list_ = params.get('check_cmd', '')
    if cmd_list_:
        cmd_list = cmd_list_.split(',')
        expect_res = params.get('expect_match', '').split(',')
        logging.debug("cmd_list is %s" % cmd_list)
        logging.debug("expect_res is %s" % expect_res)
        cmd_result_dict = dict(zip(cmd_list, expect_res))
        logging.debug("the check dict is %s" % cmd_result_dict)
    # backup vm xml
    vmxml_backup = libvirt_xml.VMXML.new_from_inactive_dumpxml(vm_name)

    libvirtd = utils_libvirtd.Libvirtd("virtqemud")
    device_name = None

    def check_nwfilter_rules(check_cmd, expect_match):
        """"check the nwfilter corresponding rule is added by iptables commands"""
        ret = utils_misc.wait_for(lambda: not process.system(
            check_cmd, ignore_status=True, shell=True),
                                  timeout=30)
        if not ret:
            test.fail("Rum command '%s' failed" % check_cmd)
        # This change anchors nwfilter_vm_start.possitive_test.new_filter.variable_notation case
        # The matched destination could be ip address or hostname
        if "iptables -L" in check_cmd and expect_match and 'ACCEPT' in expect_match:
            # ip address that need to be replaced
            replace_param = params.get("parameter_value_2")
            # Get hostname by ip address.
            hostname_info = None
            try:
                hostname_info = socket.gethostbyaddr(replace_param)
            except socket.error as e:
                logging.info(
                    "Failed to get hostname from ip address with error: %s",
                    str(e))
            if hostname_info:
                # String is used to replace ip address
                replace_with = "%s|%s" % (replace_param, hostname_info[0])
                expect_match = r"%s" % expect_match.replace(
                    replace_param, replace_with)
                logging.debug("final iptables match string:%s", expect_match)
        out = astring.to_text(
            process.system_output(check_cmd, ignore_status=False, shell=True))
        if expect_match and not re.search(expect_match, out):
            test.fail("'%s' not found in output: %s" % (expect_match, out))

    def clean_up_dirty_nwfilter_binding():
        cmd_result = virsh.nwfilter_binding_list(debug=True)
        binding_list = cmd_result.stdout_text.strip().splitlines()
        binding_list = binding_list[2:]
        result = []
        # If binding list is not empty.
        if binding_list:
            for line in binding_list:
                # Split on whitespace, assume 1 column
                linesplit = line.split(None, 1)
                result.append(linesplit[0])
        logging.info("nwfilter binding list is: %s", result)
        for binding_uuid in result:
            try:
                virsh.nwfilter_binding_delete(binding_uuid)
            except Exception as e:
                logging.error(
                    "Exception thrown while undefining nwfilter-binding: %s",
                    str(e))
                raise

    try:
        # Clean up dirty nwfilter binding if there are.
        clean_up_dirty_nwfilter_binding()
        rule = params.get("rule")
        if rule:
            # Create new filter xml
            filterxml = utlv.create_nwfilter_xml(params)
            # Define filter xml
            virsh.nwfilter_define(filterxml.xml, debug=True)

        # Update first vm interface with filter
        vmxml = libvirt_xml.VMXML.new_from_inactive_dumpxml(vm_name)
        iface_xml = vmxml.get_devices('interface')[0]
        vmxml.del_device(iface_xml)
        new_iface = interface.Interface('network')
        new_iface.xml = iface_xml.xml
        new_filterref = new_iface.new_filterref(**filterref_dict)
        new_iface.filterref = new_filterref
        logging.debug("new interface xml is: %s" % new_iface)
        vmxml.add_device(new_iface)
        vmxml.sync()

        if mount_noexec_tmp:
            device_name = utlv.setup_or_cleanup_iscsi(is_setup=True)
            utlv.mkfs(device_name, 'ext4')
            cmd = "mount %s /tmp -o noexec,nosuid" % device_name
            process.run(cmd, shell=True)

        if ipset_command:
            pkg = "ipset"
            if not utils_package.package_install(pkg):
                test.cancel("Can't install ipset on host")
            process.run(ipset_command, shell=True)

        # Run command
        try:
            vm.start()
            if not mount_noexec_tmp:
                vm.wait_for_serial_login(username=username, password=password)
            vmxml = libvirt_xml.VMXML.new_from_dumpxml(vm_name)
            iface_xml = vmxml.get_devices('interface')[0]
            iface_target = iface_xml.target['dev']
            iface_mac = iface_xml.mac_address
            logging.debug("iface target dev name is %s", iface_target)

            # Check iptables or ebtables on host
            if need_vm2:
                # Clone more vm for testing
                result = virsh.dom_list('--inactive').stdout_text
                if add_vm_name in result:
                    logging.debug("%s is already exists!" % add_vm_name)
                    vms.append(env.get_vm(add_vm_name))
                else:
                    vm.destroy()
                    ret_clone = utils_libguestfs.virt_clone_cmd(vm_name,
                                                                add_vm_name,
                                                                True,
                                                                timeout=360)
                    if ret_clone.exit_status:
                        test.fail("Error when clone a second vm!")
                    vms.append(vm.clone(add_vm_name))
                    vm.start()
                vm2 = vms[1]
                logging.debug("Now the vms is: %s", [dom.name for dom in vms])
                # update the vm2 interface with the nwfilter
                logging.debug("filter_params_list is %s" % filter_param_list)
                iface_dict = {
                    "filter": filter_name,
                    "filter_parameters": filter_param_list,
                    "del_mac": True
                }
                if vm2.is_alive():
                    vm2.destroy()
                utlv.modify_vm_iface(vm2.name, "update_iface", iface_dict)
                vmxml = libvirt_xml.VMXML.new_from_inactive_dumpxml(vm2.name)
                iface_xml = vmxml.get_devices('interface')[0]
                logging.debug("iface_xml for vm2 is %s" % iface_xml)
                vm2.start()
                vm2_session = vm2.wait_for_serial_login()
                vm2_mac = vm2.get_mac_address()
                vm2_ip = utils_net.get_guest_ip_addr(vm2_session, vm2_mac)
                vm.session = vm.wait_for_serial_login()
                # test network functions, the 2 vms can not access to each other
                gateway_ip = utils_net.get_ip_address_by_interface("virbr0")
                status1, output1 = utils_net.ping(dest=vm2_ip,
                                                  count='3',
                                                  timeout=ping_timeout,
                                                  session=vm.session,
                                                  force_ipv4=True)
                status2, output2 = utils_net.ping(dest=gateway_ip,
                                                  count='3',
                                                  timeout=ping_timeout,
                                                  session=vm.session,
                                                  force_ipv4=True)
                status3, output3 = utils_net.ping(dest=dst_outside,
                                                  count='3',
                                                  timeout=ping_timeout,
                                                  session=vm.session,
                                                  force_ipv4=True)
                if not status1:
                    test.fail(
                        "vm with clean-traffic-gateway ping succeed to %s %s, but it is not expected!"
                        % (vm2.name, vm2_ip))
                if status2 or status3:
                    test.fail("vm ping failed! check %s \n %s" %
                              (output2, output3))
            if cmd_list_:
                loop = 0
                for check_cmd_, expect_match_ in cmd_result_dict.items():
                    check_cmd = check_cmd_.strip()
                    expect_match = expect_match_.strip()
                    if "DEVNAME" in check_cmd:
                        check_cmd = check_cmd.replace("DEVNAME", iface_target)
                    if "VMMAC" in expect_match:
                        expect_match = expect_match.replace("VMMAC", iface_mac)
                    logging.debug(
                        "the check_cmd is %s, and expected result is %s" %
                        (check_cmd, expect_match))
                    check_nwfilter_rules(check_cmd, expect_match)
                    loop += 1
        except virt_vm.VMStartError as e:
            # Starting VM failed.
            if not status_error:
                test.fail("Test failed in positive case.\n error:"
                          " %s\n%s" % (e, bug_url))

        if kill_libvirtd:
            daemon_name = libvirtd.service_name
            pid = process.run('pidof %s' % daemon_name,
                              shell=True).stdout_text.strip()
            cmd = "kill -s TERM %s" % pid
            process.run(cmd, shell=True)
            ret = utils_misc.wait_for(lambda: not libvirtd.is_running(),
                                      timeout=30)
            # After libvirt 5.6.0, libvirtd is using systemd socket activation by default
            if not ret and not libvirt_version.version_compare(5, 6, 0):
                test.fail("Failed to kill libvirtd. %s" % bug_url)

    finally:
        if kill_libvirtd:
            libvirtd.restart()
        # Clean env
        if vm.is_alive():
            vm.destroy(gracefully=False)
        # Recover xml of vm.
        vmxml_backup.sync()
        # Undefine created filter except clean-traffic as it is built-in nwfilter
        if filter_name != exist_filter and filter_name != 'clean-traffic':
            virsh.nwfilter_undefine(filter_name, debug=True)
        if mount_noexec_tmp:
            if device_name:
                process.run("umount -l %s" % device_name,
                            ignore_status=True,
                            shell=True)
            utlv.setup_or_cleanup_iscsi(is_setup=False)
        if ipset_command:
            process.run("ipset destroy blacklist", shell=True)
        # Remove additional vms
        if need_vm2:
            result = virsh.dom_list("--all").stdout_text
            if add_vm_name in result:
                virsh.remove_domain(add_vm_name, "--remove-all-storage")
示例#19
0
def run(test, params, env):
    """
    KVM multi test:
    1) Log into guests
    2) Check all the nics available or not
    3) Ping among guest nic and host
       3.1) Ping with different packet size
       3.2) Flood ping test
       3.3) Final ping test
    4) Transfer files among guest nics and host
       4.1) Create file by dd command in guest
       4.2) Transfer file between nics
       4.3) Compare original file and transferred file
    5) ping among different nics
       5.1) Ping with different packet size
       5.2) Flood ping test
       5.3) Final ping test
    6) Transfer files among different nics
       6.1) Create file by dd command in guest
       6.2) Transfer file between nics
       6.3) Compare original file and transferred file
    7) Repeat step 3 - 6 on every nic.

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

    def ping(session, nic, dst_ip, strick_check, flood_minutes):
        d_packet_size = [1, 4, 48, 512, 1440, 1500, 1505, 4054, 4055, 4096,
                         4192, 8878, 9000, 32767, 65507]
        packet_size = params.get("packet_size", "").split() or d_packet_size
        for size in packet_size:
            error.context("Ping with packet size %s" % size, logging.info)
            status, output = utils_test.ping(dst_ip, 10, interface=nic,
                                             packetsize=size, timeout=30,
                                             session=session)
            if strict_check:
                ratio = utils_test.get_loss_ratio(output)
                if ratio != 0:
                    raise error.TestFail("Loss ratio is %s for packet size"
                                         " %s" % (ratio, size))
            else:
                if status != 0:
                    raise error.TestFail("Ping returns non-zero value %s" %
                                         output)

        error.context("Flood ping test", logging.info)
        utils_test.ping(dst_ip, None, interface=nic, flood=True,
                        output_func=None, timeout=flood_minutes * 60,
                        session=session)
        error.context("Final ping test", logging.info)
        counts = params.get("ping_counts", 100)
        status, output = utils_test.ping(dst_ip, counts, interface=nic,
                                         timeout=float(counts) * 1.5,
                                         session=session)
        if strick_check == "yes":
            ratio = utils_test.get_loss_ratio(output)
            if ratio != 0:
                raise error.TestFail("Packet loss ratio is %s after flood"
                                     % ratio)
        else:
            if status != 0:
                raise error.TestFail("Ping returns non-zero value %s" %
                                     output)

    def file_transfer(session, src, dst):
        username = params.get("username", "")
        password = params.get("password", "")
        src_path = "/tmp/1"
        dst_path = "/tmp/2"
        port = int(params["file_transfer_port"])

        cmd = "dd if=/dev/urandom of=%s bs=100M count=1" % src_path
        cmd = params.get("file_create_cmd", cmd)

        error.context("Create file by dd command, cmd: %s" % cmd, logging.info)
        session.cmd(cmd)

        transfer_timeout = int(params.get("transfer_timeout"))
        log_filename = "scp-from-%s-to-%s.log" % (src, dst)
        error.context("Transfer file from %s to %s" % (src, dst), logging.info)
        remote.scp_between_remotes(src, dst, port, password, password,
                                   username, username, src_path, dst_path,
                                   log_filename=log_filename,
                                   timeout=transfer_timeout)
        src_path = dst_path
        dst_path = "/tmp/3"
        log_filename = "scp-from-%s-to-%s.log" % (dst, src)
        error.context("Transfer file from %s to %s" % (dst, src), logging.info)
        remote.scp_between_remotes(dst, src, port, password, password,
                                   username, username, src_path, dst_path,
                                   log_filename=log_filename,
                                   timeout=transfer_timeout)
        error.context("Compare original file and transferred file",
                      logging.info)

        cmd1 = "md5sum /tmp/1"
        cmd2 = "md5sum /tmp/3"
        md5sum1 = session.cmd(cmd1).split()[0]
        md5sum2 = session.cmd(cmd2).split()[0]
        if md5sum1 != md5sum2:
            raise error.TestError("File changed after transfer")

    nic_interface_list = []
    check_irqbalance_cmd = params.get("check_irqbalance_cmd")
    stop_irqbalance_cmd = params.get("stop_irqbalance_cmd")
    start_irqbalance_cmd = params.get("start_irqbalance_cmd")
    status_irqbalance = params.get("status_irqbalance")
    vms = params["vms"].split()
    host_mem = utils_memory.memtotal() / (1024 * 1024)
    host_cpu_count = len(utils_misc.get_cpu_processors())
    vhost_count = 0
    if params.get("vhost"):
        vhost_count = 1
    if host_cpu_count < (1 + vhost_count) * len(vms):
        raise error.TestError("The host don't have enough cpus to start guest"
                              "pcus: %d, minimum of vcpus and vhost: %d" %
                              (host_cpu_count, (1 + vhost_count) * len(vms)))
    params['mem'] = host_mem / len(vms) * 1024
    params['smp'] = host_cpu_count / len(vms) - vhost_count
    if params['smp'] % 2 != 0:
        params['vcpu_sockets'] = 1
    params["start_vm"] = "yes"
    for vm_name in vms:
        env_process.preprocess_vm(test, params, env, vm_name)
    timeout = float(params.get("login_timeout", 360))
    strict_check = params.get("strick_check", "no")
    host_ip = utils_net.get_ip_address_by_interface(params.get("netdst"))
    host_ip = params.get("srchost", host_ip)
    flood_minutes = float(params["flood_minutes"])
    error.context("Check irqbalance service status", logging.info)
    o = process.system_output(check_irqbalance_cmd, ignore_status=True)
    check_stop_irqbalance = False
    if re.findall(status_irqbalance, o):
        logging.debug("stop irqbalance")
        process.run(stop_irqbalance_cmd)
        check_stop_irqbalance = True
        o = process.system_output(check_irqbalance_cmd, ignore_status=True)
        if re.findall(status_irqbalance, o):
            raise error.TestError("Can not stop irqbalance")
    thread_list = []
    nic_interface = []
    for vm_name in vms:
        guest_ifname = ""
        guest_ip = ""
        vm = env.get_vm(vm_name)
        session = vm.wait_for_login(timeout=timeout)
        thread_list.extend(vm.vcpu_threads)
        thread_list.extend(vm.vhost_threads)
        error.context("Check all the nics available or not", logging.info)
        for index, nic in enumerate(vm.virtnet):
            guest_ifname = utils_net.get_linux_ifname(session, nic.mac)
            guest_ip = vm.get_address(index)
            if not (guest_ifname and guest_ip):
                err_log = "vms %s get ip or ifname failed." % vm_name
                err_log = "ifname: %s, ip: %s." % (guest_ifname, guest_ip)
                raise error.TestFail(err_log)
            nic_interface = [guest_ifname, guest_ip, session]
            nic_interface_list.append(nic_interface)
    error.context("Pin vcpus and vhosts to host cpus", logging.info)
    host_numa_nodes = utils_misc.NumaInfo()
    vthread_num = 0
    for numa_node_id in host_numa_nodes.nodes:
        numa_node = host_numa_nodes.nodes[numa_node_id]
        for _ in range(len(numa_node.cpus)):
            if vthread_num >= len(thread_list):
                break
            vcpu_tid = thread_list[vthread_num]
            logging.debug("pin vcpu/vhost thread(%s) to cpu(%s)" %
                          (vcpu_tid, numa_node.pin_cpu(vcpu_tid)))
            vthread_num += 1

    nic_interface_list_len = len(nic_interface_list)
    # ping and file transfer test
    for src_ip_index in range(nic_interface_list_len):
        error.context("Ping test from guest to host", logging.info)
        src_ip_info = nic_interface_list[src_ip_index]
        ping(src_ip_info[2], src_ip_info[0], host_ip, strict_check,
             flood_minutes)
        error.context("File transfer test between guest and host",
                      logging.info)
        file_transfer(src_ip_info[2], src_ip_info[1], host_ip)
        for dst_ip in nic_interface_list[src_ip_index:]:
            if src_ip_info[1] == dst_ip[1]:
                continue
            txt = "Ping test between %s and %s" % (src_ip_info[1], dst_ip[1])
            error.context(txt, logging.info)
            ping(src_ip_info[2], src_ip_info[0], dst_ip[1], strict_check,
                 flood_minutes)
            txt = "File transfer test between %s " % src_ip_info[1]
            txt += "and %s" % dst_ip[1]
            error.context(txt, logging.info)
            file_transfer(src_ip_info[2], src_ip_info[1], dst_ip[1])
    if check_stop_irqbalance:
        process.run(start_irqbalance_cmd)
示例#20
0
def run(test, params, env):
    """
    Test bridge support from network

    1) create a linux bridge and connect a physical interface to it
    2) define nwfilter with "vdsm-no-mac-spoofing"
    3) redefine the vm with the new create bridge and filter
    4) check if guest can get public ip after vm start
    5) check if guest and host can ping each other
    6) check if guest and host can ping outside
    7) start another vm connected to the same bridge
    8) check if the 2 guests can ping each other
    """
    def create_bridge_network(br_name, net_name):
        """
        Define and start the bridge type network
        """
        # check if network with the same name already exists
        output_all = virsh.net_list("--all").stdout.strip()
        if re.search(net_name, output_all):
            test.cancel("Network with the same name already exists!")
        test_xml = network_xml.NetworkXML(network_name="%s" % net_name)
        test_xml.forward = {"mode": "bridge"}
        test_xml.bridge = {"name": br_name}
        test_xml.create()

    def define_nwfilter(filter_name):
        """
        Define nwfilter vdsm-no-mac-spoofing with content like:
        <filter name='vdsm-no-mac-spoofing' chain='root'>
            <filterref filter='no-mac-spoofing'/>
            <filterref filter='no-arp-mac-spoofing'/>
        </filter>

        :param filter_name: the name of nwfilter
        :return: filter created or raise exception
        """
        filter_uuid = params.get("filter_uuid",
                                 "11111111-b071-6127-b4ec-111111111111")
        filter_params = {
            "filter_name": "vdsm-no-mac-spoofing",
            "filter_chain": "root",
            "filter_uuid": filter_uuid,
            "filterref_name_1": "no-mac-spoofing",
            "filterref_name_2": "no-arp-mac-spoofing"
        }
        filter_xml = libvirt.create_nwfilter_xml(filter_params).xml
        # Run command
        result = virsh.nwfilter_define(filter_xml,
                                       ignore_status=True,
                                       debug=True)
        if result.exit_status:
            test.fail("Failed to define nwfilter with %s" % filter_xml)

    def ping(src_ip, dest_ip, ping_count, timeout, session=None):
        """
        Wrap of ping

        :param src_ip: source address
        :param dest_ip: destination address
        :param ping_count: count of icmp packet
        :param timeout: timeout for the ping command
        :param session: local execution or session to execute the ping command
        :return: ping succeed or raise exception
        """
        status, output = utils_net.ping(dest=dest_ip,
                                        count=ping_count,
                                        interface=src_ip,
                                        timeout=timeout,
                                        session=session,
                                        force_ipv4=True)
        if status:
            test.fail("Fail to ping %s from %s" % (dest_ip, src_ip))

    def check_net_functions(guest_ip, ping_count, ping_timeout, guest_session,
                            host_ip, remote_url, endpoint_ip):
        # make sure host network works well
        # host ping remote url
        ping(host_ip, remote_url, ping_count, ping_timeout)
        # host ping guest
        ping(host_ip, guest_ip, ping_count, ping_timeout)
        # guest ping host
        ping(guest_ip,
             host_ip,
             ping_count,
             ping_timeout,
             session=guest_session)
        # guest ping remote url
        ping(guest_ip,
             remote_url,
             ping_count,
             ping_timeout,
             session=guest_session)
        # guest ping endpoint
        ping(guest_ip,
             endpoint_ip,
             ping_count,
             ping_timeout,
             session=guest_session)

    # Get test params
    bridge_name = params.get("bridge_name", "test_br0")
    filter_name = params.get("filter_name", "vdsm-no-mac-spoofing")
    ping_count = params.get("ping_count", "5")
    ping_timeout = float(params.get("ping_timeout", "10"))
    iface_name = utils_net.get_net_if(state="UP")[0]
    bridge_script = NETWORK_SCRIPT + bridge_name
    iface_script = NETWORK_SCRIPT + iface_name
    iface_script_bk = os.path.join(data_dir.get_tmp_dir(),
                                   "iface-%s.bk" % iface_name)
    attach_interface = "yes" == params.get("attach_interface", "no")
    iface_model = params.get("iface_model", "virtio")
    iface_source = eval(params.get("iface_source", "{'bridge':'test_br0'}"))
    iface_type = params.get("iface_type", None)
    iface_target = params.get("iface_target", "br_target")
    iface_alias = params.get("iface_alias", None)
    hotplug = "yes" == params.get("hotplug", "no")
    iface_driver = params.get("iface_driver", None)
    start_vm2 = "yes" == params.get("start_vm2", "no")
    create_network = "yes" == params.get("create_network", "no")
    update_device = "yes" == params.get("update_with_diff_type", "no")

    vms = params.get("vms").split()
    if len(vms) <= 1:
        test.cancel("Need two VMs to test")
    else:
        vm1_name = vms[0]
        vm2_name = vms[1]

    vm1 = env.get_vm(vm1_name)
    vm2 = env.get_vm(vm2_name)

    # Back up the interface script
    if os.path.exists(iface_script):
        process.run("cp %s %s" % (iface_script, iface_script_bk),
                    shell=True,
                    verbose=True)
    # Back up vm xml
    vm1_xml_bak = vm_xml.VMXML.new_from_dumpxml(vm1_name)
    vm2_xml_bak = vm_xml.VMXML.new_from_dumpxml(vm2_name)

    # Stop NetworkManager service
    NM_service = service.Factory.create_service("NetworkManager")
    NM_status = NM_service.status()
    if not NM_status:
        NM_service.start()
    mac = utils_net.generate_mac_address_simple()

    try:
        if libvirt.check_iface(bridge_name, "exists", "--all"):
            test.cancel("The bridge %s already exist" % bridge_name)
        s, o = utils_net.create_linux_bridge(bridge_name, iface_name)
        if s:
            test.fail(
                "Failed to create linux bridge on the host. Status: %s Stdout: %s"
                % (s, o))
        define_nwfilter(filter_name)
        if hotplug:
            err_msgs = ("No more available PCI slots",
                        "No more available PCI addresses")
            # delete the original interface on the vm before hot-plug
            if vm1.is_alive():
                vm1.destroy()
            vmxml = vm_xml.VMXML.new_from_dumpxml(vm1_name)
            iface_xml = vmxml.get_devices('interface')[0]
            logging.debug("Delete the original interface")
            vmxml.del_device(iface_xml)
            vmxml.sync()
            vm1.start()
            # do hot-plug
            if attach_interface:
                logging.info("Try to hot-plug interface")
                options = (
                    "%s %s --model %s --mac %s" %
                    (iface_type, iface_source['bridge'], iface_model, mac))
                ret = virsh.attach_interface(vm1_name,
                                             options,
                                             ignore_status=True)
            else:
                logging.info("Try to hot-plug device")
                if create_network:
                    create_bridge_network(bridge_name, iface_source["network"])
                target = str({'dev': iface_target})
                iface_alias = str({'name': iface_alias})
                vm_iface_source = str(iface_source)
                iface_params = {
                    "type": iface_type,
                    "source": vm_iface_source,
                    "filter": filter_name,
                    "mac": mac,
                    'alias': iface_alias,
                    'target': target,
                    'model': iface_model,
                    'driver': iface_driver
                }
                attach_xml = interface.Interface(iface_params['type'])
                attach_xml.xml = libvirt.modify_vm_iface(
                    vm1_name, 'get_xml', iface_params)
                ret = virsh.attach_device(vm1_name,
                                          attach_xml.xml,
                                          ignore_status=True,
                                          debug=True)
            if ret.exit_status:
                if any([msg in ret.stderr for msg in err_msgs]):
                    test.error("No more pci slots, can't attach more devices")
                else:
                    test.fail("Failed to attach-interface: %s" %
                              ret.stderr.strip())
            else:
                logging.debug("Hot-plug interface or device pass")
                if update_device:
                    # As the interface type will change to actual type "bridge" in live xml, we need to ensure
                    # the update with original "network" type will not fail.
                    # Try to delete the nwfilter with original type in iface_params
                    update_xml = interface.Interface(iface_type)
                    iface_params_update = {
                        "del_filter": "yes",
                        "type": "network",
                        "source": vm_iface_source
                    }
                    update_xml.xml = libvirt.modify_vm_iface(
                        vm1_name, 'get_xml', iface_params_update)
                    ret = virsh.update_device(vm1_name,
                                              update_xml.xml,
                                              ignore_status=True,
                                              debug=True)
                    libvirt.check_exit_status(ret)

        else:
            vm_iface_source = str(iface_source)
            vm1_iface_params = {
                "type": "bridge",
                "source": vm_iface_source,
                "filter": filter_name,
                "mac": mac,
                'driver': iface_driver,
                "iface_model": iface_model
            }
            libvirt.modify_vm_iface(vm1_name, "update_iface", vm1_iface_params)

            if vm1.is_alive():
                vm1.destroy()

            vm1.start()
        # apply ip address as it may not be initialized
        session1 = session2 = None
        session1 = vm1.wait_for_serial_login()
        utils_net.restart_guest_network(session1)
        output = session1.cmd_output("ifconfig || ip a")
        logging.debug("guest1 ip info %s" % output)

        # Check guest's network function
        host_ip = utils_net.get_ip_address_by_interface(bridge_name)
        remote_url = params.get("remote_ip", "www.google.com")

        try:
            vm1_ip = utils_net.get_guest_ip_addr(session1, mac)
        except Exception as errs:
            test.fail("vm1 can't get IP with the new create bridge: %s" % errs)
        if hotplug:
            # reboot vm1 then check network function to ensure the interface still there and works fine
            logging.info("reboot the vm")
            virsh.reboot(vm1)
            if session1 is None:
                session1 = vm1.wait_for_serial_login()
            ping(vm1_ip,
                 remote_url,
                 ping_count,
                 ping_timeout,
                 session=session1)
            # restart libvirtd service then check the interface still works fine
            libvirtd = utils_libvirtd.Libvirtd()
            libvirtd.restart()
            vm1.cleanup_serial_console()
            vm1.create_serial_console()
            session1 = vm1.wait_for_serial_login()
            ping(vm1_ip,
                 remote_url,
                 ping_count,
                 ping_timeout,
                 session=session1)
            logging.info(
                "after reboot and restart libvirtd, the network works fine")
            if iface_driver:
                try:
                    driver_dict = eval(iface_driver)
                    if session1 is None:
                        session1 = vm1.wait_for_serial_login()
                    guest_iface_info = session1.cmd_output("ip l").strip()
                    guest_iface_name = re.findall(
                        r"^\d+: (\S+?)[@:].*state UP.*$", guest_iface_info,
                        re.MULTILINE)[0]
                    comb_size = driver_dict.get('queues')
                    rx_size = driver_dict.get('rx_queue_size')
                    session1.cmd_status("ethtool -L %s combined %s" %
                                        (guest_iface_name, comb_size))
                    ret, outp = session1.cmd_status_output("ethtool -l %s" %
                                                           guest_iface_name)
                    logging.debug("ethtool cmd output:%s" % outp)
                    if not ret:
                        pre_comb = re.search(
                            "Pre-set maximums:[\s\S]*?Combined:.*?(\d+)",
                            outp).group(1)
                        cur_comb = re.search(
                            "Current hardware settings:[\s\S]*?Combined:.*?(\d+)",
                            outp).group(1)
                        if int(pre_comb) != int(comb_size) or int(
                                cur_comb) != int(comb_size):
                            test.fail(
                                "Fail to check the combined size: setting: %s,"
                                "Pre-set: %s, Current-set: %s" %
                                (comb_size, pre_comb, cur_comb))
                        else:
                            logging.info(
                                "Getting correct Pre-set and Current set value"
                            )
                    else:
                        test.error("ethtool list fail: %s" % outp)
                    # as tx_queue size is only supported for vhost-user interface, only check rx_queue size
                    ret1, outp1 = session1.cmd_status_output("ethtool -g %s" %
                                                             guest_iface_name)
                    logging.debug("guest queue size setting is %s" % outp1)
                    if not ret1:
                        pre_set = re.search(r"Pre-set maximums:\s*RX:\s*(\d+)",
                                            outp1).group(1)
                        cur_set = re.search(
                            r"Current hardware settings:\s*RX:\s*(\d+)",
                            outp1).group(1)
                        if int(pre_set) != int(rx_size) or int(cur_set) != int(
                                rx_size):
                            test.fail("Fail to check the rx_queue_size!")
                except Exception as errs:
                    test.fail("fail to get driver info")
            # hot-unplug interface/device
            if attach_interface:
                ret = virsh.detach_interface(vm1_name,
                                             "bridge",
                                             ignore_status=True)
            else:
                ret = virsh.detach_device(vm1_name,
                                          attach_xml.xml,
                                          ignore_status=True,
                                          debug=True)
            if ret.exit_status:
                test.fail("Hot-unplug interface/device fail")
            else:
                logging.info("hot-unplug interface/device succeed")

        else:
            if start_vm2:
                # Start vm2 connect to the same bridge
                mac2 = utils_net.generate_mac_address_simple()
                vm2_iface_params = {
                    "type": "bridge",
                    "source": vm_iface_source,
                    "filter": filter_name,
                    "mac": mac2
                }
                libvirt.modify_vm_iface(vm2_name, "update_iface",
                                        vm2_iface_params)
                if vm2.is_alive():
                    vm2.destroy()
                vm2.start()

                # Check if vm1 and vm2 can ping each other
                try:
                    utils_net.update_mac_ip_address(vm2, timeout=120)
                    vm2_ip = vm2.get_address()
                except Exception as errs:
                    test.fail(
                        "vm2 can't get IP with the new create bridge: %s" %
                        errs)
                session2 = vm2.wait_for_login()
                # make sure guest has got ip address
                utils_net.restart_guest_network(session2)
                output2 = session2.cmd_output("ifconfig || ip a")
                logging.debug("guest ip info %s" % output2)
                # check 2 guests' network functions
                check_net_functions(vm1_ip, ping_count, ping_timeout, session1,
                                    host_ip, remote_url, vm2_ip)
                check_net_functions(vm2_ip, ping_count, ping_timeout, session2,
                                    host_ip, remote_url, vm1_ip)

    finally:
        logging.debug("Start to restore")
        vm1_xml_bak.sync()
        vm2_xml_bak.sync()
        virsh.nwfilter_undefine(filter_name, ignore_status=True)
        if os.path.exists(iface_script_bk):
            process.run("mv %s %s" % (iface_script_bk, iface_script),
                        shell=True,
                        verbose=True)
        if os.path.exists(bridge_script):
            process.run("rm -rf %s" % bridge_script, shell=True, verbose=True)
        br_path = "/sys/class/net/%s" % bridge_name
        if os.path.exists(br_path):
            utils_net.delete_linux_bridge(bridge_name, iface_name)
        # reload network configuration
        NM_service.restart()
        # recover NetworkManager
        if NM_status is True:
            NM_service.start()
        if 'network' in iface_source and iface_source[
                "network"] in virsh.net_state_dict():
            virsh.net_destroy(iface_source["network"], ignore_status=False)
示例#21
0
def run(test, params, env):
    """
    Test bridge support from network

    1) create a linux bridge and connect a physical interface to it
    2) define nwfilter with "vdsm-no-mac-spoofing"
    3) redefine the vm with the new create bridge and filter
    4) check if guest can get public ip after vm start
    5) check if guest and host can ping each other
    6) check if guest and host can ping outside
    7) start another vm connected to the same bridge
    8) check if the 2 guests can ping each other
    """

    def create_bridge(br_name, iface_name):
        """
        Create a linux bridge by virsh cmd:
        1. Stop NetworkManager and Start network service
        2. virsh iface-bridge <iface> <name> [--no-stp]

        :param br_name: bridge name
        :param iface_name: physical interface name
        :return: bridge created or raise exception
        """
        # Make sure the bridge not exist
        if libvirt.check_iface(br_name, "exists", "--all"):
            test.cancel("The bridge %s already exist" % br_name)

        # Create bridge
        # This cmd run a long time, so set timeout=240
        result = virsh.iface_bridge(iface_name, br_name, "--no-stp", debug=True, timeout=240)
        if result.exit_status:
            test.fail("Failed to create bridge:\n%s" % result.stderr)

    def define_nwfilter(filter_name):
        """
        Define nwfilter vdsm-no-mac-spoofing with content like:
        <filter name='vdsm-no-mac-spoofing' chain='root'>
            <filterref filter='no-mac-spoofing'/>
            <filterref filter='no-arp-mac-spoofing'/>
        </filter>

        :param filter_name: the name of nwfilter
        :return: filter created or raise exception
        """
        filter_uuid = params.get("filter_uuid", "11111111-b071-6127-b4ec-111111111111")
        filter_params = {"filter_name": "vdsm-no-mac-spoofing",
                         "filter_chain": "root",
                         "filter_uuid": filter_uuid,
                         "filterref_name_1": "no-mac-spoofing",
                         "filterref_name_2": "no-arp-mac-spoofing"}
        filter_xml = libvirt.create_nwfilter_xml(filter_params).xml
        # Run command
        result = virsh.nwfilter_define(filter_xml, ignore_status=True, debug=True)
        if result.exit_status:
            test.fail("Failed to define nwfilter with %s" % filter_xml)

    def modify_iface_xml(br_name, nwfilter, vm_name):
        """
        Modify interface xml with the new bridge and the nwfilter

        :param br_name: bridge name
        :param nwfilter: nwfilter name
        :param vm_name: vm name
        """
        vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name)
        iface_xml = vmxml.get_devices('interface')[0]
        vmxml.del_device(iface_xml)
        iface_xml.source = {'bridge': br_name}
        iface_xml.filterref = iface_xml.new_filterref(name=nwfilter)
        logging.debug("new interface xml is: %s" % iface_xml)
        vmxml.add_device(iface_xml)
        vmxml.sync()

    def ping(src_ip, dest_ip, ping_count, timeout, session=None):
        """
        Wrap of ping

        :param src_ip: source address
        :param dest_ip: destination address
        :param ping_count: count of icmp packet
        :param timeout: timeout for the ping command
        :param session: local execution or session to execute the ping command
        :return: ping succeed or raise exception
        """
        status, output = utils_net.ping(dest=dest_ip, count=ping_count,
                                        interface=src_ip, timeout=timeout,
                                        session=session)
        if status:
            test.fail("Fail to ping %s from %s" % (dest_ip, src_ip))

    # Get test params
    bridge_name = params.get("bridge_name", "br0")
    filter_name = params.get("filter_name", "vdsm-no-mac-spoofing")
    ping_count = params.get("ping_count", "5")
    ping_timeout = float(params.get("ping_timeout", "10"))
    iface_name = utils_net.get_net_if(state="UP")[0]
    bridge_script = NETWORK_SCRIPT + bridge_name
    iface_script = NETWORK_SCRIPT + iface_name
    iface_script_bk = os.path.join(data_dir.get_tmp_dir(), "iface-%s.bk" % iface_name)

    vms = params.get("vms").split()
    if len(vms) <= 1:
        test.cancel("Need two VMs to test")
    else:
        vm1_name = vms[0]
        vm2_name = vms[1]

    vm1 = env.get_vm(vm1_name)
    vm2 = env.get_vm(vm2_name)

    # Back up the interface script
    process.run("cp %s %s" % (iface_script, iface_script_bk), shell=True)
    # Back up vm xml
    vm1_xml_bak = vm_xml.VMXML.new_from_dumpxml(vm1_name)
    vm2_xml_bak = vm_xml.VMXML.new_from_dumpxml(vm2_name)

    # Stop NetworkManager service
    NM_service = service.Factory.create_service("NetworkManager")
    NM_status = NM_service.status()
    if NM_status is True:
        NM_service.stop()

    # Start network service
    NW_service = service.Factory.create_service("network")
    NW_status = NW_service.status()
    if NW_status is None:
        logging.debug("network service not found")
        if not utils_package.package_install('network-scripts') or \
                not utils_package.package_install('initscripts'):
            test.cancel("Failed to install network service")
    if NW_status is not True:
        logging.debug("network service is not running")
        NW_service.start()

    try:
        create_bridge(bridge_name, iface_name)
        define_nwfilter(filter_name)
        modify_iface_xml(bridge_name, filter_name, vm1_name)

        if vm1.is_alive():
            vm1.destroy()

        vm1.start()
        # Check if vm can get ip with the new create bridge
        session1 = session2 = None
        try:
            utils_net.update_mac_ip_address(vm1, timeout=120)
            vm1_ip = vm1.get_address()
        except Exception as errs:
            test.fail("vm1 can't get IP with the new create bridge: %s" % errs)

        # Check guest and host can ping each other
        host_ip = utils_net.get_ip_address_by_interface(bridge_name)
        remote_ip = params.get("remote_ip", "www.baidu.com")
        ping(host_ip, vm1_ip, ping_count, ping_timeout)
        ping(host_ip, remote_ip, ping_count, ping_timeout)
        session1 = vm1.wait_for_login()
        ping(vm1_ip, host_ip, ping_count, ping_timeout, session=session1)
        ping(vm1_ip, remote_ip, ping_count, ping_timeout, session=session1)

        # Start vm2 connect to the same bridge
        modify_iface_xml(bridge_name, filter_name, vm2_name)
        if vm2.is_alive():
            vm2.destroy()
        vm2.start()

        # Check if vm1 and vm2 can ping each other
        try:
            utils_net.update_mac_ip_address(vm2, timeout=120)
            vm2_ip = vm2.get_address()
        except Exception as errs:
            test.fail("vm2 can't get IP with the new create bridge: %s" % errs)
        session2 = vm2.wait_for_login()
        ping(vm2_ip, vm1_ip, ping_count, ping_timeout, session=session2)
        ping(vm1_ip, vm2_ip, ping_count, ping_timeout, session=session1)
    finally:
        logging.debug("Start to restore")
        vm1_xml_bak.sync()
        vm2_xml_bak.sync()
        virsh.nwfilter_undefine(filter_name, ignore_status=True)
        if libvirt.check_iface(bridge_name, "exists", "--all"):
            virsh.iface_unbridge(bridge_name, timeout=60, debug=True)
        if os.path.exists(iface_script_bk):
            process.run("mv %s %s" % (iface_script_bk, iface_script), shell=True)
        if os.path.exists(bridge_script):
            process.run("rm -rf %s" % bridge_script, shell=True)
        # reload network configuration
        NW_service.restart()
        # recover NetworkManager
        if NM_status is True:
            NM_service.start()
示例#22
0
def run(test, params, env):
    """
    Test failover by team driver

    1) Boot a vm with 4 nics.
    2) inside guest, configure the team driver.
    3) inside guest, ping host
    4) inside guest, repeated down the slaves one by one.
    5) check ping_result.

    :param test: Kvm test object.
    :param params: Dictionary with the test parameters.
    :param env: Dictionary with test environment.
    """
    def team_port_add(ifnames, team_if):
        """Team0 add ports and return the ip link result for debuging"""
        for port in ifnames:
            session_serial.cmd_output_safe(params["clearip_cmd"] % port)
            session_serial.cmd_output_safe(params["setdown_cmd"] % port)
            session_serial.cmd_output_safe(params["addport_cmd"] % port)
        output_teamnl = session_serial.cmd_output_safe(params["portchk_cmd"])
        ports = re.findall(r"%s" % params["ptn_teamnl"], output_teamnl)
        for port in ifnames:
            if port not in ports:
                test.fail("Add %s to %s failed." % (port, team_if))
        session_serial.cmd_output_safe(params["killdhclient_cmd"])
        output = session_serial.cmd_output_safe(params["getip_cmd"],
                                                timeout=300)
        team_ip = re.search(r"%s" % params["ptn_ipv4"], output).group()
        if not team_ip:
            test.fail("Failed to get ip address of %s" % team_if)
        return ports, team_ip

    def failover(ifnames, timeout):
        """func for failover"""
        time.sleep(3)
        starttime = time.time()
        while True:
            pid_ping = session_serial.cmd_output_safe("pidof ping")
            pid = re.findall(r"(\d+)", pid_ping)
            if not pid:
                break
                # if ping finished, will break the loop.
            for port in ifnames:
                session_serial.cmd_output_safe(params["setdown_cmd"] % port)
                time.sleep(random.randint(5, 30))
                session_serial.cmd_output_safe(params["setup_cmd"] % port)
            endtime = time.time()
            timegap = endtime - starttime
            if timegap > timeout:
                break

    def check_ping(status, output):
        """ ratio <5% is acceptance."""
        if status != 0:
            test.fail("Ping failed, staus:%s, output:%s" % (status, output))
        # if status != 0 the ping process seams hit issue.
        ratio = utils_test.get_loss_ratio(output)
        if ratio == -1:
            test.fail("The ratio is %s, and status is %s, "
                      "output is %s" % (ratio, status, output))
        elif ratio > int(params["failed_ratio"]):
            test.fail("The loss raito is %s, test failed" % ratio)
        logging.info("ping pass with loss raito:%s, that less than %s", ratio,
                     params["failed_ratio"])

    def team_if_exist():
        """ judge if team is alive well."""
        team_exists_cmd = params.get("team_if_exists_cmd")
        return session_serial.cmd_status(team_exists_cmd) == 0

    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    timeout = int(params.get("login_timeout", 1200))
    session_serial = vm.wait_for_serial_login(timeout=timeout)
    ifnames = [
        utils_net.get_linux_ifname(session_serial, vm.get_mac_address(vlan))
        for vlan, nic in enumerate(vm.virtnet)
    ]
    session_serial.cmd_output_safe(params["nm_stop_cmd"])
    team_if = params.get("team_if")
    # initial

    error_context.context("Step1: Configure the team environment",
                          logging.info)
    # steps of building the teaming environment starts
    modprobe_cmd = "modprobe team"
    session_serial.cmd_output_safe(modprobe_cmd)
    session_serial.cmd_output_safe(params["createteam_cmd"])
    # this cmd is to create the team0 and correspoding userspace daemon
    if not team_if_exist():
        test.fail("Interface %s is not created." % team_if)
    # check if team0 is created successfully
    ports, team_ip = team_port_add(ifnames, team_if)
    logging.debug("The list of the ports that added to %s : %s", team_if,
                  ports)
    logging.debug("The ip address of %s : %s", team_if, team_ip)
    output = session_serial.cmd_output_safe(params["team_debug_cmd"])
    logging.debug("team interface configuration: %s", output)
    route_cmd = session_serial.cmd_output_safe(params["route_cmd"])
    logging.debug("The route table of guest: %s", route_cmd)
    # this is not this case checkpoint, just to check if route works fine
    # steps of building finished

    try:
        error_context.context("Login in guest via ssh", logging.info)
        # steps of testing this case starts
        session = vm.wait_for_login(timeout=timeout)
        dest = utils_net.get_ip_address_by_interface(params["netdst"])
        count = params.get("count")
        timeout = float(count) * 2
        error_context.context("Step2: Check if guest can ping out:",
                              logging.info)
        status, output = utils_test.ping(dest=dest,
                                         count=10,
                                         interface=team_if,
                                         timeout=30,
                                         session=session)
        check_ping(status, output)
        # small ping check if the team0 works w/o failover
        error_context.context(
            "Step3: Start failover testing until "
            "ping finished", logging.info)
        failover_thread = utils_misc.InterruptedThread(failover,
                                                       (ifnames, timeout))
        failover_thread.start()
        # start failover loop until ping finished
        error_context.context("Step4: Start ping host for %s counts" % count,
                              logging.info)
        if failover_thread.is_alive():
            status, output = utils_test.ping(dest=dest,
                                             count=count,
                                             interface=team_if,
                                             timeout=float(count) * 1.5,
                                             session=session)
            error_context.context("Step5: Check if ping succeeded",
                                  logging.info)
            check_ping(status, output)
        else:
            test.error("The failover thread is not alive")
        time.sleep(3)
        try:
            timeout = timeout * 1.5
            failover_thread.join(timeout)
        except Exception:
            test.error("Failed to join the failover thread")
        # finish the main steps and check the result
        session_serial.cmd_output_safe(params["killteam_cmd"])
        if team_if_exist():
            test.fail("Remove %s failed" % team_if)
        logging.info("%s removed", team_if)
        # remove the team0 and the daemon, check if succeed
    finally:
        if session:
            session.close()
def run(test, params, env):
    """
    create/delete macvtap in host

    1) Verify no other macvtap share the physical network device.
    2) Create a macvtap device in host.
    3) Check configuraton of macvtap device.
    4) Ping out from host with the interface that create macvtap.
    5) Delete the macvtap device create in step 2.
    6) Ping out from host with the interface that create macvtap.

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

    ifname = params.get("macvtap_base_interface")
    macvtap_mode = params.get("macvtap_mode", "passthru")
    dest_host = params.get("dest_host")
    set_mac = params.get("set_mac", "yes") == "yes"
    macvtaps = []

    if not ifname:
        ifname = params.get("netdst")
    ifname = utils_net.get_macvtap_base_iface(ifname)

    error.context("Verify no other macvtap share the physical network device.", logging.info)
    macvtap_devices = get_macvtap_device_on_ifname(ifname)
    for device in macvtap_devices:
        utils.system_output("ip link delete %s" % device)

    for mode in macvtap_mode.split():
        macvtap_name = "%s_01" % mode
        txt = "Create %s mode macvtap device %s on %s." % (mode, macvtap_name, ifname)
        error.context(txt, logging.info)
        cmd = " ip link add link %s name %s type macvtap mode %s" % (ifname, macvtap_name, mode)
        utils.system(cmd, timeout=240)
        if set_mac:
            txt = "Determine and configure mac address of %s, " % macvtap_name
            txt += "Then link up it."
            error.context(txt, logging.info)
            mac = utils_net.generate_mac_address_simple()
            cmd = " ip link set %s address %s up" % (macvtap_name, mac)
            utils.system(cmd, timeout=240)

        error.context("Check configuraton of macvtap device", logging.info)
        check_cmd = " ip -d link show %s" % macvtap_name
        try:
            tap_info = utils.system_output(check_cmd, timeout=240)
        except error.CmdError:
            err = "Fail to create %s mode macvtap on %s" % (mode, ifname)
            raise error.TestFail(err)
        if set_mac:
            if mac not in tap_info:
                err = "Fail to set mac for %s" % macvtap_name
                raise error.TestFail(err)
        macvtaps.append(macvtap_name)

    if not dest_host:
        dest_host_get_cmd = "ip route | awk '/default/ { print $3 }'"
        dest_host_get_cmd = params.get("dest_host_get_cmd", dest_host_get_cmd)
        dest_host = utils.system_output(dest_host_get_cmd).split()[-1]

    txt = "Ping dest host %s from " % dest_host
    txt += "localhost with the interface %s" % ifname
    error.context(txt, logging.info)
    status, output = utils_test.ping(dest_host, 10, interface=ifname, timeout=20)
    ratio = utils_test.get_loss_ratio(output)
    if "passthru" in macvtap_mode:
        ifnames = utils_net.get_host_iface()
        ifnames.remove(ifname)
        logging.info("ifnames = %s", ifnames)
        ips = []
        for name in ifnames:
            try:
                _ip = utils_net.get_ip_address_by_interface(name)
                if _ip != "127.0.0.1":
                    ips.append(_ip)
            except Exception:
                pass
        logging.info("ips = %s", ips)
        if not ips:
            if ratio != 100:
                err = "%s did not lost network connection after " % ifname
                err += " creating %s mode macvtap on it." % macvtap_mode
                raise error.TestFail(err)
        else:
            err = "%s is not the only network device in host" % ifname
            logging.debug(err)
    else:
        if ratio != 0:
            err = "Package lost during ping %s from %s " % (dest_host, ifname)
            err += "after creating %s mode macvtap on it." % macvtap_mode
            raise error.TestFail(err)

    for name in macvtaps:
        txt = "Delete macvtap device %s on %s." % (name, ifname)
        error.context(txt, logging.info)
        del_cmd = "ip link delete %s" % name
        utils.system(del_cmd)
        devices = get_macvtap_device_on_ifname(ifname)
        if name in devices:
            err = "Fail to delete macvtap %s on %s" % (name, ifname)
            raise error.TestFail(err)

    logging.info("dest_host = %s", dest_host)
    txt = "Ping dest host %s from " % dest_host
    txt += "localhost with the interface %s" % ifname
    error.context(txt, logging.info)
    status, output = utils_test.ping(dest_host, 10, interface=ifname, timeout=20)
    if status != 0:
        raise error.TestFail("Ping failed, status: %s," " output: %s" % (status, output))
    ratio = utils_test.get_loss_ratio(output)
    if ratio != 0:
        err = "Package lost during ping %s from %s " % (dest_host, ifname)
        raise error.TestFail(err)
示例#24
0
def run(test, params, env):
    """
    Test port mirror between guests in one ovs backend

    1) Boot the three vms.
    2) Set tap device of vm1 to mirror (input, output, input & output)
       of tap device of vm2 in openvswith.
    3) Start two tcpdump threads to dump icmp packet from vm2 and vm3.
    4) Ping host from vm2 and vm3.
    5) Stop ping in vm2 and vm3
    6) Check tcmpdump result in vm1.

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

    def make_mirror_cmd(
            mirror_port, target_port, direction="all", netdst="ovs0"):
        """
        Generate create ovs port mirror command.

        :parm mirror_port: port name in ovs in mirror status.
        :parm target_port: port name in ovs be mirroring.
        :parm direction: mirror direction, all, only input or output.
        :parm netdst: ovs port name.

        :return: string of ovs port mirror command.
        """
        cmd = ["ovs-vsctl set Bridge %s mirrors=@m " % netdst]
        cmd += map(lambda x: "-- --id=@%s get Port %s " % (x, x),
                   [mirror_port, target_port])
        if direction == "input":
            cmd.append(
                "-- --id=@m create Mirror name=input_of_%s" %
                target_port)
            cmd.append("select-dst-port=@%s" % target_port)
        elif direction == "output":
            cmd.append(
                "-- --id=@m create Mirror name=output_of_%s" % target_port)
            cmd.append("select-src-port=@%s" % target_port)
        else:
            cmd.append(
                "-- --id=@m create Mirror name=mirror_%s" % target_port)
            cmd.append("select-src-port=@%s" % target_port)
            cmd.append("select-dst-port=@%s" % target_port)
        cmd.append("output-port=@%s" % mirror_port)
        return " ".join(cmd)

    def create_mirror_port(mirror_port, target_port, direction, netdst):
        """
        Execute ovs port mirror command and check port really in mirror status.

        :parm mirror_port: port name in ovs in mirror status.
        :parm target_port: port name in ovs be mirroring.
        :parm direction: mirror direction, all, only input or output.
        :parm netdst: ovs port name.
        """
        mirror_cmd = make_mirror_cmd(mirror_port, target_port, direction, netdst)
        uuid = utils.system_output(mirror_cmd)
        output = utils.system_output("ovs-vsctl list mirror")
        if uuid not in output:
            logging.debug("Create OVS Mirror CMD: %s " % mirror_cmd)
            logging.debug("Ovs Info: %s " % output)
            raise error.TestFail("Setup mirorr port failed")

    def checkTcpdump(output, target_ip, host_ip, direction):
        """
        Check tcpdump result file and report unexpect packet to debug log.

        :parm output: string of tcpdump output.
        :parm target_p: ip of port in ovs be mirroring.
        :parm host_ip: ip of ovs port.
        :parm direction: mirror direction, all, only input or output.

        :return: bool type result.
        """
        rex = r".*IP (%s|%s) > " % (host_ip, target_ip)
        rex += "(%s|%s).*ICMP echo.*" % (target_ip, host_ip)
        if direction == "input":
            rex = r".*IP %s > %s.*ICMP echo reply.*" % (host_ip, target_ip)
        if direction == "output":
            rex = r".*IP %s > %s.*ICMP echo request.*" % (target_ip, host_ip)
        for idx, _ in enumerate(output.splitlines()):
            if not re.match(rex, _):
                logging.debug("Unexpect packet in line %d: %s" % (idx, _))
                return False
        return True

    os_dep.command("ovs-vsctl")
    if params.get("netdst") not in utils.system_output("ovs-vsctl show"):
        raise error.TestError("This is a openvswitch only test")

    netdst = params.get("netdst", "ovs0")
    direction = params.get("direction", "all")
    mirror_vm = params.get("mirror_vm", "vm1")
    target_vm = params.get("target_vm", "vm2")
    refer_vm = params.get("refer_vm", "vm3")
    login_timeout = int(params.get("login_timeout", "600"))
    ip_version = params.get("ip_version", "ipv4")
    host_ip = utils_net.get_ip_address_by_interface(netdst)
    try:
        vms_info = {}
        for p_vm in params.get("vms").split():
            o_vm = env.get_vm(p_vm)
            o_vm.verify_alive()
            session = o_vm.wait_for_serial_login(timeout=login_timeout)
            ifname = o_vm.get_ifname()
            ip = o_vm.wait_for_get_address(0, timeout=login_timeout,
                                           ip_version=ip_version)
            vms_info[p_vm] = [o_vm, ifname, ip, session]

        mirror_ifname = vms_info[mirror_vm][1]
        target_ifname = vms_info[target_vm][1]
        target_ip = vms_info[target_vm][2]
        refer_ip = vms_info[refer_vm][2]
        session = vms_info[mirror_vm][3]

        error.context("Create mirror port in ovs", logging.info)
        create_mirror_port(mirror_ifname, target_ifname, direction, netdst)
        ping_cmd = "ping -c 10 %s" % host_ip
        status, output = session.cmd_status_output(ping_cmd, timeout=60)
        if status == 0:
            ifcfg = session.cmd_output_safe("ifconfig")
            logging.debug("Guest network info: %s" % ifcfg)
            logging.debug("Ping results: %s" % output)
            raise error.TestFail("All packets from %s to host should lost"
                                 % mirror_vm)

        error.context("Start tcpdump threads in %s" % mirror_vm, logging.info)
        session.cmd("ifconfig eth0 0 up", timeout=60)
        for vm, ip in [(target_vm, target_ip), (refer_vm, refer_ip)]:
            tcpdump_cmd = "tcpdump -l -n host %s and icmp >" % ip
            tcpdump_cmd += "/tmp/tcpdump-%s.txt &" % vm
            session.sendline(tcpdump_cmd)
            time.sleep(0.5)

        error.context("Start ping threads in %s %s" % (target_vm, refer_vm),
                      logging.info)
        for vm in [target_vm, refer_vm]:
            ses = vms_info[vm][3]
            ses.cmd("ping %s -c 100" % host_ip, timeout=150)

        error.context("Check tcpdump results", logging.info)
        session.cmd_output_safe("pkill tcpdump")
        utils.system("ovs-vsctl clear bridge %s mirrors" % netdst)
        session.cmd("service network restart", timeout=60)
        for vm in [target_vm, refer_vm]:
            src_file = "/tmp/tcpdump-%s.txt" % vm
            dst_file = os.path.join(test.resultsdir, "tcpdump-%s.txt" % vm)
            vms_info[mirror_vm][0].copy_files_from(src_file, dst_file)
            fd = open(dst_file, "r")
            content = fd.read().strip()
            fd.close()
            if vm == refer_vm and content:
                raise error.TestFail(
                    "should not packet from %s dumped in %s" %
                    (refer_vm, mirror_vm))
            elif not checkTcpdump(content, target_ip, host_ip, direction):
                raise error.TestFail(
                    "Unexpect packages from %s dumped in %s" % (vm, mirror_vm))
    finally:
        for f in glob.glob("/var/log/openvswith/*.log"):
            dst = os.path.join(test.resultsdir, os.path.basename(f))
            shutil.copy(f, dst)
示例#25
0
def run_netperf_udp(test, params, env):
    """
    Run netperf on server and client side, we need run this case on two
    machines. If dsthost is not set will start netperf server on local
    host and log a error message.:
    1) Start one vm guest os as client.
    2) Start a reference machine (dsthost) as server.
    3) Setup netperf on guest and reference machine (dsthost).
    4) Run netserver on server using control.server.
    5) Run netperf client command in guest several time with different
       message size.
    6) Compare UDP performance to make sure it is acceptable.

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


    def get_remote_host_session():
        dsthostssh = remote.remote_login("ssh", dsthost, 22, "root",
                                         passwd, "#", timeout=30)
        if dsthostssh:
            dsthostssh.set_status_test_command("echo $?")
            return dsthostssh
        else:
            return None


    def scp_to_remote(local_path="", remote_path=""):
        remote.scp_to_remote(dsthost, 22, "root", passwd, local_path,
                             remote_path)
        vm.copy_files_to(local_path, remote_path)

    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()

    session = vm.wait_for_login(timeout=int(params.get("login_timeout", 360)))

    dsthost = params.get("dsthost")
    if not dsthost:
        dsthost = utils_net.get_ip_address_by_interface(params.get("netdst"))
        logging.error("dsthost is not set, use localhost ip %s" % dsthost)
    else:
        logging.info("Dest host is %s" % dsthost)
    passwd = params.get("hostpasswd")
    test_timeout = float(params.get("test_timeout", "1200"))

    error.context("Create session connection to remote machine")
    dsthostssh = utils_misc.wait_for(get_remote_host_session, 120, 0, 2)
    if not dsthostssh:
        raise error.TestError("Could not login into remote host %s " % dsthost)

    # Get range of message size.
    message_size_range = params.get("message_size_range")
    message_size = message_size_range.split()
    start_size = int(message_size[0])
    end_size = int(message_size[1])
    step = int(message_size[2])
    m_size = start_size

    error.context("Copy netperf to dsthost and guest vm.")
    netperf_dir = os.path.join(os.environ['AUTODIR'], "tests/netperf2")
    for i in params.get("netperf_files").split():
        scp_to_remote("%s/%s" % (netperf_dir, i), "/tmp/")

    # Setup netpref.
    error.context("Set up netperf on reference machine.", logging.info)
    cmd = params.get("setup_cmd")
    (s, output) = dsthostssh.get_command_status_output(cmd,
                                                       timeout=test_timeout)
    if s != 0:
        raise error.TestError("Fail to setup netperf on reference machine.")
    error.context("Setup netperf on guest os.", logging.info)
    (s, output) = session.get_command_status_output(cmd,
                                                   timeout=test_timeout)
    if s != 0:
        raise error.TestError("Fail to setup netperf on guest os.")

    # Start netperf server in dsthost.
    cmd = "killall netserver"
    dsthostssh.get_command_status_output(cmd)
    cmd = params.get("netserver_cmd")
    txt = "Run netserver on server (dsthost) using control.server."
    error.context(txt, logging.info)
    (s, output) = dsthostssh.get_command_status_output(cmd)
    if s != 0:
        txt = "Fail to start netperf server on remote machine."
        txt += " Command output: %s" % output
        raise error.TestError(txt)

    throughput = []

    # Run netperf with message size defined in range.
    msg = "Detail result for netperf udp test with different message size.\n"
    while(m_size <= end_size):
        cmd = params.get("netperf_cmd")% (dsthost, m_size)
        txt = "Run netperf client command in guest: %s" % cmd
        error.context(txt, logging.info)
        (s, output) = session.get_command_status_output(cmd)
        if s != 0:
            txt = "Fail to execute netperf client side command in guest."
            txt += " Command output: %s" % output
            raise error.TestError(txt)
        line_tokens = output.splitlines()[6].split()
        throughput.append(float(line_tokens[5]))
        msg += output
        m_size += step
    file(os.path.join(test.debugdir, "udp_results"), "w").write(msg)

    failratio = float(params.get("failratio", 0.3))
    error.context("Compare UDP performance.", logging.info)
    for i in range(len(throughput) - 1):
        if abs(throughput[i] - throughput[i + 1]) > throughput[i] * failratio:
            txt = "The gap between adjacent throughput is greater than"
            txt += "%f." % failratio
            txt += "Please refer to log file for details:\n %s" % msg
            raise error.TestFail(txt)
    logging.info("The UDP performance as measured via netperf is ok.")
    logging.info("Throughput of netperf command: %s" % throughput)
    logging.debug("Output of netperf command:\n %s" % msg)
    error.context("Kill netperf server on server (dsthost).")

    cmd = "killall -9 netserver"
    try:
        dsthostssh.get_command_status_output(cmd)
    except Exception:
        pass
示例#26
0
def run(test, params, env):
    """
    KVM multi test:
    1) Log into guests
    2) Check all the nics available or not
    3) Ping among guest nic and host
       3.1) Ping with different packet size
       3.2) Flood ping test
       3.3) Final ping test
    4) Transfer files among guest nics and host
       4.1) Create file by dd command in guest
       4.2) Transfer file between nics
       4.3) Compare original file and transferred file
    5) ping among different nics
       5.1) Ping with different packet size
       5.2) Flood ping test
       5.3) Final ping test
    6) Transfer files among different nics
       6.1) Create file by dd command in guest
       6.2) Transfer file between nics
       6.3) Compare original file and transferred file
    7) Repeat step 3 - 6 on every nic.

    :param test: QEMU test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    """
    def ping(session, nic, dst_ip, strick_check, flood_minutes):
        d_packet_size = [
            1, 4, 48, 512, 1440, 1500, 1505, 4054, 4055, 4096, 4192, 8878,
            9000, 32767, 65507
        ]
        packet_size = params.get("packet_size", "").split() or d_packet_size
        for size in packet_size:
            error_context.context("Ping with packet size %s" % size,
                                  logging.info)
            status, output = utils_test.ping(dst_ip,
                                             10,
                                             interface=nic,
                                             packetsize=size,
                                             timeout=30,
                                             session=session)
            if strict_check:
                ratio = utils_test.get_loss_ratio(output)
                if ratio != 0:
                    test.fail("Loss ratio is %s for packet size"
                              " %s" % (ratio, size))
            else:
                if status != 0:
                    test.fail("Ping returns non-zero value %s" % output)

        error_context.context("Flood ping test", logging.info)
        utils_test.ping(dst_ip,
                        None,
                        interface=nic,
                        flood=True,
                        output_func=None,
                        timeout=flood_minutes * 60,
                        session=session)
        error_context.context("Final ping test", logging.info)
        counts = params.get("ping_counts", 100)
        status, output = utils_test.ping(dst_ip,
                                         counts,
                                         interface=nic,
                                         timeout=float(counts) * 1.5,
                                         session=session)
        if strick_check == "yes":
            ratio = utils_test.get_loss_ratio(output)
            if ratio != 0:
                test.fail("Packet loss ratio is %s after flood" % ratio)
        else:
            if status != 0:
                test.fail("Ping returns non-zero value %s" % output)

    def file_transfer(session, src, dst):
        username = params.get("username", "")
        password = params.get("password", "")
        src_path = "/tmp/1"
        dst_path = "/tmp/2"
        port = int(params["file_transfer_port"])

        cmd = "dd if=/dev/urandom of=%s bs=100M count=1" % src_path
        cmd = params.get("file_create_cmd", cmd)

        error_context.context("Create file by dd command, cmd: %s" % cmd,
                              logging.info)
        session.cmd(cmd)

        transfer_timeout = int(params.get("transfer_timeout"))
        log_filename = "scp-from-%s-to-%s.log" % (src, dst)
        error_context.context("Transfer file from %s to %s" % (src, dst),
                              logging.info)
        remote.scp_between_remotes(src,
                                   dst,
                                   port,
                                   password,
                                   password,
                                   username,
                                   username,
                                   src_path,
                                   dst_path,
                                   log_filename=log_filename,
                                   timeout=transfer_timeout)
        src_path = dst_path
        dst_path = "/tmp/3"
        log_filename = "scp-from-%s-to-%s.log" % (dst, src)
        error_context.context("Transfer file from %s to %s" % (dst, src),
                              logging.info)
        remote.scp_between_remotes(dst,
                                   src,
                                   port,
                                   password,
                                   password,
                                   username,
                                   username,
                                   src_path,
                                   dst_path,
                                   log_filename=log_filename,
                                   timeout=transfer_timeout)
        error_context.context("Compare original file and transferred file",
                              logging.info)

        cmd1 = "md5sum /tmp/1"
        cmd2 = "md5sum /tmp/3"
        md5sum1 = session.cmd(cmd1).split()[0]
        md5sum2 = session.cmd(cmd2).split()[0]
        if md5sum1 != md5sum2:
            test.error("File changed after transfer")

    nic_interface_list = []
    check_irqbalance_cmd = params.get("check_irqbalance_cmd",
                                      "systemctl status irqbalance")
    stop_irqbalance_cmd = params.get("stop_irqbalance_cmd",
                                     "systemctl stop irqbalance")
    start_irqbalance_cmd = params.get("start_irqbalance_cmd",
                                      "systemctl start irqbalance")
    status_irqbalance = params.get("status_irqbalance",
                                   "Active: active|running")
    vms = params["vms"].split()
    host_mem = utils_memory.memtotal() // (1024 * 1024)
    host_cpu_count = cpu.total_count()
    vhost_count = 0
    if params.get("vhost"):
        vhost_count = 1
    if host_cpu_count < (1 + vhost_count) * len(vms):
        test.error("The host don't have enough cpus to start guest"
                   "pcus: %d, minimum of vcpus and vhost: %d" %
                   (host_cpu_count, (1 + vhost_count) * len(vms)))
    params['mem'] = host_mem // len(vms) * 1024
    params['smp'] = host_cpu_count // len(vms) - vhost_count
    if params['smp'] % 2 != 0:
        params['vcpu_sockets'] = 1
    params["start_vm"] = "yes"
    for vm_name in vms:
        env_process.preprocess_vm(test, params, env, vm_name)
    timeout = float(params.get("login_timeout", 360))
    strict_check = params.get("strick_check", "no")
    host_ip = utils_net.get_ip_address_by_interface(params.get("netdst"))
    host_ip = params.get("srchost", host_ip)
    flood_minutes = float(params["flood_minutes"])
    error_context.context("Check irqbalance service status", logging.info)
    o = process.system_output(check_irqbalance_cmd,
                              ignore_status=True,
                              shell=True).decode()
    check_stop_irqbalance = False
    if re.findall(status_irqbalance, o):
        logging.debug("stop irqbalance")
        process.run(stop_irqbalance_cmd, shell=True)
        check_stop_irqbalance = True
        o = process.system_output(check_irqbalance_cmd,
                                  ignore_status=True,
                                  shell=True).decode()
        if re.findall(status_irqbalance, o):
            test.error("Can not stop irqbalance")
    thread_list = []
    nic_interface = []
    for vm_name in vms:
        guest_ifname = ""
        guest_ip = ""
        vm = env.get_vm(vm_name)
        session = vm.wait_for_login(timeout=timeout)
        thread_list.extend(vm.vcpu_threads)
        thread_list.extend(vm.vhost_threads)
        error_context.context("Check all the nics available or not",
                              logging.info)
        for index, nic in enumerate(vm.virtnet):
            guest_ifname = utils_net.get_linux_ifname(session, nic.mac)
            guest_ip = vm.get_address(index)
            if not (guest_ifname and guest_ip):
                err_log = "vms %s get ip or ifname failed." % vm_name
                err_log = "ifname: %s, ip: %s." % (guest_ifname, guest_ip)
                test.fail(err_log)
            nic_interface = [guest_ifname, guest_ip, session]
            nic_interface_list.append(nic_interface)
    error_context.context("Pin vcpus and vhosts to host cpus", logging.info)
    host_numa_nodes = utils_misc.NumaInfo()
    vthread_num = 0
    for numa_node_id in host_numa_nodes.nodes:
        numa_node = host_numa_nodes.nodes[numa_node_id]
        for _ in range(len(numa_node.cpus)):
            if vthread_num >= len(thread_list):
                break
            vcpu_tid = thread_list[vthread_num]
            logging.debug("pin vcpu/vhost thread(%s) to cpu(%s)" %
                          (vcpu_tid, numa_node.pin_cpu(vcpu_tid)))
            vthread_num += 1

    nic_interface_list_len = len(nic_interface_list)
    # ping and file transfer test
    for src_ip_index in range(nic_interface_list_len):
        error_context.context("Ping test from guest to host", logging.info)
        src_ip_info = nic_interface_list[src_ip_index]
        ping(src_ip_info[2], src_ip_info[0], host_ip, strict_check,
             flood_minutes)
        error_context.context("File transfer test between guest and host",
                              logging.info)
        file_transfer(src_ip_info[2], src_ip_info[1], host_ip)
        for dst_ip in nic_interface_list[src_ip_index:]:
            if src_ip_info[1] == dst_ip[1]:
                continue
            txt = "Ping test between %s and %s" % (src_ip_info[1], dst_ip[1])
            error_context.context(txt, logging.info)
            ping(src_ip_info[2], src_ip_info[0], dst_ip[1], strict_check,
                 flood_minutes)
            txt = "File transfer test between %s " % src_ip_info[1]
            txt += "and %s" % dst_ip[1]
            error_context.context(txt, logging.info)
            file_transfer(src_ip_info[2], src_ip_info[1], dst_ip[1])
    if check_stop_irqbalance:
        process.run(start_irqbalance_cmd, shell=True)
示例#27
0
文件: kdump.py 项目: arges/tp-qemu
def kdump_enable(vm, vm_name, crash_kernel_prob_cmd,
                 kernel_param_cmd, kdump_enable_cmd, timeout):
    """
    Check, configure and enable the kdump in guest.

    :param vm_name: vm name
    :param crash_kernel_prob_cmd: check kdume loaded
    :param kernel_param_cmd: the param add into kernel line for kdump
    :param kdump_enable_cmd: enable kdump command
    :param timeout: Timeout in seconds
    """
    kdump_cfg_path = vm.params.get("kdump_cfg_path", "/etc/kdump.conf")
    kdump_config = vm.params.get("kdump_config")
    vmcore_path = vm.params.get("vmcore_path", "/var/crash")
    kdump_method = vm.params.get("kdump_method", "basic")
    kdump_propagate_cmd = vm.params.get("kdump_propagate_cmd")

    error.context("Try to log into guest '%s'." % vm_name, logging.info)
    session = vm.wait_for_login(timeout=timeout)

    error.context("Checking the existence of crash kernel in %s" %
                  vm_name, logging.info)
    try:
        session.cmd(crash_kernel_prob_cmd)
    except Exception:
        error.context("Crash kernel is not loaded. Trying to load it",
                      logging.info)
        session.cmd(kernel_param_cmd)
        session = vm.reboot(session, timeout=timeout)

    if kdump_config:
        if kdump_method == "ssh":
            host_ip = utils_net.get_ip_address_by_interface(vm.params.get('netdst'))
            kdump_config = kdump_config % (host_ip, vmcore_path)

        error.context("Configuring the Core Collector...", logging.info)

        session.cmd("cat /dev/null > %s" % kdump_cfg_path)
        for config_line in kdump_config.split(";"):
            config_cmd = "echo -e '%s' >> %s "
            config_con = config_line.strip()
            session.cmd(config_cmd % (config_con, kdump_cfg_path))

    if kdump_method == "ssh":
        host_pwd = vm.params.get("host_pwd", "redhat")
        guest_pwd = vm.params.get("guest_pwd", "redhat")
        guest_ip = vm.get_address()

        error.context("Setup ssh login without password...", logging.info)
        session.cmd("rm -rf /root/.ssh/*")

        ssh_connection = utils_conn.SSHConnection(server_ip=host_ip,
                                                  server_pwd=host_pwd,
                                                  client_ip=guest_ip,
                                                  client_pwd=guest_pwd)
        try:
            ssh_connection.conn_check()
        except utils_conn.ConnectionError:
            ssh_connection.conn_setup()
            ssh_connection.conn_check()

        logging.info("Trying to propagate with command '%s'" %
                     kdump_propagate_cmd)
        session.cmd(kdump_propagate_cmd, timeout=120)

    error.context("Enabling kdump service...", logging.info)
    # the initrd may be rebuilt here so we need to wait a little more
    session.cmd(kdump_enable_cmd, timeout=120)

    return session
示例#28
0
def run(test, params, env):
    """
    create/delete macvtap in host

    1) Verify no other macvtap share the physical network device.
    2) Create a macvtap device in host.
    3) Check configuraton of macvtap device.
    4) Ping out from host with the interface that create macvtap.
    5) Delete the macvtap device create in step 2.
    6) Ping out from host with the interface that create macvtap.

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

    ifname = params.get("macvtap_base_interface")
    macvtap_mode = params.get("macvtap_mode", "passthru")
    dest_host = params.get("dest_host")
    set_mac = params.get("set_mac", "yes") == "yes"
    macvtaps = []

    if not ifname:
        ifname = params.get("netdst")
    ifname = utils_net.get_macvtap_base_iface(ifname)

    error.context("Verify no other macvtap share the physical network device.",
                  logging.info)
    macvtap_devices = get_macvtap_device_on_ifname(ifname)
    for device in macvtap_devices:
        utils.system_output("ip link delete %s" % device)

    for mode in macvtap_mode.split():
        macvtap_name = "%s_01" % mode
        txt = "Create %s mode macvtap device %s on %s." % (mode,
                                                           macvtap_name,
                                                           ifname)
        error.context(txt, logging.info)
        cmd = " ip link add link %s name %s type macvtap mode %s" % (ifname,
                                                                     macvtap_name,
                                                                     mode)
        utils.system(cmd, timeout=240)
        if set_mac:
            txt = "Determine and configure mac address of %s, " % macvtap_name
            txt += "Then link up it."
            error.context(txt, logging.info)
            mac = utils_net.generate_mac_address_simple()
            cmd = " ip link set %s address %s up" % (macvtap_name, mac)
            utils.system(cmd, timeout=240)

        error.context("Check configuraton of macvtap device", logging.info)
        check_cmd = " ip -d link show %s" % macvtap_name
        try:
            tap_info = utils.system_output(check_cmd, timeout=240)
        except error.CmdError:
            err = "Fail to create %s mode macvtap on %s" % (mode, ifname)
            raise error.TestFail(err)
        if set_mac:
            if mac not in tap_info:
                err = "Fail to set mac for %s" % macvtap_name
                raise error.TestFail(err)
        macvtaps.append(macvtap_name)

    if not dest_host:
        dest_host_get_cmd = "ip route | awk '/default/ { print $3 }'"
        dest_host_get_cmd = params.get("dest_host_get_cmd", dest_host_get_cmd)
        dest_host = utils.system_output(dest_host_get_cmd).split()[-1]

    txt = "Ping dest host %s from " % dest_host
    txt += "localhost with the interface %s" % ifname
    error.context(txt, logging.info)
    status, output = utils_test.ping(dest_host, 10,
                                     interface=ifname, timeout=20)
    ratio = utils_test.get_loss_ratio(output)
    if "passthru" in macvtap_mode:
        ifnames = utils_net.get_host_iface()
        ifnames.remove(ifname)
        logging.info("ifnames = %s", ifnames)
        ips = []
        for name in ifnames:
            try:
                _ip = utils_net.get_ip_address_by_interface(name)
                if _ip != "127.0.0.1":
                    ips.append(_ip)
            except Exception:
                pass
        logging.info("ips = %s", ips)
        if not ips:
            if ratio != 100:
                err = "%s did not lost network connection after " % ifname
                err += " creating %s mode macvtap on it." % macvtap_mode
                raise error.TestFail(err)
        else:
            err = "%s is not the only network device in host" % ifname
            logging.debug(err)
    else:
        if ratio != 0:
            err = "Package lost during ping %s from %s " % (dest_host, ifname)
            err += "after creating %s mode macvtap on it." % macvtap_mode
            raise error.TestFail(err)

    for name in macvtaps:
        txt = "Delete macvtap device %s on %s." % (name, ifname)
        error.context(txt, logging.info)
        del_cmd = "ip link delete %s" % name
        utils.system(del_cmd)
        devices = get_macvtap_device_on_ifname(ifname)
        if name in devices:
            err = "Fail to delete macvtap %s on %s" % (name, ifname)
            raise error.TestFail(err)

    logging.info("dest_host = %s", dest_host)
    txt = "Ping dest host %s from " % dest_host
    txt += "localhost with the interface %s" % ifname
    error.context(txt, logging.info)
    status, output = utils_test.ping(dest_host, 10,
                                     interface=ifname, timeout=20)
    if status != 0:
        raise error.TestFail("Ping failed, status: %s,"
                             " output: %s" % (status, output))
    ratio = utils_test.get_loss_ratio(output)
    if ratio != 0:
        err = "Package lost during ping %s from %s " % (dest_host, ifname)
        raise error.TestFail(err)
示例#29
0
    def __init__(self, test, params, vm):
        """
        Sets class attributes from test parameters.

        :param test: QEMU test object.
        :param params: Dictionary with test parameters.
        """
        root_dir = data_dir.get_data_dir()
        self.deps_dir = os.path.join(test.virtdir, 'deps')
        self.unattended_dir = os.path.join(test.virtdir, 'unattended')
        self.results_dir = test.debugdir
        self.params = params

        self.attributes = ['kernel_args', 'finish_program', 'cdrom_cd1',
                           'unattended_file', 'medium', 'url', 'kernel',
                           'initrd', 'nfs_server', 'nfs_dir', 'install_virtio',
                           'floppy_name', 'cdrom_unattended', 'boot_path',
                           'kernel_params', 'extra_params', 'qemu_img_binary',
                           'cdkey', 'finish_program', 'vm_type',
                           'process_check', 'vfd_size', 'cdrom_mount_point',
                           'floppy_mount_point', 'cdrom_virtio',
                           'virtio_floppy', 're_driver_match',
                           're_hardware_id', 'driver_in_floppy']

        for a in self.attributes:
            setattr(self, a, params.get(a, ''))

        # Will setup the virtio attributes
        v_attributes = ['virtio_floppy', 'virtio_scsi_path', 'virtio_storage_path',
                        'virtio_network_path', 'virtio_oemsetup_id',
                        'virtio_network_installer_path',
                        'virtio_balloon_installer_path',
                        'virtio_qxl_installer_path']

        for va in v_attributes:
            setattr(self, va, params.get(va, ''))

        self.tmpdir = test.tmpdir
        self.qemu_img_binary = utils_misc.get_qemu_img_binary(params)

        if getattr(self, 'unattended_file'):
            self.unattended_file = os.path.join(test.virtdir,
                                                self.unattended_file)

        if getattr(self, 'finish_program'):
            self.finish_program = os.path.join(test.virtdir,
                                               self.finish_program)

        if getattr(self, 'cdrom_cd1'):
            self.cdrom_cd1 = os.path.join(root_dir, self.cdrom_cd1)
        self.cdrom_cd1_mount = tempfile.mkdtemp(prefix='cdrom_cd1_',
                                                dir=self.tmpdir)
        if getattr(self, 'cdrom_unattended'):
            self.cdrom_unattended = os.path.join(root_dir,
                                                 self.cdrom_unattended)

        if getattr(self, 'virtio_floppy'):
            self.virtio_floppy = os.path.join(root_dir, self.virtio_floppy)

        if getattr(self, 'cdrom_virtio'):
            self.cdrom_virtio = os.path.join(root_dir, self.cdrom_virtio)

        if getattr(self, 'kernel'):
            self.kernel = os.path.join(root_dir, self.kernel)
        if getattr(self, 'initrd'):
            self.initrd = os.path.join(root_dir, self.initrd)

        if self.medium == 'nfs':
            self.nfs_mount = tempfile.mkdtemp(prefix='nfs_',
                                              dir=self.tmpdir)

        setattr(self, 'floppy', self.floppy_name)
        if getattr(self, 'floppy'):
            self.floppy = os.path.join(root_dir, self.floppy)
            if not os.path.isdir(os.path.dirname(self.floppy)):
                os.makedirs(os.path.dirname(self.floppy))

        self.image_path = os.path.dirname(self.kernel)

        # Content server params
        # lookup host ip address for first nic by interface name
        try:
            auto_ip = utils_net.get_ip_address_by_interface(
                vm.virtnet[0].netdst)
        except utils_net.NetError:
            auto_ip = None

        self.url_auto_content_ip = params.get('url_auto_ip', auto_ip)
        self.url_auto_content_port = None

        # Kickstart server params
        # use the same IP as url_auto_content_ip, but a different port
        self.unattended_server_port = None

        # Embedded Syslog Server
        self.syslog_server_enabled = params.get('syslog_server_enabled', 'no')
        self.syslog_server_ip = params.get('syslog_server_ip', auto_ip)
        self.syslog_server_port = int(params.get('syslog_server_port', 5140))
        self.syslog_server_tcp = params.get('syslog_server_proto',
                                            'tcp') == 'tcp'

        self.vm = vm
示例#30
0
    def __init__(self, test, params, vm):
        """
        Sets class attributes from test parameters.

        :param test: QEMU test object.
        :param params: Dictionary with test parameters.
        """
        root_dir = data_dir.get_data_dir()
        self.deps_dir = os.path.join(test.virtdir, 'deps')
        self.unattended_dir = os.path.join(test.virtdir, 'unattended')
        self.results_dir = test.debugdir
        self.params = params

        self.attributes = [
            'kernel_args', 'finish_program', 'cdrom_cd1', 'unattended_file',
            'medium', 'url', 'kernel', 'initrd', 'nfs_server', 'nfs_dir',
            'install_virtio', 'floppy_name', 'cdrom_unattended', 'boot_path',
            'kernel_params', 'extra_params', 'qemu_img_binary', 'cdkey',
            'finish_program', 'vm_type', 'process_check', 'vfd_size',
            'cdrom_mount_point', 'floppy_mount_point', 'cdrom_virtio',
            'virtio_floppy', 're_driver_match', 're_hardware_id',
            'driver_in_floppy'
        ]

        for a in self.attributes:
            setattr(self, a, params.get(a, ''))

        # Will setup the virtio attributes
        v_attributes = [
            'virtio_floppy', 'virtio_scsi_path', 'virtio_storage_path',
            'virtio_network_path', 'virtio_oemsetup_id',
            'virtio_network_installer_path', 'virtio_balloon_installer_path',
            'virtio_qxl_installer_path'
        ]

        for va in v_attributes:
            setattr(self, va, params.get(va, ''))

        self.tmpdir = test.tmpdir
        self.qemu_img_binary = utils_misc.get_qemu_img_binary(params)

        if getattr(self, 'unattended_file'):
            self.unattended_file = os.path.join(test.virtdir,
                                                self.unattended_file)

        if getattr(self, 'finish_program'):
            self.finish_program = os.path.join(test.virtdir,
                                               self.finish_program)

        if getattr(self, 'cdrom_cd1'):
            self.cdrom_cd1 = os.path.join(root_dir, self.cdrom_cd1)
        self.cdrom_cd1_mount = tempfile.mkdtemp(prefix='cdrom_cd1_',
                                                dir=self.tmpdir)
        if getattr(self, 'cdrom_unattended'):
            self.cdrom_unattended = os.path.join(root_dir,
                                                 self.cdrom_unattended)

        if getattr(self, 'virtio_floppy'):
            self.virtio_floppy = os.path.join(root_dir, self.virtio_floppy)

        if getattr(self, 'cdrom_virtio'):
            self.cdrom_virtio = os.path.join(root_dir, self.cdrom_virtio)

        if getattr(self, 'kernel'):
            self.kernel = os.path.join(root_dir, self.kernel)
        if getattr(self, 'initrd'):
            self.initrd = os.path.join(root_dir, self.initrd)

        if self.medium == 'nfs':
            self.nfs_mount = tempfile.mkdtemp(prefix='nfs_', dir=self.tmpdir)

        setattr(self, 'floppy', self.floppy_name)
        if getattr(self, 'floppy'):
            self.floppy = os.path.join(root_dir, self.floppy)
            if not os.path.isdir(os.path.dirname(self.floppy)):
                os.makedirs(os.path.dirname(self.floppy))

        self.image_path = os.path.dirname(self.kernel)

        # Content server params
        # lookup host ip address for first nic by interface name
        try:
            auto_ip = utils_net.get_ip_address_by_interface(
                vm.virtnet[0].netdst)
        except utils_net.NetError:
            auto_ip = None

        self.url_auto_content_ip = params.get('url_auto_ip', auto_ip)
        self.url_auto_content_port = None

        # Kickstart server params
        # use the same IP as url_auto_content_ip, but a different port
        self.unattended_server_port = None

        # Embedded Syslog Server
        self.syslog_server_enabled = params.get('syslog_server_enabled', 'no')
        self.syslog_server_ip = params.get('syslog_server_ip', auto_ip)
        self.syslog_server_port = int(params.get('syslog_server_port', 5140))
        self.syslog_server_tcp = params.get('syslog_server_proto',
                                            'tcp') == 'tcp'

        self.vm = vm
示例#31
0
def run_multi_vms_nics(test, params, env):
    """
    KVM multi test:
    1) Log into guests
    2) Check all the nics available or not
    3) Ping among guest nic and host
       3.1) Ping with different packet size
       3.2) Flood ping test
       3.3) Final ping test
    4) Transfer files among guest nics and host
       4.1) Create file by dd command in guest
       4.2) Transfer file between nics
       4.3) Compare original file and transferred file
    5) ping among different nics
       5.1) Ping with different packet size
       5.2) Flood ping test
       5.3) Final ping test
    6) Transfer files among different nics
       6.1) Create file by dd command in guest
       6.2) Transfer file between nics
       6.3) Compare original file and transferred file
    7) Repeat step 3 - 6 on every nic.

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

    def ping(session, nic, dst_ip, strick_check, flood_minutes):
        d_packet_size = [1, 4, 48, 512, 1440, 1500, 1505, 4054, 4055, 4096,
                         4192, 8878, 9000, 32767, 65507]
        packet_size = params.get("packet_size", "").split() or d_packet_size
        for size in packet_size:
            error.context("Ping with packet size %s" % size, logging.info)
            status, output = utils_test.ping(dst_ip, 10, interface=nic,
                                             packetsize=size,
                                             timeout=30, session=session)
            if strict_check:
                ratio = utils_test.get_loss_ratio(output)
                if ratio != 0:
                    raise error.TestFail("Loss ratio is %s for packet size"
                                         " %s" % (ratio, size))
            else:
                if status != 0:
                    raise error.TestFail("Ping returns non-zero value %s" %
                                         output)

        error.context("Flood ping test", logging.info)
        utils_test.ping(dst_ip, None, interface=nic, flood=True,
                        output_func=None, timeout=flood_minutes * 60,
                        session=session)
        error.context("Final ping test", logging.info)
        counts = params.get("ping_counts", 100)
        status, output = utils_test.ping(dst_ip, counts, interface=nic,
                                         timeout=float(counts) * 1.5,
                                         session=session)
        if strick_check == "yes":
            ratio = utils_test.get_loss_ratio(output)
            if ratio != 0:
                raise error.TestFail("Packet loss ratio is %s after flood"
                                     % ratio)
        else:
            if status != 0:
                raise error.TestFail("Ping returns non-zero value %s" %
                                     output)

    def file_transfer(session, src, dst):
        username = params.get("username", "")
        password = params.get("password", "")
        src_path = "/tmp/1"
        dst_path = "/tmp/2"
        port = int(params["file_transfer_port"])

        cmd = "dd if=/dev/urandom of=%s bs=100M count=1" % src_path
        cmd = params.get("file_create_cmd", cmd)

        error.context("Create file by dd command, cmd: %s" % cmd, logging.info)
        session.cmd(cmd)

        transfer_timeout = int(params.get("transfer_timeout"))
        log_filename = "scp-from-%s-to-%s.log" % (src, dst)
        error.context("Transfer file from %s to %s" % (src, dst), logging.info)
        remote.scp_between_remotes(src, dst, port, password, password,
                                   username, username, src_path, dst_path,
                                   log_filename=log_filename,
                                   timeout=transfer_timeout)
        src_path = dst_path
        dst_path = "/tmp/3"
        log_filename = "scp-from-%s-to-%s.log" % (dst, src)
        error.context("Transfer file from %s to %s" % (dst, src), logging.info)
        remote.scp_between_remotes(dst, src, port, password, password,
                                   username, username, src_path, dst_path,
                                   log_filename=log_filename,
                                   timeout=transfer_timeout)
        error.context("Compare original file and transferred file",
                      logging.info)

        cmd1 = "md5sum /tmp/1"
        cmd2 = "md5sum /tmp/3"
        md5sum1 = session.cmd(cmd1).split()[0]
        md5sum2 = session.cmd(cmd2).split()[0]
        if md5sum1 != md5sum2:
            raise error.TestError("File changed after transfer")

    vm_list = []
    session_list = []
    vms = params["vms"].split()
    timeout = float(params.get("login_timeout", 360))
    mac_ip_filter = params["mac_ip_filter"]
    strict_check = params.get("strick_check", "no")
    host_ip = utils_net.get_ip_address_by_interface(params.get("netdst"))
    host_ip = params.get("srchost", host_ip)
    flood_minutes = float(params["flood_minutes"])
    for vm_name in vms:
        vm = env.get_vm(vm_name)
        vm_list.append(vm)
        session_list.append(vm.wait_for_login(timeout=timeout))

    ip_list = []

    error.context("Check all the nics available or not", logging.info)
    count_nics = len(params.get("nics").split())
    for i in session_list:
        ips = []
        cmd = params.get("net_check_cmd")
        end_time = time.time() + timeout
        while time.time() < end_time:
            status, output = i.get_command_status_output(cmd)
            if status:
                err_msg = "Can not get ip from guest."
                err_msg += " Cmd '%s' fail with output: %s" % (cmd, output)
                logging.error(err_msg)
            ips = re.findall(mac_ip_filter, output, re.S)
            if count_nics == len(ips):
                break
            time.sleep(2)
        else:
            err_log = "Not all nics get ip.  Set '%s' nics." % count_nics
            err_log += " Guest only get '%s' ip(s). " % len(ips)
            err_log += " Command '%s' output in guest:\n%s" % (cmd, output)
            raise error.TestFail(err_log)
        for ip in ips:
            ip_list.append(ip + (i,))
    ip_list_len = len(ip_list)
    # ping and file transfer test
    for src_ip_index in range(ip_list_len):
        error.context("Ping test from guest to host", logging.info)
        src_ip_info = ip_list[src_ip_index]
        ping(src_ip_info[3], src_ip_info[0], host_ip, strict_check,
             flood_minutes)
        error.context("File transfer test between guest and host",
                      logging.info)
        file_transfer(src_ip_info[3], src_ip_info[2], host_ip)
        for dst_ip in ip_list[src_ip_index:]:
            txt = "Ping test between %s and %s" % (src_ip_info[2], dst_ip[2])
            error.context(txt, logging.info)
            ping(src_ip_info[3], src_ip_info[0], dst_ip[2], strict_check,
                 flood_minutes)
            txt = "File transfer test between %s " % src_ip_info[2]
            txt += "and %s" % dst_ip[2]
            error.context(txt, logging.info)
            file_transfer(src_ip_info[3], src_ip_info[2], dst_ip[2])
示例#32
0
def run(test, params, env):
    """
    Test virsh iface-bridge and iface-unbridge commands.

    (1) Bridge an existing network device(iface-bridge).
    (2) Unbridge a network device(iface-unbridge).
    """

    iface_name = params.get("iface_name")
    bridge_name = params.get("bridge_name")
    ping_ip = params.get("ping_ip", "")
    ping_count = int(params.get("ping_count", "3"))
    ping_timeout = int(params.get("ping_timeout", "5"))
    bridge_option = params.get("bridge_option")
    unbridge_option = params.get("unbridge_option")
    bridge_delay = "yes" == params.get("bridge_delay", "no")
    delay_num = params.get("delay_num", "0")
    create_bridge = "yes" == params.get("create_bridge", "yes")
    bridge_status_error = "yes" == params.get("bridge_status_error", "no")
    unbridge_status_error = "yes" == params.get("unbridge_status_error", "no")
    iface_script = NETWORK_SCRIPT + iface_name
    iface_script_bk = os.path.join(test.tmpdir, "iface-%s.bk" % iface_name)
    check_iface = "yes" == params.get("check_iface", "yes")
    if check_iface:
        # Make sure the interface exists
        if not libvirt.check_iface(iface_name, "exists", "--all"):
            test.cancel("Interface '%s' not exists" % iface_name)

        net_iface = utils_net.Interface(name=iface_name)
        iface_is_up = net_iface.is_up()
        iface_ip = net_iface.get_ip()

        # Back up the interface script
        process.run("cp %s %s" % (iface_script, iface_script_bk), shell=True)

    # Make sure the bridge name not exists
    net_bridge = utils_net.Bridge()
    if bridge_name in net_bridge.list_br():
        test.cancel("Bridge '%s' already exists" % bridge_name)

    # Stop NetworkManager service
    try:
        NM = utils_path.find_command("NetworkManager")
    except utils_path.CmdNotFoundError:
        logging.debug("No NetworkManager service.")
        NM = None
    NM_is_running = False
    if NM is not None:
        NM_service = service.Factory.create_service("NetworkManager")
        NM_is_running = NM_service.status()
        if NM_is_running:
            NM_service.stop()

    def unbridge_check():
        """
        Check the result after do unbridge.
        """
        list_option = "--all"
        if libvirt.check_iface(bridge_name, "exists", list_option):
            test.fail("%s is still present." % bridge_name)
        if "no-start" in unbridge_option:
            list_option = "--inactive"
        if not libvirt.check_iface(iface_name, "exists", list_option):
            test.fail("%s is not present." % iface_name)

    if bridge_delay:
        bridge_option += " --delay %s" % delay_num
    # Run test
    try:
        if create_bridge:
            # Create bridge
            result = virsh.iface_bridge(iface_name, bridge_name, bridge_option)
            libvirt.check_exit_status(result, bridge_status_error)
            if not bridge_status_error:
                # Get the new create bridge IP address
                try:
                    br_ip = utils_net.get_ip_address_by_interface(bridge_name)
                except:
                    br_ip = ""
                # check IP of new bridge
                if check_iface and br_ip and br_ip != iface_ip:
                    test.fail("bridge IP(%s) isn't the same as iface IP(%s)." %
                              (br_ip, iface_ip))
                # check the status of STP feature
                if "no-start" not in bridge_option:
                    if "no-stp" not in bridge_option:
                        if "yes" != net_bridge.get_stp_status(bridge_name):
                            test.fail("Fail to enable STP.")
                # Do ping test only bridge has IP address and ping_ip not empty
                if br_ip and ping_ip:
                    if not libvirt.check_iface(bridge_name,
                                               "ping",
                                               ping_ip,
                                               count=ping_count,
                                               timeout=ping_timeout):
                        test.fail("Fail to ping %s from %s." %
                                  (ping_ip, bridge_name))
                else:
                    # Skip ping test
                    logging.debug("Skip ping test as %s has no IP address",
                                  bridge_name)
                list_option = ""
                if "no-start" in bridge_option:
                    list_option = "--inactive"
                if libvirt.check_iface(bridge_name, "exists", list_option):
                    # Unbridge
                    result = virsh.iface_unbridge(bridge_name, unbridge_option)
                    libvirt.check_exit_status(result, unbridge_status_error)
                    if not unbridge_status_error:
                        unbridge_check()
                else:
                    test.fail("%s is not present." % bridge_name)
        else:
            # Unbridge without creating bridge, only for negative test now
            result = virsh.iface_unbridge(bridge_name, unbridge_option)
            libvirt.check_exit_status(result, unbridge_status_error)
            if not unbridge_status_error:
                unbridge_check()
    finally:
        if create_bridge and check_iface:
            if libvirt.check_iface(bridge_name, "exists", "--all"):
                virsh.iface_unbridge(bridge_name)
            if os.path.exists(iface_script_bk):
                process.run("mv %s %s" % (iface_script_bk, iface_script),
                            shell=True)
            if iface_is_up:
                # Need reload script
                process.run("ifdown %s" % iface_name, shell=True)
                process.run("ifup %s" % iface_name, shell=True)
            else:
                net_iface.down()
            # Clear the new create bridge if it exists
            try:
                utils_net.bring_down_ifname(bridge_name)
                process.run("brctl delbr %s" % bridge_name, shell=True)
            except utils_net.TAPBringDownError:
                pass
        if NM_is_running:
            NM_service.start()
示例#33
0
def run(test, params, env):
    """
    Qemu guest irqbalance inactive/active test:
    1) Setup host for sr-iov test.
    2) Boot VM with sr-iov vf/pf assigned and multi vcpu.
    3) Update irqbalance service status in guest. stop/start this server
       according to request.
    4) Get available network interface name in guest.
    5) Start background network stress in guest.
    6) Get irq number assigned to attached vfs/pfs.
    7) Get the cpu number the irq running.
    8) Check specified IRQ count grow on specified cpu.
    9) Repeat step 7 for every 10s.
    10) Balance IRQs generated by vfs/pfs to different vcpus (optional)
       e.g.
       echo 4 > /proc/irq/num/smp_affinity
    11) Repeat step 6, 7
    12) Check that specified IRQ count grow on every cpu. (optional)

    :param test: QEMU test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    """
    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    timeout = int(params.get("login_timeout", 360))
    session = vm.wait_for_login(timeout=timeout)
    irqbalance_check_count = int(params.get("irqbalance_check_count", 36))
    nic_interface_filter = params["nic_interface_filter"]

    error.context("Make sure that guest have at least 2 vCPUs.", logging.info)
    cpu_count = vm.get_cpu_count()
    if cpu_count < 2:
        raise error.TestNAError("Test requires at least 2 vCPUs.")

    msg = "Update irqbalance service status in guest if not match request."
    error.context(msg, logging.info)
    irqbalance_status = params.get("irqbalance_status", "active")
    status = get_guest_service_status(session=session, service="irqbalance")
    service_cmd = ""
    if status == "active" and irqbalance_status == "inactive":
        service_cmd = "service irqbalance stop"
    elif status == "inactive" and irqbalance_status == "active":
        service_cmd = "service irqbalance start"
    if service_cmd:
        status, output = session.cmd_status_output(service_cmd)
        if status:
            msg = "Fail to update irqbalance service status in guest."
            msg += " Command output in guest: %s" % output
            raise error.TestError(msg)

    error.context("Get first network interface name in guest.", logging.info)
    devname = get_first_network_devname(session, nic_interface_filter)

    error.context("Start background network stress in guest.", logging.info)
    host_ip = utils_net.get_ip_address_by_interface(params.get('netdst'))
    ping_cmd = "ping %s  -f -q" % host_ip
    ping_timeout = irqbalance_check_count * 10 + 100
    ping_session = vm.wait_for_login(timeout=timeout)
    bg_stress = utils.InterruptedThread(utils_test.raw_ping,
                                        kwargs={'command': ping_cmd,
                                                'timeout': ping_timeout,
                                                'session': ping_session,
                                                'output_func': None})
    bg_stress.start()
    try:
        error.context("Get irq number assigned to attached VF/PF in guest",
                      logging.info)
        irq_nums_dict = get_guest_irq_info(session, devname, cpu_count)
        if irq_nums_dict:
            irqs = irq_nums_dict.keys()

        msg = "Check specified IRQ count grow on specified cpu."
        error.context(msg, logging.info)
        check_irqbalance(session, devname, cpu_count, irqs)
        irq_cpus_dict = {}
        for irq in irqs:
            cpus = get_irq_smp_affinity(session, irq)
            irq_cpus_dict[irq] = cpus

        if irqbalance_status == "inactive":
            msg = "balance IRQs generated by vfs/pfs to different vcpus."
            error.context(msg, logging.info)
            post_irq_cpus_dict = {}
            for irq in irq_cpus_dict:
                balance_cpu_count = 1
                cpus = []
                for cpu in xrange(cpu_count):
                    if cpu not in irq_cpus_dict[irq]:
                        cpus.append(cpu)
                        if len(cpus) == balance_cpu_count:
                            break
                set_irq_smp_affinity(session, irq, cpus)
                post_irq_cpus_dict[irq] = cpus

            for irq in irqs:
                cpus = get_irq_smp_affinity(session, irq)
                msg = "Fail to balance IRQs generated by vf/pf to different cpu"
                if cpus != post_irq_cpus_dict[irq]:
                    raise error.TestFail(msg)

        msg = "Check specified IRQ count grow on specified cpu."
        error.context(msg, logging.info)
        check_irqbalance(session, devname,
                         cpu_count, irqs,
                         count=irqbalance_check_count)

        if irqbalance_status == "active":
            msg = "Check that specified IRQ count grow on every cpu."
            error.context(msg, logging.info)
            post_irq_nums_dict = get_guest_irq_info(session, devname, cpu_count)

            for irq in irqs:
                if irq not in post_irq_nums_dict.keys():
                    post_irqs = post_irq_nums_dict.keys()
                    msg = "Different irq detected: '%s' and '%s'." % (irqs,
                                                                      post_irqs)
                    raise error.TestError(msg)
                for cpu in xrange(cpu_count):
                    if (int(irq_nums_dict[irq][cpu]) >=
                            int(post_irq_nums_dict[irq][cpu])):
                        msg = "'Cpu%s' did not handle more interrupt" % cpu
                        msg += "for irq '%s'." % irq
                        msg += "IRQ balance information for IRQ '%s'\n" % irq
                        msg += "First time: %s\n" % irq_nums_dict
                        msg += "Just now: %s" % post_irq_nums_dict
                        raise error.TestFail(msg)
    finally:
        if bg_stress.isAlive():
            bg_stress.join(suppress_exception=True)
        else:
            logging.warn("Background stress test already finished")
示例#34
0
def run_netperf_udp(test, params, env):
    """
    Run netperf on server and client side, we need run this case on two
    machines. If dsthost is not set will start netperf server on local
    host and log a error message.:
    1) Start one vm guest os as client.
    2) Start a reference machine (dsthost) as server.
    3) Setup netperf on guest and reference machine (dsthost).
    4) Run netserver on server using control.server.
    5) Run netperf client command in guest several time with different
       message size.
    6) Compare UDP performance to make sure it is acceptable.

    @param test: QEMU test object
    @param params: Dictionary with the test parameters
    @param env: Dictionary with test environment.
    """
    def get_remote_host_session():
        dsthostssh = remote.remote_login("ssh",
                                         dsthost,
                                         22,
                                         "root",
                                         passwd,
                                         "#",
                                         timeout=30)
        if dsthostssh:
            dsthostssh.set_status_test_command("echo $?")
            return dsthostssh
        else:
            return None

    def scp_to_remote(local_path="", remote_path=""):
        remote.scp_to_remote(dsthost, 22, "root", passwd, local_path,
                             remote_path)
        vm.copy_files_to(local_path, remote_path)

    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()

    session = vm.wait_for_login(timeout=int(params.get("login_timeout", 360)))

    dsthost = params.get("dsthost")
    if not dsthost:
        dsthost = utils_net.get_ip_address_by_interface(params.get("netdst"))
        logging.error("dsthost is not set, use localhost ip %s" % dsthost)
    else:
        logging.info("Dest host is %s" % dsthost)
    passwd = params.get("hostpasswd")
    test_timeout = float(params.get("test_timeout", "1200"))

    error.context("Create session connection to remote machine")
    dsthostssh = utils_misc.wait_for(get_remote_host_session, 120, 0, 2)
    if not dsthostssh:
        raise error.TestError("Could not login into remote host %s " % dsthost)

    # Get range of message size.
    message_size_range = params.get("message_size_range")
    message_size = message_size_range.split()
    start_size = int(message_size[0])
    end_size = int(message_size[1])
    step = int(message_size[2])
    m_size = start_size

    error.context("Copy netperf to dsthost and guest vm.")
    netperf_dir = os.path.join(os.environ['AUTODIR'], "tests/netperf2")
    for i in params.get("netperf_files").split():
        scp_to_remote("%s/%s" % (netperf_dir, i), "/tmp/")

    # Setup netpref.
    error.context("Set up netperf on reference machine.", logging.info)
    cmd = params.get("setup_cmd")
    (s, output) = dsthostssh.get_command_status_output(cmd,
                                                       timeout=test_timeout)
    if s != 0:
        raise error.TestError("Fail to setup netperf on reference machine.")
    error.context("Setup netperf on guest os.", logging.info)
    (s, output) = session.get_command_status_output(cmd, timeout=test_timeout)
    if s != 0:
        raise error.TestError("Fail to setup netperf on guest os.")

    # Start netperf server in dsthost.
    cmd = "killall netserver"
    dsthostssh.get_command_status_output(cmd)
    cmd = params.get("netserver_cmd")
    txt = "Run netserver on server (dsthost) using control.server."
    error.context(txt, logging.info)
    (s, output) = dsthostssh.get_command_status_output(cmd)
    if s != 0:
        txt = "Fail to start netperf server on remote machine."
        txt += " Command output: %s" % output
        raise error.TestError(txt)

    throughput = []

    # Run netperf with message size defined in range.
    msg = "Detail result for netperf udp test with different message size.\n"
    while (m_size <= end_size):
        cmd = params.get("netperf_cmd") % (dsthost, m_size)
        txt = "Run netperf client command in guest: %s" % cmd
        error.context(txt, logging.info)
        (s, output) = session.get_command_status_output(cmd)
        if s != 0:
            txt = "Fail to execute netperf client side command in guest."
            txt += " Command output: %s" % output
            raise error.TestError(txt)
        line_tokens = output.splitlines()[6].split()
        throughput.append(float(line_tokens[5]))
        msg += output
        m_size += step
    file(os.path.join(test.debugdir, "udp_results"), "w").write(msg)

    failratio = float(params.get("failratio", 0.3))
    error.context("Compare UDP performance.", logging.info)
    for i in range(len(throughput) - 1):
        if abs(throughput[i] - throughput[i + 1]) > throughput[i] * failratio:
            txt = "The gap between adjacent throughput is greater than"
            txt += "%f." % failratio
            txt += "Please refer to log file for details:\n %s" % msg
            raise error.TestFail(txt)
    logging.info("The UDP performance as measured via netperf is ok.")
    logging.info("Throughput of netperf command: %s" % throughput)
    logging.debug("Output of netperf command:\n %s" % msg)
    error.context("Kill netperf server on server (dsthost).")

    cmd = "killall -9 netserver"
    try:
        dsthostssh.get_command_status_output(cmd)
    except Exception:
        pass