[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] Re: [Autotest] [RFC PATCH 14/14] KVM-test: Add subtest of t
From: |
Amos Kong |
Subject: |
[Qemu-devel] Re: [Autotest] [RFC PATCH 14/14] KVM-test: Add subtest of testing offload by ethtool |
Date: |
Tue, 10 Aug 2010 15:07:31 +0800 |
On Tue, Aug 3, 2010 at 3:10 AM, Lucas Meneghel Rodrigues <address@hidden> 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 <address@hidden>
>> ---
>> 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
>> +
>> + address@hidden test: Kvm test object
>> + address@hidden params: Dictionary with the test parameters.
>> + address@hidden 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
>> +
>> + address@hidden type: Offload type name
>> + address@hidden 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.
>> +
>> + address@hidden src: Source host of transfer file
>> + address@hidden: 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%