OLD | NEW |
1 import logging, time, re | 1 import logging, time, re, os |
2 from autotest_lib.client.common_lib import error | 2 from autotest_lib.client.common_lib import error |
3 from autotest_lib.client.bin import utils | 3 from autotest_lib.client.bin import utils |
4 import kvm_vm | 4 import kvm_vm, kvm_utils |
| 5 |
| 6 |
| 7 class EnospcConfig(object): |
| 8 """ |
| 9 Performs setup for the test enospc. This is a borg class, similar to a |
| 10 singleton. The idea is to keep state in memory for when we call cleanup() |
| 11 on postprocessing. |
| 12 """ |
| 13 __shared_state = {} |
| 14 def __init__(self, test, params): |
| 15 self.__dict__ = self.__shared_state |
| 16 root_dir = test.bindir |
| 17 self.tmpdir = test.tmpdir |
| 18 self.qemu_img_binary = params.get('qemu_img_binary') |
| 19 if not os.path.isfile(self.qemu_img_binary): |
| 20 self.qemu_img_binary = os.path.join(root_dir, |
| 21 self.qemu_img_binary) |
| 22 self.raw_file_path = os.path.join(self.tmpdir, 'enospc.raw') |
| 23 # Here we're trying to choose fairly explanatory names so it's less |
| 24 # likely that we run in conflict with other devices in the system |
| 25 self.vgtest_name = params.get("vgtest_name") |
| 26 self.lvtest_name = params.get("lvtest_name") |
| 27 self.lvtest_device = "/dev/%s/%s" % (self.vgtest_name, self.lvtest_name) |
| 28 image_dir = os.path.dirname(params.get("image_name")) |
| 29 self.qcow_file_path = os.path.join(image_dir, 'enospc.qcow2') |
| 30 try: |
| 31 getattr(self, 'loopback') |
| 32 except AttributeError: |
| 33 self.loopback = '' |
| 34 |
| 35 @error.context_aware |
| 36 def setup(self): |
| 37 logging.debug("Starting enospc setup") |
| 38 error.context("performing enospc setup") |
| 39 kvm_utils.display_attributes(self) |
| 40 # Double check if there aren't any leftovers |
| 41 self.cleanup() |
| 42 try: |
| 43 utils.run("%s create -f raw %s 10G" % |
| 44 (self.qemu_img_binary, self.raw_file_path)) |
| 45 # Associate a loopback device with the raw file. |
| 46 # Subject to race conditions, that's why try here to associate |
| 47 # it with the raw file as quickly as possible |
| 48 l_result = utils.run("losetup -f") |
| 49 utils.run("losetup -f %s" % self.raw_file_path) |
| 50 self.loopback = l_result.stdout.strip() |
| 51 # Add the loopback device configured to the list of pvs |
| 52 # recognized by LVM |
| 53 utils.run("pvcreate %s" % self.loopback) |
| 54 utils.run("vgcreate %s %s" % (self.vgtest_name, self.loopback)) |
| 55 # Create an lv inside the vg with starting size of 200M |
| 56 utils.run("lvcreate -L 200M -n %s %s" % |
| 57 (self.lvtest_name, self.vgtest_name)) |
| 58 # Create a 10GB qcow2 image in the logical volume |
| 59 utils.run("%s create -f qcow2 %s 10G" % |
| 60 (self.qemu_img_binary, self.lvtest_device)) |
| 61 # Let's symlink the logical volume with the image name that autotest |
| 62 # expects this device to have |
| 63 os.symlink(self.lvtest_device, self.qcow_file_path) |
| 64 except Exception, e: |
| 65 self.cleanup() |
| 66 raise |
| 67 |
| 68 @error.context_aware |
| 69 def cleanup(self): |
| 70 error.context("performing enospc cleanup") |
| 71 if os.path.isfile(self.lvtest_device): |
| 72 utils.run("fuser -k %s" % self.lvtest_device) |
| 73 time.sleep(2) |
| 74 l_result = utils.run("lvdisplay") |
| 75 # Let's remove all volumes inside the volume group created |
| 76 if self.lvtest_name in l_result.stdout: |
| 77 utils.run("lvremove -f %s" % self.lvtest_device) |
| 78 # Now, removing the volume group itself |
| 79 v_result = utils.run("vgdisplay") |
| 80 if self.vgtest_name in v_result.stdout: |
| 81 utils.run("vgremove -f %s" % self.vgtest_name) |
| 82 # Now, if we can, let's remove the physical volume from lvm list |
| 83 if self.loopback: |
| 84 p_result = utils.run("pvdisplay") |
| 85 if self.loopback in p_result.stdout: |
| 86 utils.run("pvremove -f %s" % self.loopback) |
| 87 l_result = utils.run('losetup -a') |
| 88 if self.loopback and (self.loopback in l_result.stdout): |
| 89 try: |
| 90 utils.run("losetup -d %s" % self.loopback) |
| 91 except error.CmdError: |
| 92 logging.error("Failed to liberate loopback %s", self.loopback) |
| 93 if os.path.islink(self.qcow_file_path): |
| 94 os.remove(self.qcow_file_path) |
| 95 if os.path.isfile(self.raw_file_path): |
| 96 os.remove(self.raw_file_path) |
5 | 97 |
6 | 98 |
7 def run_enospc(test, params, env): | 99 def run_enospc(test, params, env): |
8 """ | 100 """ |
9 ENOSPC test | 101 ENOSPC test |
10 | 102 |
11 1) Create a virtual disk on lvm | 103 1) Create a virtual disk on lvm |
12 2) Boot up guest with two disks | 104 2) Boot up guest with two disks |
13 3) Continually write data to second disk | 105 3) Continually write data to second disk |
14 4) Check images and extend second disk when no space | 106 4) Check images and extend second disk when no space |
15 5) Continue paused guest | 107 5) Continue paused guest |
16 6) Repeat step 3~5 several times | 108 6) Repeat step 3~5 several times |
17 | 109 |
18 @param test: KVM test object. | 110 @param test: KVM test object. |
19 @param params: Dictionary with the test parameters. | 111 @param params: Dictionary with the test parameters. |
20 @param env: Dictionary with test environment. | 112 @param env: Dictionary with test environment. |
21 """ | 113 """ |
| 114 enospc_config = EnospcConfig(test, params) |
| 115 enospc_config.setup() |
22 vm = env.get_vm(params["main_vm"]) | 116 vm = env.get_vm(params["main_vm"]) |
23 vm.verify_alive() | 117 vm.create() |
24 login_timeout = int(params.get("login_timeout", 360)) | 118 login_timeout = int(params.get("login_timeout", 360)) |
25 session_serial = vm.wait_for_serial_login(timeout=login_timeout) | 119 session_serial = vm.wait_for_serial_login(timeout=login_timeout) |
26 | 120 |
27 vgtest_name = params.get("vgtest_name") | 121 vgtest_name = params.get("vgtest_name") |
28 lvtest_name = params.get("lvtest_name") | 122 lvtest_name = params.get("lvtest_name") |
29 logical_volume = "/dev/%s/%s" % (vgtest_name, lvtest_name) | 123 logical_volume = "/dev/%s/%s" % (vgtest_name, lvtest_name) |
30 | 124 |
31 drive_format = params.get("drive_format") | 125 drive_format = params.get("drive_format") |
32 if drive_format == "virtio": | 126 if drive_format == "virtio": |
33 devname = "/dev/vdb" | 127 devname = "/dev/vdb" |
(...skipping 13 matching lines...) Expand all Loading... |
47 while i < iterations: | 141 while i < iterations: |
48 status = vm.monitor.cmd("info status") | 142 status = vm.monitor.cmd("info status") |
49 logging.debug(status) | 143 logging.debug(status) |
50 if "paused" in status: | 144 if "paused" in status: |
51 pause_n += 1 | 145 pause_n += 1 |
52 logging.info("Checking all images in use by the VM") | 146 logging.info("Checking all images in use by the VM") |
53 for image_name in vm.params.objects("images"): | 147 for image_name in vm.params.objects("images"): |
54 image_params = vm.params.object_params(image_name) | 148 image_params = vm.params.object_params(image_name) |
55 try: | 149 try: |
56 kvm_vm.check_image(image_params, test.bindir) | 150 kvm_vm.check_image(image_params, test.bindir) |
57 except kvm_vm.VMError, e: | 151 except (kvm_vm.VMError, error.TestWarn), e: |
58 logging.error(e) | 152 logging.error(e) |
59 logging.info("Guest paused, extending Logical Volume size") | 153 logging.info("Guest paused, extending Logical Volume size") |
60 try: | 154 try: |
61 utils.run("lvextend -L +200M %s" % logical_volume) | 155 utils.run("lvextend -L +200M %s" % logical_volume) |
62 except error.CmdError, e: | 156 except error.CmdError, e: |
63 logging.debug(e.result_obj.stdout) | 157 logging.debug(e.result_obj.stdout) |
64 vm.monitor.cmd("cont") | 158 vm.monitor.cmd("cont") |
65 time.sleep(10) | 159 time.sleep(10) |
66 i += 1 | 160 i += 1 |
67 | 161 |
68 if pause_n == 0: | 162 if pause_n == 0: |
69 raise error.TestFail("Guest didn't pause during loop") | 163 raise error.TestFail("Guest didn't pause during loop") |
70 else: | 164 else: |
71 logging.info("Guest paused %s times from %s iterations", | 165 logging.info("Guest paused %s times from %s iterations", |
72 pause_n, iterations) | 166 pause_n, iterations) |
73 | 167 |
74 logging.info("Final %s", vm.monitor.cmd("info status")) | 168 logging.info("Final %s", vm.monitor.cmd("info status")) |
| 169 enospc_config.cleanup() |
OLD | NEW |