Dear autotest team,
I made an lvm test that creates a basic image, takes snapshots from it,
reverts and cleans up with the addition that it can create a volume group on
top of the ramdisk for quicker read/write ops. Some things are still hardcoded
but I can change this if the test could be of your interest.
Thanks,
Plamen
import commands
import logging
import re, os
from autotest.client import utils, test
from autotest.client.shared import error
class lvsetup(test.test):
version = 1
def _vg_ramdisk(self, vg_name):
"""Create vg on top of ram memory to speed up lv performance"""
logging.info("Creating virtual group on top of ram memory")
vg_size = "40000"
def _cleanup(vg_name, loop_device):
"""Inline cleanup function in case of test error"""
if os.path.exists("/tmp/" + vg_name):
commands.getstatusoutput("vgremove " + vg_name)
commands.getstatusoutput("pvremove " + loop_device)
commands.getstatusoutput("losetup -d " + loop_device)
commands.getstatusoutput("rm -f -R /tmp/" + vg_name +
"/virtual_hdd")
commands.getstatusoutput("umount /tmp/" + vg_name)
commands.getstatusoutput("rm -f -R /tmp/" + vg_name)
_cleanup(vg_name, "")
(status, output) = commands.getstatusoutput("mkdir /tmp/" + vg_name)
if status:
logging.warning(output)
(status, output) = commands.getstatusoutput("mount -t tmpfs tmpfs
/tmp/" + vg_name)
if status:
_cleanup(vg_name, "")
raise error.TestError(output)
cmd = "dd if=/dev/zero of=/tmp/" + vg_name + "/virtual_hdd bs=1M
count=1 seek=" + vg_size
(status, output) = commands.getstatusoutput(cmd)
if status:
_cleanup(vg_name, "")
raise error.TestError(output)
(status, output) = commands.getstatusoutput("losetup --find")
if status:
_cleanup(vg_name, "")
raise error.TestError(output)
else:
loop_device = output
(status, output) = commands.getstatusoutput("losetup " + loop_device +
" /tmp/" + vg_name + "/virtual_hdd")
if status:
_cleanup(vg_name, loop_device)
raise error.TestError(output)
(status, output) = commands.getstatusoutput("pvcreate " + loop_device)
if status:
_cleanup(vg_name, loop_device)
raise error.TestError(output)
else:
logging.info(output)
(status, output) = commands.getstatusoutput("vgcreate " + vg_name + "
" + loop_device)
if status:
_cleanup(vg_name, loop_device)
raise error.TestError(output)
else:
logging.info(output)
def _vg_check(self, vg_name):
"""Check whether provided volume group exists"""
cmd = "vgdisplay " + vg_name
(status, _) = commands.getstatusoutput(cmd)
if status:
return False
else:
logging.info("Provided logical group exists: " + vg_name)
return True
def _lv_check(self, vg_name, lv_name):
"""Check whether provided logical volume exists"""
cmd = "lvdisplay"
(status, output) = commands.getstatusoutput(cmd)
if status:
raise error.TestError("Invocation of " + cmd +
" returned status " + str(status))
# unstable approach but currently works
#lvpattern = r'LV Name\s+/dev/' + vg_name + r'/' + lv_name
lvpattern = r"LV Path\s+/dev/" + vg_name + r"/" + lv_name + "\s+"
match = re.search(lvpattern, output)
if match:
logging.info("Provided logical volume exists: /dev/" +
vg_name + "/" + lv_name)
return True
else:
return False
def _lv_remove(self, vg_name, lv_name):
"""Create a logical volume"""
logging.warning("Removing origin")
cmd = "lvremove -f " + vg_name + "/" + lv_name
(status, output) = commands.getstatusoutput(cmd)
logging.info(output)
if status:
raise error.TestError("Invocation of " + cmd +
" returned status " + str(status))
def _lv_create(self, vg_name, lv_name, lv_size):
"""Create a logical volume"""
logging.warning("Creating lv origin to take snapshot from")
cmd = ("lvcreate --size " + lv_size +
" --name " + lv_name + " " +
vg_name)
(status, output) = commands.getstatusoutput(cmd)
logging.info(output)
if status:
raise error.TestError("Invocation of " + cmd +
" returned status " + str(status))
def _lv_revert(self, vg_name, lv_snapshot_name):
"""
Revert the origin to a snapshot
Check this bug:
http://www.redhat.com/archives/linux-lvm/2011-July/msg00047.html
"""
logging.info("Reverting origin to snapshot")
cmd = ("lvconvert --merge /dev/%s/%s"
% (vg_name, lv_snapshot_name))
(status, output) = commands.getstatusoutput(cmd)
logging.info(output)
if status:
raise error.TestError("Invocation of " + cmd +
" returned status " + str(status))
def _lv_take_snapshot(self, vg_name, lv_name, lv_snapshot_name,
lv_snapshot_size):
"""Take a snapshot of the original logical volume"""
logging.info("Taking snapshot from origin")
cmd = ("lvcreate --size " + lv_snapshot_size + " --snapshot " +
" --name " + lv_snapshot_name +
" /dev/" + vg_name + "/" + lv_name)
(status, output) = commands.getstatusoutput(cmd)
logging.info(output)
if status:
raise error.TestError("Invocation of " + cmd +
" returned status " + str(status))
def run_once(self, vg_name, lv_name, lv_size, lv_snapshot_name,
lv_snapshot_size, override_flag = 0):
"""
General lv setup.
Override flag can be set to -1 for force-remove, 1 for force-create, 0
for default
"""
# if no virtual group is defined create one based on ramdisk
if not self._vg_check(vg_name):
self._vg_ramdisk(vg_name)
# if no snapshot is defined start fresh logical volume
if override_flag == 1 and self._lv_check(vg_name, lv_name):
self._lv_remove(vg_name, lv_name)
self._lv_create(vg_name, lv_name, lv_size)
elif override_flag == -1 and self._lv_check(vg_name, lv_name):
self._lv_remove(vg_name, lv_name)
else:
# perform normal check policy
if self._lv_check(vg_name, lv_snapshot_name) and \
self._lv_check(vg_name, lv_name):
self._lv_revert(vg_name, lv_snapshot_name)
self._lv_take_snapshot(vg_name, lv_name, lv_snapshot_name,
lv_snapshot_size)
elif self._lv_check(vg_name, lv_snapshot_name) and \
not self._lv_check(vg_name, lv_name):
raise error.TestError("Snapshot origin not found")
elif not self._lv_check(vg_name, lv_snapshot_name) and \
self._lv_check(vg_name, lv_name):
self._lv_take_snapshot(vg_name, lv_name, lv_snapshot_name,
lv_snapshot_size)
else:
self._lv_create(vg_name, lv_name, lv_size)
_______________________________________________
Autotest-kernel mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/autotest-kernel