On Tue, Aug 3, 2010 at 3:10 AM, Lucas Meneghel Rodrigues <lmr@xxxxxxxxxx> wrote: > On Tue, 2010-07-20 at 09:36 +0800, Amos Kong wrote: >> The latest case contains TX/RX/SG/TSO/GSO/GRO/LRO test. RTL8139 NIC doesn't >> support TSO, LRO, it's too old, so drop offload test from rtl8139. LRO, GRO >> are only supported by latest kernel, virtio nic doesn't support receive >> offloading function. >> Initialize the callbacks first and execute all the sub tests one by one, all >> the result will be check at the end. >> When execute this test, vhost should be enabled, then most of new feature can >> be used. Vhost doestn't support VIRTIO_NET_F_MRG_RXBUF, so do not check large >> packets in received offload test. >> Transfer files by scp between host and guest, match new opened TCP port by >> netstat. Capture the packages info by tcpdump, it contains package length. > > This test is heavily dependent on ethtool, so we need to make sure the > package is going to be installed on linux guests. The default package > selection for Fedora 13 does not include it for example. So, we need to > modify linux guest kickstarts/XMLs to add ethtool to the default package > selection. OK. >> Signed-off-by: Amos Kong <akong@xxxxxxxxxx> >> --- >> 0 files changed, 0 insertions(+), 0 deletions(-) >> >> diff --git a/client/tests/kvm/tests/ethtool.py b/client/tests/kvm/tests/ethtool.py >> new file mode 100644 >> index 0000000..7274eae >> --- /dev/null >> +++ b/client/tests/kvm/tests/ethtool.py >> @@ -0,0 +1,205 @@ >> +import time, os, logging, commands, re >> +from autotest_lib.client.common_lib import error >> +from autotest_lib.client.bin import utils >> +import kvm_test_utils, kvm_utils, kvm_net_utils >> + >> +def run_ethtool(test, params, env): >> + """ >> + Test offload functions of ethernet device by ethtool >> + >> + 1) Log into a guest >> + 2) Initialize the callback of sub functions >> + 3) Enable/disable sub function of NIC >> + 4) Execute callback function >> + 5) Check the return value >> + 6) Restore original configuration >> + >> + @param test: Kvm test object >> + @param params: Dictionary with the test parameters. >> + @param env: Dictionary with test environment. >> + """ >> + def ethtool_get(type): >> + feature_pattern = { >> + 'tx': 'tx.*checksumming', >> + 'rx': 'rx.*checksumming', >> + 'sg': 'scatter.*gather', >> + 'tso': 'tcp.*segmentation.*offload', >> + 'gso': 'generic.*segmentation.*offload', >> + 'gro': 'generic.*receive.*offload', >> + 'lro': 'large.*receive.*offload', >> + } >> + s, o = session.get_command_status_output("ethtool -k %s" % ethname) >> + try: >> + return re.findall("%s: (.*)" % feature_pattern.get(type), o)[0] >> + except IndexError: >> + logging.debug("Could not get %s status" % type) >> + >> + def ethtool_set(type, status): >> + """ >> + Set ethernet device offload status >> + >> + @param type: Offload type name >> + @param status: New status will be changed to >> + """ >> + logging.info("Try to set %s %s" % (type, status)) >> + if status not in ["off", "on"]: >> + return False >> + cmd = "ethtool -K %s %s %s" % (ethname, type, status) >> + if ethtool_get(type) != status: >> + return session.get_command_status(cmd) == 0 >> + if ethtool_get(type) != status: >> + logging.error("Fail to set %s %s" % (type, status)) >> + return False >> + return True >> + >> + def ethtool_save_params(): >> + logging.info("Save ethtool configuration") >> + for i in supported_features: >> + feature_status[i] = ethtool_get(i) >> + >> + def ethtool_restore_params(): >> + logging.info("Restore ethtool configuration") >> + for i in supported_features: >> + ethtool_set(i, feature_status[i]) >> + >> + def compare_md5sum(name): >> + logging.info("Compare md5sum of the files on guest and host") >> + host_result = utils.hash_file(name, method="md5") >> + try: >> + o = session.get_command_output("md5sum %s" % name) >> + guest_result = re.findall("\w+", o)[0] >> + except IndexError: >> + logging.error("Could not get file md5sum in guest") >> + return False >> + logging.debug("md5sum: guest(%s), host(%s)" % (guest_result, >> + host_result)) >> + return guest_result == host_result >> + >> + def transfer_file(src="guest"): >> + """ >> + Transfer file by scp, use tcpdump to capture packets, then check the >> + return string. >> + >> + @param src: Source host of transfer file >> + @return: Tuple (status, error msg/tcpdump result) >> + """ >> + session2.get_command_status("rm -rf %s" % filename) >> + dd_cmd = "dd if=/dev/urandom of=%s bs=1M count=%s" % (filename, >> + params.get("filesize")) >> + logging.info("Creat file in source host, cmd: %s" % dd_cmd) >> + tcpdump_cmd = "tcpdump -lep -s 0 tcp -vv port ssh" >> + if src == "guest": >> + s = session.get_command_status(dd_cmd, timeout=360) >> + tcpdump_cmd += " and src %s" % guest_ip >> + copy_files_fun = vm.copy_files_from >> + else: >> + s, o = commands.getstatusoutput(dd_cmd) >> + tcpdump_cmd += " and dst %s" % guest_ip >> + copy_files_fun = vm.copy_files_to >> + if s != 0: >> + return (False, "Fail to create file by dd, cmd: %s" % dd_cmd) >> + >> + # only capture the new tcp port after offload setup >> + original_tcp_ports = re.findall("tcp.*:(\d+).*%s" % guest_ip, >> + commands.getoutput("/bin/netstat -nap")) >> + for i in original_tcp_ports: >> + tcpdump_cmd += " and not port %s" % i >> + logging.debug("Listen by command: %s" % tcpdump_cmd) >> + session2.sendline(tcpdump_cmd) >> + if not kvm_utils.wait_for(lambda: session.get_command_status( >> + "pgrep tcpdump") == 0, 30): >> + return (False, "Tcpdump process wasn't launched") >> + >> + logging.info("Start to transfer file") >> + if not copy_files_fun(filename, filename): >> + return (False, "Child process transfer file failed") >> + logging.info("Transfer file completed") >> + if session.get_command_status("killall tcpdump") != 0: >> + return (False, "Could not kill all tcpdump process") >> + s, tcpdump_string = session2.read_up_to_prompt(timeout=60) >> + if not s: >> + return (False, "Fail to read tcpdump's output") >> + >> + if not compare_md5sum(filename): >> + return (False, "Files' md5sum mismatched") >> + return (True, tcpdump_string) >> + >> + def tx_callback(status="on"): >> + s, o = transfer_file(src="guest") >> + if not s: >> + logging.error(o) >> + return False >> + return True >> + >> + def rx_callback(status="on"): >> + s, o = transfer_file(src="host") >> + if not s: >> + logging.error(o) >> + return False >> + return True >> + >> + def so_callback(status="on"): >> + s, o = transfer_file(src="guest") >> + if not s: >> + logging.error(o) >> + return False >> + logging.info("Check if contained large frame") >> + # mtu: default IPv4 MTU is 1500 Bytes, ethernet header is 14 Bytes >> + return (status == "on") ^ (len([i for i in re.findall( >> + "length (\d*):", o) if int(i) > mtu]) == 0) >> + >> + def ro_callback(status="on"): >> + s, o = transfer_file(src="host") >> + if not s: >> + logging.error(o) >> + return False >> + return True >> + >> + vm = kvm_test_utils.get_living_vm(env, params.get("main_vm")) >> + session = kvm_test_utils.wait_for_login(vm, >> + timeout=int(params.get("login_timeout", 360))) >> + session2 = kvm_test_utils.wait_for_login(vm, >> + timeout=int(params.get("login_timeout", 360))) >> + mtu = 1514 >> + feature_status = {} >> + filename = "/tmp/ethtool.dd" >> + guest_ip = vm.get_address() >> + ethname = kvm_net_utils.get_linux_ifname(session, vm.get_macaddr(0)) >> + supported_features = params.get("supported_features").split() > > ^ We could use ethtool to query the machine for the supported features, > and if it's not possible to do that (virtio_net), we resort to > supported_feature being set on the config file, what do you think? How to query which offload features are supported by nic dev by ethtool ? '# ethtool -k eth0' can only list the function status. I try to enable all the function, by this order 'tx rx gs tso ufo gso gro lro', if some of them failed, it should not be supported ? This method is not dependable in test environment. >> + test_matrix = { >> + # type:(callback, (dependence), (exclude) >> + "tx": (tx_callback, (), ()), >> + "rx": (rx_callback, (), ()), >> + "sg": (tx_callback, ("tx",), ()), >> + "tso": (so_callback, ("tx", "sg",), ("gso",)), >> + "gso": (so_callback, (), ("tso",)), >> + "gro": (ro_callback, ("rx",), ("lro",)), >> + "lro": (rx_callback, (), ("gro",)), >> + } >> + ethtool_save_params() >> + success = True >> + try: >> + for type in supported_features: >> + callback = test_matrix[type][0] >> + for i in test_matrix[type][2]: >> + if not ethtool_set(i, "off"): >> + logging.error("Fail to disable %s" % i) >> + success = False >> + for i in [f for f in test_matrix[type][1]] + [type]: >> + if not ethtool_set(i, "on"): >> + logging.error("Fail to enable %s" % i) >> + success = False >> + if not callback(): >> + raise error.TestFail("Test failed, %s: on" % type) >> + >> + if not ethtool_set(type, "off"): >> + logging.error("Fail to disable %s" % type) >> + success = False >> + if not callback(status="off"): >> + raise error.TestFail("Test failed, %s: off" % type) >> + if not success: >> + raise error.TestError("Enable/disable offload function fail") >> + finally: >> + ethtool_restore_params() >> + session.close() >> + session2.close() >> diff --git a/client/tests/kvm/tests_base.cfg.sample b/client/tests/kvm/tests_base.cfg.sample >> index b25980e..6f0e295 100644 >> --- a/client/tests/kvm/tests_base.cfg.sample >> +++ b/client/tests/kvm/tests_base.cfg.sample >> @@ -412,6 +412,19 @@ variants: >> netperf_cmd = %s/netperf-2.4.5/src/netperf -t %s -H %s -l 60 -- -m 1 >> protocols = "TCP_STREAM TCP_MAERTS TCP_RR TCP_CRR UDP_RR TCP_SENDFILE UDP_STREAM" >> >> + - ethtool: install setup unattended_install.cdrom >> + type = ethtool >> + filesize = 512 >> + nic_mode = tap >> + variants: >> + # gso gro lro is only supported by latest kernel >> + - nic_virtio: >> + pci_model = virtio >> + supported_features = "tx sg tso gso" >> + - nic_e1000: >> + pci_model = e1000 >> + supported_features = "tx rx sg tso gso gro lro" >> + >> - physical_resources_check: install setup unattended_install.cdrom >> type = physical_resources_check >> catch_uuid_cmd = dmidecode | awk -F: '/UUID/ {print $2}' >> @@ -1088,7 +1101,7 @@ variants: >> >> # Windows section >> - @Windows: >> - no autotest linux_s3 vlan ioquit unattended_install.(url|nfs|remote_ks) jumbo file_transfer nicdriver_unload nic_promisc multicast mac_change >> + no autotest linux_s3 vlan ioquit unattended_install.(url|nfs|remote_ks) jumbo file_transfer nicdriver_unload nic_promisc multicast mac_change ethtool >> shutdown_command = shutdown /s /f /t 0 >> reboot_command = shutdown /r /f /t 0 >> status_test_command = echo %errorlevel% -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html