From patchwork Sat Jan 22 01:30:49 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lucas Meneghel Rodrigues X-Patchwork-Id: 497511 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p0M1VEZ7022962 for ; Sat, 22 Jan 2011 01:31:16 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753388Ab1AVBbL (ORCPT ); Fri, 21 Jan 2011 20:31:11 -0500 Received: from mx1.redhat.com ([209.132.183.28]:44458 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750791Ab1AVBbD (ORCPT ); Fri, 21 Jan 2011 20:31:03 -0500 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id p0M1V231006332 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 21 Jan 2011 20:31:02 -0500 Received: from freedom.redhat.com (vpn-11-112.rdu.redhat.com [10.11.11.112]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id p0M1Up5P007822; Fri, 21 Jan 2011 20:31:00 -0500 From: Lucas Meneghel Rodrigues To: autotest@test.kernel.org Cc: kvm@vger.kernel.org, Lucas Meneghel Rodrigues Subject: [PATCH 5/6] KVM test: Turn enospc test pre/post actions into infrastructure Date: Fri, 21 Jan 2011 23:30:49 -0200 Message-Id: <1295659850-29609-5-git-send-email-lmr@redhat.com> In-Reply-To: <1295659850-29609-1-git-send-email-lmr@redhat.com> References: <1295659850-29609-1-git-send-email-lmr@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.11 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Sat, 22 Jan 2011 01:31:16 +0000 (UTC) diff --git a/client/tests/kvm/kvm_preprocessing.py b/client/tests/kvm/kvm_preprocessing.py index 081a13f..2713805 100644 --- a/client/tests/kvm/kvm_preprocessing.py +++ b/client/tests/kvm/kvm_preprocessing.py @@ -262,6 +262,10 @@ def preprocess(test, params, env): u = test_setup.UnattendedInstallConfig(test, params) u.setup() + if params.get("type") == "enospc": + e = test_setup.EnospcConfig(test, params) + e.setup() + # Execute any pre_commands if params.get("pre_command"): process_command(test, params, env, params.get("pre_command"), @@ -362,6 +366,10 @@ def postprocess(test, params, env): h = kvm_utils.HugePageConfig(params) h.cleanup() + if params.get("type") == "enospc": + e = test_setup.EnospcConfig(test, params) + e.cleanup() + # Execute any post_commands if params.get("post_command"): process_command(test, params, env, params.get("post_command"), diff --git a/client/tests/kvm/test_setup.py b/client/tests/kvm/test_setup.py index b17c473..e906e18 100644 --- a/client/tests/kvm/test_setup.py +++ b/client/tests/kvm/test_setup.py @@ -2,7 +2,7 @@ Library to perform pre/post test setup for KVM autotest. """ import os, sys, shutil, tempfile, re, ConfigParser, glob, inspect, commands -import logging +import logging, time from autotest_lib.client.common_lib import error from autotest_lib.client.bin import utils @@ -42,6 +42,19 @@ def clean_old_image(image): os.remove(image) +def display_attributes(instance): + """ + Inspects a given class instance attributes and displays them, convenient + for debugging. + """ + logging.debug("Attributes set:") + for member in inspect.getmembers(instance): + name, value = member + attribute = getattr(instance, name) + if not (name.startswith("__") or callable(attribute) or not value): + logging.debug(" %s: %s", name, value) + + class Disk(object): """ Abstract class for Disk objects, with the common methods implemented. @@ -472,13 +485,7 @@ class UnattendedInstallConfig(object): Uses an appropriate strategy according to each install model. """ logging.info("Starting unattended install setup") - - logging.debug("Variables set:") - for member in inspect.getmembers(self): - name, value = member - attribute = getattr(self, name) - if not (name.startswith("__") or callable(attribute) or not value): - logging.debug(" %s: %s", name, value) + display_attributes(self) if self.unattended_file and (self.floppy or self.cdrom_unattended): self.setup_boot_disk() @@ -593,3 +600,96 @@ class HugePageConfig(object): return utils.system("echo 0 > %s" % self.kernel_hp_file) logging.debug("Hugepage memory successfuly dealocated") + + +class EnospcConfig(object): + """ + Performs setup for the test enospc. This is a borg class, similar to a + singleton. The idea is to keep state in memory for when we call cleanup() + on postprocessing. + """ + __shared_state = {} + def __init__(self, test, params): + self.__dict__ = self.__shared_state + root_dir = test.bindir + self.tmpdir = test.tmpdir + self.qemu_img_binary = params.get('qemu_img_binary') + if not os.path.isfile(self.qemu_img_binary): + self.qemu_img_binary = os.path.join(root_dir, + self.qemu_img_binary) + self.raw_file_path = os.path.join(self.tmpdir, 'enospc.raw') + # Here we're trying to choose fairly explanatory names so it's less + # likely that we run in conflict with other devices in the system + self.vgtest_name = params.get("vgtest_name") + self.lvtest_name = params.get("lvtest_name") + self.lvtest_device = "/dev/%s/%s" % (self.vgtest_name, self.lvtest_name) + image_dir = os.path.dirname(params.get("image_name")) + self.qcow_file_path = os.path.join(image_dir, 'enospc.qcow2') + try: + getattr(self, 'loopback') + except AttributeError: + self.loopback = '' + + + @error.context_aware + def setup(self): + logging.debug("Starting enospc setup") + error.context("performing enospc setup") + display_attributes(self) + # Double check if there aren't any leftovers + self.cleanup() + try: + utils.run("%s create -f raw %s 10G" % + (self.qemu_img_binary, self.raw_file_path)) + # Associate a loopback device with the raw file. + # Subject to race conditions, that's why try here to associate + # it with the raw file as quickly as possible + l_result = utils.run("losetup -f") + utils.run("losetup -f %s" % self.raw_file_path) + self.loopback = l_result.stdout.strip() + # Add the loopback device configured to the list of pvs + # recognized by LVM + utils.run("pvcreate %s" % self.loopback) + utils.run("vgcreate %s %s" % (self.vgtest_name, self.loopback)) + # Create an lv inside the vg with starting size of 200M + utils.run("lvcreate -L 200M -n %s %s" % + (self.lvtest_name, self.vgtest_name)) + # Create a 10GB qcow2 image in the logical volume + utils.run("%s create -f qcow2 %s 10G" % + (self.qemu_img_binary, self.lvtest_device)) + # Let's symlink the logical volume with the image name that autotest + # expects this device to have + os.symlink(self.lvtest_device, self.qcow_file_path) + except Exception, e: + self.cleanup() + raise + + @error.context_aware + def cleanup(self): + error.context("performing enospc cleanup") + if os.path.isfile(self.lvtest_device): + utils.run("fuser -k %s" % self.lvtest_device) + time.sleep(2) + l_result = utils.run("lvdisplay") + # Let's remove all volumes inside the volume group created + if self.lvtest_name in l_result.stdout: + utils.run("lvremove -f %s" % self.lvtest_device) + # Now, removing the volume group itself + v_result = utils.run("vgdisplay") + if self.vgtest_name in v_result.stdout: + utils.run("vgremove -f %s" % self.vgtest_name) + # Now, if we can, let's remove the physical volume from lvm list + if self.loopback: + p_result = utils.run("pvdisplay") + if self.loopback in p_result.stdout: + utils.run("pvremove -f %s" % self.loopback) + l_result = utils.run('losetup -a') + if self.loopback and (self.loopback in l_result.stdout): + try: + utils.run("losetup -d %s" % self.loopback) + except error.CmdError: + logging.error("Failed to liberate loopback %s", self.loopback) + if os.path.islink(self.qcow_file_path): + os.remove(self.qcow_file_path) + if os.path.isfile(self.raw_file_path): + os.remove(self.raw_file_path) diff --git a/client/tests/kvm/tests/enospc.py b/client/tests/kvm/tests/enospc.py index 6a149f9..3868cc4 100644 --- a/client/tests/kvm/tests/enospc.py +++ b/client/tests/kvm/tests/enospc.py @@ -24,6 +24,10 @@ def run_enospc(test, params, env): login_timeout = int(params.get("login_timeout", 360)) session_serial = vm.wait_for_serial_login(timeout=login_timeout) + vgtest_name = params.get("vgtest_name") + lvtest_name = params.get("lvtest_name") + logical_volume = "/dev/%s/%s" % (vgtest_name, lvtest_name) + drive_format = params.get("drive_format") if drive_format == "virtio": devname = "/dev/vdb" @@ -54,7 +58,7 @@ def run_enospc(test, params, env): logging.error(e) logging.info("Guest paused, extending Logical Volume size") try: - cmd_result = utils.run("lvextend -L +200M /dev/vgtest/lvtest") + cmd_result = utils.run("lvextend -L +200M %s" % logical_volume) except error.CmdError, e: logging.debug(e.result_obj.stdout) vm.monitor.cmd("cont") diff --git a/client/tests/kvm/tests_base.cfg.sample b/client/tests/kvm/tests_base.cfg.sample index f90d551..bd2f720 100644 --- a/client/tests/kvm/tests_base.cfg.sample +++ b/client/tests/kvm/tests_base.cfg.sample @@ -601,9 +601,10 @@ variants: image_format_stg = qcow2 image_boot_stg = no image_snapshot_stg = no + check_image_stg = no + vgtest_name = vg_kvm_test_enospc + lvtest_name = lv_kvm_test_enospc 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