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. Signed-off-by: Jason Wang <jasowang@xxxxxxxxxx> --- 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 diff --git a/client/tests/kvm/tests/iofuzz.py b/client/tests/kvm/tests/iofuzz.py new file mode 100644 index 0000000..c2f22af --- /dev/null +++ b/client/tests/kvm/tests/iofuzz.py @@ -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() diff --git a/client/tests/kvm/tests_base.cfg.sample b/client/tests/kvm/tests_base.cfg.sample index d162cf8..01080bb 100644 --- a/client/tests/kvm/tests_base.cfg.sample +++ b/client/tests/kvm/tests_base.cfg.sample @@ -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 -- 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