----- Original Message ----- > 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 v2: > - Oops! Forgot to update tests_base.cfg.sample > > 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> Thank you, Lucas I've retested this patch, it's ok. BTW, hi Kevin, when I check the images during this test, got the following output, is it harmful? Leaked cluster 60796 refcount=1 reference=0 Leaked cluster 60797 refcount=1 reference=0 Leaked cluster 60798 refcount=1 reference=0 Leaked cluster 60799 refcount=1 reference=0 Leaked cluster 60800 refcount=1 reference=0 Leaked cluster 60801 refcount=1 reference=0 Leaked cluster 60802 refcount=1 reference=0 Leaked cluster 60803 refcount=1 reference=0 Leaked cluster 60804 refcount=1 reference=0 Leaked cluster 60805 refcount=1 reference=0 Leaked cluster 60806 refcount=1 reference=0 Leaked cluster 60807 refcount=1 reference=0 Leaked cluster 63982 refcount=1 reference=0 Leaked cluster 63983 refcount=1 reference=0 Leaked cluster 63984 refcount=1 reference=0 Leaked cluster 63985 refcount=1 reference=0 Leaked cluster 63986 refcount=1 reference=0 Leaked cluster 63987 refcount=1 reference=0 Leaked cluster 63988 refcount=1 reference=0 Leaked cluster 63989 refcount=1 reference=0 Leaked cluster 63990 refcount=1 reference=0 Leaked cluster 63991 refcount=1 reference=0 Leaked cluster 63992 refcount=1 reference=0 Leaked cluster 63993 refcount=1 reference=0 Leaked cluster 63994 refcount=1 reference=0 Leaked cluster 63995 refcount=1 reference=0 Leaked cluster 63996 refcount=1 reference=0 Leaked cluster 63997 refcount=1 reference=0 Leaked cluster 63998 refcount=1 reference=0 Leaked cluster 63999 refcount=1 reference=0 867 leaked clusters were found on the image. This means waste of disk space, but no harm to data. > --- > 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..978a440 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 += " scripts/enospc-pre.py;" > + post_command += " scripts/enospc-post.py;" > + 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 -- 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