From: Amos Kong <akong@xxxxxxxxxx> KVM guest always pauses on NOSPACE error, this test just repeatedly extend guest disk space and resume guest from paused status. Changes from v1: - Use the most current KVM test API - Use the autotest API for external commands execution - Instead of chaining multiple shell commands as pre and post commands, create proper pre and post scripts for the test, as it is easier to figure out problems - Instead of setting up /dev/loop0 hardcoded by default, find the first available loop device before and use it. Signed-off-by: Amos Kong <akong@xxxxxxxxxx> --- client/tests/kvm/scripts/enospc-post.py | 74 +++++++++++++++++++++++++++++ client/tests/kvm/scripts/enospc-pre.py | 71 +++++++++++++++++++++++++++ client/tests/kvm/tests/enospc.py | 68 ++++++++++++++++++++++++++ client/tests/kvm/tests_base.cfg.sample | 14 +++++ 4 files changed, 227 insertions(+), 0 deletions(-) mode change 100644 => 100755 client/tests/kvm/scripts/bonding_setup.py mode change 100644 => 100755 client/tests/kvm/scripts/check_image.py create mode 100755 client/tests/kvm/scripts/enospc-post.py create mode 100755 client/tests/kvm/scripts/enospc-pre.py create mode 100644 client/tests/kvm/tests/enospc.py diff --git a/client/tests/kvm/scripts/bonding_setup.py b/client/tests/kvm/scripts/bonding_setup.py old mode 100644 new mode 100755 diff --git a/client/tests/kvm/scripts/check_image.py b/client/tests/kvm/scripts/check_image.py old mode 100644 new mode 100755 diff --git a/client/tests/kvm/scripts/enospc-post.py b/client/tests/kvm/scripts/enospc-post.py new file mode 100755 index 0000000..71cc383 --- /dev/null +++ b/client/tests/kvm/scripts/enospc-post.py @@ -0,0 +1,74 @@ +#!/usr/bin/python +""" +Simple script to setup enospc test environment +""" +import os, commands + +class SetupError(Exception): + """ + Simple wrapper for the builtin Exception class. + """ + pass + + +def find_command(cmd): + """ + Searches for a command on common paths, error if it can't find it. + + @param cmd: Command to be found. + """ + if os.path.exists(cmd): + return cmd + for dir in ["/usr/local/sbin", "/usr/local/bin", + "/usr/sbin", "/usr/bin", "/sbin", "/bin"]: + file = os.path.join(dir, cmd) + if os.path.exists(file): + return file + raise ValueError('Missing command: %s' % cmd) + + +def run(cmd, info=None): + """ + Run a command and throw an exception if it fails. + Optionally, you can provide additional contextual info. + + @param cmd: Command string. + @param reason: Optional string that explains the context of the failure. + + @raise: SetupError if command fails. + """ + print "Running '%s'" % cmd + cmd_name = cmd.split(' ')[0] + find_command(cmd_name) + status, output = commands.getstatusoutput(cmd) + if status: + e_msg = ('Command %s failed.\nStatus:%s\nOutput:%s' % + (cmd, status, output)) + if info is not None: + e_msg += '\nAdditional Info:%s' % info + raise SetupError(e_msg) + + return (status, output) + + +if __name__ == "__main__": + qemu_img_binary = os.environ['KVM_TEST_qemu_img_binary'] + if not os.path.isabs(qemu_img_binary): + qemu_img_binary = os.path.join(KVM_TEST_DIR, qemu_img_binary) + if not os.path.exists(qemu_img_binary): + raise SetupError('The qemu-img binary that is supposed to be used ' + '(%s) does not exist. Please verify your ' + 'configuration' % qemu_img_binary) + + run("lvremove -f vgtest") + status, output = run("losetup -a") + loopback_device = None + if output: + for line in output.splitlines(): + device = line.split(":")[0] + if "/tmp/enospc.raw" in line: + loopback_device = device + break + if loopback_device is not None: + run("losetup -d %s" % loopback_device) + run("rm -rf /tmp/enospc.raw /tmp/kvm_autotest_root/images/enospc.qcow2") diff --git a/client/tests/kvm/scripts/enospc-pre.py b/client/tests/kvm/scripts/enospc-pre.py new file mode 100755 index 0000000..e56bdc0 --- /dev/null +++ b/client/tests/kvm/scripts/enospc-pre.py @@ -0,0 +1,71 @@ +#!/usr/bin/python +""" +Simple script to setup enospc test environment +""" +import os, commands + +class SetupError(Exception): + """ + Simple wrapper for the builtin Exception class. + """ + pass + + +def find_command(cmd): + """ + Searches for a command on common paths, error if it can't find it. + + @param cmd: Command to be found. + """ + if os.path.exists(cmd): + return cmd + for dir in ["/usr/local/sbin", "/usr/local/bin", + "/usr/sbin", "/usr/bin", "/sbin", "/bin"]: + file = os.path.join(dir, cmd) + if os.path.exists(file): + return file + raise ValueError('Missing command: %s' % cmd) + + +def run(cmd, info=None): + """ + Run a command and throw an exception if it fails. + Optionally, you can provide additional contextual info. + + @param cmd: Command string. + @param reason: Optional string that explains the context of the failure. + + @raise: SetupError if command fails. + """ + print "Running '%s'" % cmd + cmd_name = cmd.split(' ')[0] + find_command(cmd_name) + status, output = commands.getstatusoutput(cmd) + if status: + e_msg = ('Command %s failed.\nStatus:%s\nOutput:%s' % + (cmd, status, output)) + if info is not None: + e_msg += '\nAdditional Info:%s' % info + raise SetupError(e_msg) + + return (status, output.strip()) + + +if __name__ == "__main__": + qemu_img_binary = os.environ['KVM_TEST_qemu_img_binary'] + if not os.path.isabs(qemu_img_binary): + qemu_img_binary = os.path.join(KVM_TEST_DIR, qemu_img_binary) + if not os.path.exists(qemu_img_binary): + raise SetupError('The qemu-img binary that is supposed to be used ' + '(%s) does not exist. Please verify your ' + 'configuration' % qemu_img_binary) + + run("%s create -f raw /tmp/enospc.raw 10G" % qemu_img_binary) + status, loopback_device = run("losetup -f") + run("losetup -f /tmp/enospc.raw") + run("pvcreate %s" % loopback_device) + run("vgcreate vgtest %s" % loopback_device) + run("lvcreate -L200M -n lvtest vgtest") + run("%s create -f qcow2 /dev/vgtest/lvtest 10G" % qemu_img_binary) + run("ln -s /dev/vgtest/lvtest /tmp/kvm_autotest_root/images/enospc.qcow2") + diff --git a/client/tests/kvm/tests/enospc.py b/client/tests/kvm/tests/enospc.py new file mode 100644 index 0000000..21ea24e --- /dev/null +++ b/client/tests/kvm/tests/enospc.py @@ -0,0 +1,68 @@ +import logging, commands, time, os +from autotest_lib.client.common_lib import error +from autotest_lib.client.bin import utils +import kvm_test_utils + + +def run_enospc(test, params, env): + """ + ENOSPC test + + 1) Create a virtual disk on lvm + 2) Boot up guest with two disks + 3) Continually write data to second disk + 4) Check images and extend second disk when no space + 5) Continue paused guest + 6) Repeat step 3~5 several times + + @param test: KVM 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() + login_timeout = int(params.get("login_timeout", 360)) + session_serial = vm.wait_for_serial_login(timeout=login_timeout) + + drive_format = params.get("drive_format") + if drive_format == "virtio": + devname = "/dev/vdb" + elif drive_format == "ide": + devname = "/dev/hdb" + elif drive_format == "scsi": + devname = "/dev/sdb" + cmd = params.get("background_cmd") + cmd %= devname + logging.info("Sending background cmd '%s'", cmd) + session_serial.sendline(cmd) + + iterations = int(params.get("repeat_time", 40)) + i = 0 + pause_n = 0 + while i < iterations: + status = vm.monitor.cmd("info status") + logging.debug(status) + if "paused" in status: + pause_n += 1 + logging.info("Checking all images in use by the VM") + script_path = os.path.join(test.bindir, "scripts/check_image.py") + try: + cmd_result = utils.run('python %s' % script_path) + except error.CmdError, e: + logging.debug(e.result_obj.stdout) + logging.info("Guest paused, extending Logical Volume size") + try: + cmd_result = utils.run("lvextend -L +200M /dev/vgtest/lvtest") + except error.CmdError, e: + logging.debug(e.result_obj.stdout) + vm.monitor.cmd("cont") + time.sleep(10) + i += 1 + + if pause_n == 0: + raise error.TestFail("Guest didn't pause during loop") + else: + logging.info("Guest paused %s times from %s iterations", + pause_n, iterations) + + logging.info("Final %s" % vm.monitor.cmd("info status")) diff --git a/client/tests/kvm/tests_base.cfg.sample b/client/tests/kvm/tests_base.cfg.sample index 97db3e7..2157a15 100644 --- a/client/tests/kvm/tests_base.cfg.sample +++ b/client/tests/kvm/tests_base.cfg.sample @@ -591,6 +591,20 @@ variants: - fmt_raw: image_format_stg = raw + - enospc: + type = enospc + images += " stg" + drive_werror = stop + drive_cache = none + image_name_stg = enospc + image_format_stg = qcow2 + image_boot_stg = no + image_snapshot_stg = no + background_cmd = "nohup dd if=/dev/zero of=%s bs=1024 &" + pre_command += "qemu-img create -f raw /tmp/enospc.raw 10G && losetup /dev/loop0 /tmp/enospc.raw && pvcreate /dev/loop0 && vgcreate vgtest /dev/loop0 && lvcreate -L200M -n lvtest vgtest && qemu-img create -f qcow2 /dev/vgtest/lvtest 10G && ln -s /dev/vgtest/lvtest /tmp/kvm_autotest_root/images/enospc.qcow2;" + post_command += "lvremove -f vgtest; losetup -d /dev/loop0; rm -rf /tmp/enospc.raw /tmp/kvm_autotest_root/images/enospc.qcow2;" + kill_vm = yes + - qmp_basic: install setup unattended_install.cdrom type = qmp_basic -- 1.7.3.4 -- 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