KVM test: Add a subtest iofuzz
PATCH 1/1 KVM test: Add a subtest iofuzz
The design of iofuzz is simple: it just generate random I/O port activity inside the virtual machine. The correctness of the device emulation may be verified through this test.
As the instrcutions are randomly generated, guest may enter the wrong state. The test solve this issue by detect the hang and restart the virtual machine.
The test duration could also be adjusted through the "fuzz_count". And the parameter "skip_devices" is used to specified the devices which should not be used to do the fuzzing.
For current version, every activity were logged and the commnad was sent through a seesion between host and guest. Through this method may slow down the whole test but it works well. The enumeration was done through /proc/ioports and the scenario of avtivity is not aggressive.
Suggestions are welcomed.
--- client/tests/kvm/tests/iofuzz.py | 97 ++++++++++++++++++++++++++++++++ client/tests/kvm/tests_base.cfg.sample | 2 + 2 files changed, 99 insertions(+), 0 deletions(-) create mode 100644 client/tests/kvm/tests/iofuzz.py
client/tests/kvm/tests/iofuzz.py new file +97 -0
@@ -0,0 +1,97 @@ +import logging, time, re, random +from autotest_lib.client.common_lib import error +import kvm_subprocess, kvm_test_utils, kvm_utils + + +def run_iofuzz(test, params, env): + """ + KVM iofuzz test: + 1) Log into a guest + + @param test: kvm test object + @param params: Dictionary with the test parameters + @param env: Dictionary with test environment. + """ + vm = kvm_test_utils.get_living_vm(env, params.get("main_vm")) + session = kvm_test_utils.wait_for_login(vm, 0, + float(params.get("boot_timeout", 240)), + 0, 2) + + def outb(session, port, data): + logging.debug("outb(0x%x,0x%x)" % (port, data)) + outb_cmd = "echo -e '\\%s' | dd of=/dev/port seek=%d bs=1 count=1" % \ + (oct(data), port) + s, o = session.get_command_status_output(outb_cmd) + if s != 0: + logging.debug("None zero value returned") + + def inb(session, port): + logging.debug("inb(0x%x)" % port) + inb_cmd = "dd if=/dev/port seek=%d of=/dev/null bs=1 count=1" % port + s, o = session.get_command_status_output(inb_cmd) + if s != 0: + logging.debug("None zero value returned") + + def fuzz(session, inst_list): + for (op, operand) in inst_list: + if op == "read": + inb(session, operand[0]) + elif op =="write": + outb(session, operand[0], operand[1]) + else: + raise error.TestError("Unknown command %s" % op) + + if not session.is_responsive(): + logging.debug("Session is not responsive") + if vm.process.is_alive(): + logging.debug("VM is alive, try to re-login") + try: + session = kvm_test_utils.wait_for_login(vm, 0, 10, 0, 2) + except: + logging.debug("Could not re-login, reboot the guest") + session = kvm_test_utils.reboot(vm, session, + method = "system_reset") + else: + raise error.TestFail("VM have quit abnormally") + try: + ports = {} + ran = random.SystemRandom() + + logging.info("Enumerate the device through /proc/ioports") + ioports = session.get_command_output("cat /proc/ioports") + logging.debug(ioports) + devices = re.findall("(\w+)-(\w+)\ : (.*)", ioports) + + skip_devices = params.get("skip_devices","") + fuzz_count = int(params.get("fuzz_count", 10)) + + for (beg, end, name) in devices: + ports[(int(beg, base=16), int(end, base=16))] = name.strip() + + for (beg, end) in ports.keys(): + + name = ports[(beg, end)] + if name in skip_devices: + logging.info("Skipping %s" % name) + continue + + logging.info("Fuzzing %s at 0x%x-0x%x" % (name, beg, end)) + inst = [] + + # Read all ports + for port in range(beg, end+1): + inst.append(("read", [port])) + + # Outb with zero + for port in range(beg, end+1): + inst.append(("write", [port, 0])) + pass + + # Random fuzzing + for seq in range(fuzz_count * (end-beg+1)): + inst.append(("write", [ran.randint(beg, end), ran.randint(0,255)])) + + fuzz(session, inst) + + finally: + session.close()
client/tests/kvm/tests_base.cfg.sample +2 -0
@@ -294,6 +294,8 @@ variants: ksm_mode = "serial" - ksm_parallel: ksm_mode = "parallel" + - iofuzz: + type = iofuzz # system_powerdown, system_reset and shutdown *must* be the last ones # defined (in this order), since the effect of such tests can leave
Quoted 12 lines · Jason Wang
The design of iofuzz is simple: it just generate random I/O port activity inside the virtual machine. The correctness of the device emulation may be verified through this test.
As the instrcutions are randomly generated, guest may enter the wrong state. The test solve this issue by detect the hang and restart the virtual machine.
The test duration could also be adjusted through the "
fuzz_count". And the parameter "skip_devices" is used to specified the devices which should not be used to do the fuzzing.
Quoted 6 lines
For current version, every activity were logged and the commnad was sent through a seesion between host and guest. Through this method may slow down the whole test but it works well. The enumeration was done through
/proc/ioportsand the scenario of avtivity is not aggressive.Suggestions are welcomed.
Hi Jason, nice test! I have made some little changes, re-submitted and will commit. Thanks!
Quoted 129 lines
Signed-off-by Jason Wang <[email protected]>---
client/tests/kvm/tests/iofuzz.py | 97 ++++++++++++++++++++++++++++++++ client/tests/kvm/tests_base.cfg.sample | 2 +2 files changed, 99 insertions(+), 0 deletions(-)create mode 100644
client/tests/kvm/tests/iofuzz.pyclient/tests/kvm/tests/iofuzz.py new file +97
-0@@ -0,0 +1,97 @@ +import logging, time, re, random +from autotest_lib.client.common_lib import error +import kvm_subprocess, kvm_test_utils, kvm_utils + + +def run_iofuzz(test, params, env): + """ + KVM iofuzz test: + 1) Log into a guest + + @param test: kvm test object + @param params: Dictionary with the test parameters + @param env: Dictionary with test environment. + """ + vm = kvm_test_utils.get_living_vm(env, params.get("main_vm")) + session = kvm_test_utils.wait_for_login(vm, 0, + float(params.get("boot_timeout", 240)), + 0, 2) + + def outb(session, port, data): + logging.debug("outb(0x%x,0x%x)" % (port, data)) + outb_cmd = "echo -e '\\%s' | dd of=/dev/port seek=%d bs=1 count=1" % \ + (oct(data), port) + s, o = session.get_command_status_output(outb_cmd) + if s != 0: + logging.debug("None zero value returned") + + def inb(session, port): + logging.debug("inb(0x%x)" % port) + inb_cmd = "dd if=/dev/port seek=%d of=/dev/null bs=1 count=1" % port + s, o = session.get_command_status_output(inb_cmd) + if s != 0: + logging.debug("None zero value returned") + + def fuzz(session, inst_list): + for (op, operand) in inst_list: + if op == "read": + inb(session, operand[0]) + elif op =="write": + outb(session, operand[0], operand[1]) + else: + raise error.TestError("Unknown command %s" % op) + + if not session.is_responsive(): + logging.debug("Session is not responsive") + if vm.process.is_alive(): + logging.debug("VM is alive, try to re-login") + try: + session = kvm_test_utils.wait_for_login(vm, 0, 10, 0, 2) + except: + logging.debug("Could not re-login, reboot the guest") + session = kvm_test_utils.reboot(vm, session, + method = "system_reset") + else: + raise error.TestFail("VM have quit abnormally") + try: + ports = {} + ran = random.SystemRandom() + + logging.info("Enumerate the device through /proc/ioports") + ioports = session.get_command_output("cat /proc/ioports") + logging.debug(ioports) + devices = re.findall("(\w+)-(\w+)\ : (.*)", ioports) + + skip_devices = params.get("skip_devices","") + fuzz_count = int(params.get("fuzz_count", 10)) + + for (beg, end, name) in devices: + ports[(int(beg, base=16), int(end, base=16))] = name.strip() + + for (beg, end) in ports.keys(): + + name = ports[(beg, end)] + if name in skip_devices: + logging.info("Skipping %s" % name) + continue + + logging.info("Fuzzing %s at 0x%x-0x%x" % (name, beg, end)) + inst = [] + + # Read all ports + for port in range(beg, end+1): + inst.append(("read", [port])) + + # Outb with zero + for port in range(beg, end+1): + inst.append(("write", [port, 0])) + pass + + # Random fuzzing + for seq in range(fuzz_count * (end-beg+1)): + inst.append(("write", [ran.randint(beg, end), ran.randint(0,255)])) + + fuzz(session, inst) + + finally: + session.close()client/tests/kvm/tests_base.cfg.sample +0
-0@@ -294,6 +294,8 @@ variants:
ksm_mode= "serial"
-ksm_parallel:
ksm_mode= "parallel"
+ - iofuzz:
+ type = iofuzz#
system_powerdown,system_resetand shutdown *must* be the last ones# defined (in this order), since the effect of such tests can leave_______________________________________________
Autotest mailing list
[email protected]
http://test.kernel.org/cgi-bin/mailman/listinfo/autotest
Signature · 1 line
Lucas