summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog10
-rw-r--r--fsset.py57
-rw-r--r--lvm.py189
-rw-r--r--lvmErrors.py101
4 files changed, 256 insertions, 101 deletions
diff --git a/ChangeLog b/ChangeLog
index bc5497bab..24f33c09c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2007-02-07 Peter Jones <pjones@redhat.com>
+
+ * lvmErrors.py: add some exception classes
+
+ * lvm.py: add lvmExec and lvmCapture wrappers to iutil.exec*.
+ make lots of lvm commands use lvmExec and lvmCapture.
+ When exceptions happen, raise the exceptions defined in lvmErrors.py
+
+ * fsset.py: use lvm commands in lvm.py
+
2007-02-07 Jeremy Katz <katzj@redhat.com>
* isys/isys.py (fbconProbe): Remove obsolete crap.
diff --git a/fsset.py b/fsset.py
index 5d407a0b1..ffb2f6c51 100644
--- a/fsset.py
+++ b/fsset.py
@@ -1808,11 +1808,7 @@ MAILADDR root
if isinstance(root.device, LogicalVolumeDevice) or rootlvm1:
# now make sure all of the device nodes exist. *sigh*
- rc = iutil.execWithRedirect("lvm",
- ["vgmknodes", "-v"],
- stdout = "/tmp/lvmout",
- stderr = "/tmp/lvmout",
- searchPath = 1)
+ rc = lvm.vgmknodes()
rootDev = "/dev/%s" % (root.device.getDevice(),)
rootdir = instPath + rootDev[:string.rfind(rootDev, "/")]
@@ -2263,42 +2259,11 @@ class VolumeGroupDevice(Device):
# XXX I should check if the pv is set up somehow so that we
# can have preexisting vgs and add new pvs to them.
if not self.isSetup:
- # now make the device into a real physical volume
- # XXX I don't really belong here. should
- # there be a PhysicalVolumeDevice(PartitionDevice) ?
- lvm.writeForceConf()
- rc = iutil.execWithRedirect("lvm",
- ["pvcreate", "-ff", "-y",
- "-v", node],
- stdout = "/tmp/lvmout",
- stderr = "/tmp/lvmout",
- searchPath = 1)
- if rc:
- raise SystemError, "pvcreate failed for %s" % (volume,)
- lvm.unlinkConf()
-
- lvm.wipeOtherMetadataFromPV(node)
-
+ lvm.pvcreate(node)
nodes.append(node)
if not self.isSetup:
- # rescan now that we've recreated pvs. ugh.
- lvm.writeForceConf()
- lvm.vgscan()
-
- args = [ "vgcreate", "-v", "-An",
- "-s", "%sk" %(self.physicalextentsize,),
- self.name ]
- args.extend(nodes)
- rc = iutil.execWithRedirect("lvm", args,
- stdout = "/tmp/lvmout",
- stderr = "/tmp/lvmout",
- searchPath = 1)
-
- if rc:
- raise SystemError, "vgcreate failed for %s" %(self.name,)
-
- lvm.unlinkConf()
+ lvm.vgcreate(self.name, self.physicalextentsize, nodes)
self.isSetup = 1
else:
lvm.vgscan()
@@ -2330,21 +2295,11 @@ class LogicalVolumeDevice(Device):
def setupDevice(self, chroot="/", devPrefix='/tmp', vgdevice = None):
if not self.isSetup:
- lvm.writeForceConf()
- rc = iutil.execWithRedirect("lvm",
- ["lvcreate", "-L",
- "%dM" % (self.size,),
- "-n", self.name, "-An",
- self.vgname],
- stdout = "/tmp/lvmout",
- stderr = "/tmp/lvmout",
- searchPath = 1)
- if rc:
- raise SystemError, "lvcreate failed for %s" %(self.name,)
- lvm.unlinkConf()
+ lvm.lvcreate(self.name, self.vgname, self.size)
self.isSetup = 1
- if vgdevice and vgdevice.isNetdev(): self.setAsNetdev()
+ if vgdevice and vgdevice.isNetdev():
+ self.setAsNetdev()
return "/dev/%s" % (self.getDevice(),)
diff --git a/lvm.py b/lvm.py
index 8ba17aa85..b2c193851 100644
--- a/lvm.py
+++ b/lvm.py
@@ -30,6 +30,8 @@ output = "/tmp/lvmout"
lvmDevicePresent = 0
+from lvmErrors import *
+
def has_lvm():
global lvmDevicePresent
@@ -53,6 +55,22 @@ def has_lvm():
# now check to see if lvm is available
has_lvm()
+def lvmExec(*args):
+ try:
+ return iutil.execWithRedirect("lvm", args, stdout = output,
+ stderr = output, searchPath = 1)
+ except:
+ raise LvmError, args[0]
+
+def lvmCapture(*args):
+ try:
+ lvmout = iutil.execWithCapture("lvm", args, stderr = output)
+ lines = []
+ for line in lvmout.split("\n"):
+ lines.append(line.strip().split(':'))
+ return lines
+ except:
+ raise LvmError, args[0]
def vgscan():
"""Runs vgscan."""
@@ -61,13 +79,21 @@ def vgscan():
if flags.test or lvmDevicePresent == 0:
return
- rc = iutil.execWithRedirect("lvm", ["vgscan", "-v"],
- stdout = output, stderr = output,
- searchPath = 1)
+ rc = lvmExec("vgscan", "-v")
if rc:
log.error("running vgscan failed: %s" %(rc,))
# lvmDevicePresent = 0
+def vgmknodes(volgroup=None):
+ # now make the device nodes
+ args = ["vgmknodes", "-v"]
+ if volgroup:
+ args.append(volgroup)
+ rc = lvmExec(*args)
+ if rc:
+ log.error("running vgmknodes failed: %s" %(rc,))
+# lvmDevicePresent = 0
+
def vgactivate(volgroup = None):
"""Activate volume groups by running vgchange -ay.
@@ -77,24 +103,14 @@ def vgactivate(volgroup = None):
if flags.test or lvmDevicePresent == 0:
return
- args = ["vgchange", "-ay"]
+ args = ["vgchange", "-ay", "-v"]
if volgroup:
args.append(volgroup)
- rc = iutil.execWithRedirect("lvm", args, stdout = output,
- stderr = output, searchPath = 1)
+ rc = lvmExec(*args)
if rc:
log.error("running vgchange failed: %s" %(rc,))
# lvmDevicePresent = 0
-
- # now make the device nodes
- args = ["vgmknodes"]
- if volgroup:
- args.append(volgroup)
- rc = iutil.execWithRedirect("lvm", args, stdout = output,
- stderr = output, searchPath = 1)
- if rc:
- log.error("running vgmknodes failed: %s" %(rc,))
-# lvmDevicePresent = 0
+ vgmknodes(volgroup)
def vgdeactivate(volgroup = None):
"""Deactivate volume groups by running vgchange -an.
@@ -105,16 +121,36 @@ def vgdeactivate(volgroup = None):
if flags.test or lvmDevicePresent == 0:
return
- args = ["vgchange", "-an"]
+ args = ["vgchange", "-an", "-v"]
if volgroup:
args.append(volgroup)
- rc = iutil.execWithRedirect("lvm", args, stdout = output,
- stderr = output, searchPath = 1)
+ rc = lvmExec(*args)
if rc:
log.error("running vgchange failed: %s" %(rc,))
# lvmDevicePresent = 0
-
-
+
+def lvcreate(lvname, vgname, size):
+ """Creates a new logical volume.
+
+ lvname - name of logical volume to create.
+ vgname - name of volume group lv will be in.
+ size - size of lv, in megabytes.
+ """
+ global lvmDevicePresent
+ if flags.test or lvmDevicePresent == 0:
+ return
+ writeForceConf()
+ vgscan()
+
+ args = ["lvcreate", "-v", "-L", "%dM" %(size,), "-n", lvname, "-An", vgname]
+ try:
+ rc = lvmExec(*args)
+ except:
+ rc = 1
+ if rc:
+ raise LVCreateError(vgname, lvname, size)
+ unlinkConf()
+
def lvremove(lvname, vgname):
"""Removes a logical volume.
@@ -125,15 +161,42 @@ def lvremove(lvname, vgname):
if flags.test or lvmDevicePresent == 0:
return
- args = ["lvremove", "-f"]
+ args = ["lvremove", "-f", "-v"]
dev = "/dev/%s/%s" %(vgname, lvname)
args.append(dev)
- rc = iutil.execWithRedirect("lvm", args, stdout = output,
- stderr = output, searchPath = 1)
+ try:
+ rc = lvmExec(*args)
+ except:
+ rc = 1
if rc:
- raise SystemError, "lvremove failed"
+ raise LVRemoveError(vgname, lvname)
+def vgcreate(vgname, PESize, nodes):
+ """Creates a new volume group."
+
+ vgname - name of volume group to create.
+ PESize - Physical Extent size, in kilobytes.
+ nodes - LVM Physical Volumes on which to put the new VG.
+ """
+ global lvmDevicePresent
+ if flags.test or lvmDevicePresent == 0:
+ return
+
+ # rescan now that we've recreated pvs. ugh.
+ writeForceConf()
+ vgscan()
+
+ args = ["vgcreate", "-v", "-An", "-s", "%sk" % (PESize,), vgname ]
+ args.extend(nodes)
+
+ try:
+ rc = lvmExec(*args)
+ except:
+ rc = 1
+ if rc:
+ raise VGCreateError(vgname, PESize, nodes)
+ unlinkConf()
def vgremove(vgname):
"""Removes a volume group. Deactivates the volume group first
@@ -158,34 +221,62 @@ def vgremove(vgname):
except:
pass
- args = ["vgremove", vgname]
+ args = ["vgremove", "-v", vgname]
log.info(string.join(args, ' '))
- rc = iutil.execWithRedirect("lvm", args, stdout = output,
- stderr = output, searchPath = 1)
+ try:
+ rc = lvmExec(*args)
+ except:
+ rc = 1
if rc:
- raise SystemError, "vgremove failed"
+ raise VGRemoveError, vgname
# now iterate all the PVs we've just freed up, so we reclaim the metadata
# space. This is an LVM bug, AFAICS.
for pvname in pvs:
- args = ["pvremove", "-ff", "-y", pvname]
+ args = ["pvremove", "-ff", "-y", "-v", pvname]
log.info(string.join(args, ' '))
- rc = iutil.execWithRedirect("lvm", args, stdout = output,
- stderr = output, searchPath = 1)
-
+ try:
+ rc = lvmExec(*args)
+ except:
+ rc = 1
if rc:
- raise SystemError, "pvremove failed"
+ raise PVRemoveError, pvname
args = ["pvcreate", "-ff", "-y", "-v", pvname]
log.info(string.join(args, ' '))
- rc = iutil.execWithRedirect("lvm", args, stdout = output,
- stderr = output, searchPath = 1)
-
+ try:
+ rc = lvmExec(*args)
+ except:
+ rc = 1
if rc:
- raise SystemError, "pvcreate failed for %s" % (pvname,)
+ raise PVCreateError, pvname
+ wipeOtherMetadataFromPV(pvname)
+
+def pvcreate(node):
+ """Initializes a new Physical Volume."
+
+ node - path to device node on which to create the new PV."
+ """
+ global lvmDevicePresent
+ if flags.test or lvmDevicePresent == 0:
+ return
+
+ # rescan now that we've recreated pvs. ugh.
+ writeForceConf()
+
+ args = ["pvcreate", "-ff", "-y", "-v", node ]
+
+ try:
+ rc = lvmExec(*args)
+ except:
+ rc = 1
+ if rc:
+ raise PVCreateError(node)
+ unlinkConf()
+ wipeOtherMetadataFromPV(node)
def lvlist():
global lvmDevicePresent
@@ -199,9 +290,9 @@ def lvlist():
"vg_name,lv_name,lv_size,origin"
]
lvscanout = iutil.execWithCapture("lvm", args, stderr = "/dev/tty6")
- for line in lvscanout.split("\n"):
+ for line in lvmCapture(*args):
try:
- (vg, lv, size, origin) = line.strip().split(':')
+ (vg, lv, size, origin) = line
size = long(math.floor(long(size) / (1024 * 1024)))
if origin == '':
origin = None
@@ -226,10 +317,9 @@ def pvlist():
"--nosuffix", "--separator", ":", "--options",
"pv_name,vg_name,dev_size"
]
- scanout = iutil.execWithCapture("lvm", args, stderr = "/dev/tty6")
- for line in scanout.split("\n"):
+ for line in lvmCapture(*args):
try:
- (dev, vg, size) = line.strip().split(':')
+ (dev, vg, size) = line
size = long(math.floor(long(size) / (1024 * 1024)))
except:
continue
@@ -248,10 +338,9 @@ def vglist():
"--nosuffix", "--separator", ":", "--options",
"vg_name,vg_size,vg_extent_size"
]
- scanout = iutil.execWithCapture("lvm", args, stderr = "/dev/tty6")
- for line in scanout.split("\n"):
+ for line in lvmCapture(*args):
try:
- (vg, size, pesize) = line.strip().split(':')
+ (vg, size, pesize) = line
size = long(math.floor(long(size) / (1024 * 1024)))
pesize = long(pesize)/1024
except:
@@ -267,11 +356,11 @@ def partialvgs():
return []
vgs = []
- args = ["vgdisplay", "-C", "-P", "--noheadings", "--units", "b"]
- scanout = iutil.execWithCapture("lvm", args, stderr = "/dev/tty6")
- for line in scanout.split("\n"):
+ args = ["vgdisplay", "-C", "-P", "--noheadings", "--units", "b",
+ "--nosuffix", "--separator", ":"]
+ for line in lvmCapture(*args):
try:
- (vg, numpv, numlv, numsn, attr, size, free) = line.strip()[:-1].split()
+ (vg, numpv, numlv, numsn, attr, size, free) = line
except:
continue
if attr.find("p") != -1:
diff --git a/lvmErrors.py b/lvmErrors.py
new file mode 100644
index 000000000..3371c05a4
--- /dev/null
+++ b/lvmErrors.py
@@ -0,0 +1,101 @@
+#
+# lvmErrors.py: lvm error exceptions
+#
+# Peter Jones <pjones@redhat.com>
+#
+# Copyright 2007 Red Hat, Inc.
+#
+# This software may be freely redistributed under the terms of the GNU
+# library public license.
+#
+# You should have received a copy of the GNU Library Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+"""Exceptions for use in lvm operations."""
+
+import string
+from lvm import output
+
+class LvmError(Exception):
+ """An error occurred with lvm."""
+ def __init__(self, command, name=None):
+ self.command = command
+ self.name = name
+ self.log = self.getLvmOutput()
+
+ def getLvmOutput(self):
+ f = open(output, "r")
+ lines = reduce(lambda x,y: x + [string.strip(y),], f.readlines(), [])
+ lines = string.join(reduce(lambda x,y: x + [" %s" % (y,)], \
+ lines, []), "\n")
+ return lines
+
+ def __str__(self):
+ s = ""
+ if not self.name is None:
+ s = " for device %s" % (self.name,)
+ return "%s failed%s\nLog:\n%s" % (self.command, s, self.log)
+
+class LVCreateError(LvmError):
+ def __init__(self, vgname, lvname, size):
+ self.vgname = vgname
+ self.lvname = lvname
+ self.size = size
+ self.log = self.getLvmOutput()
+
+ def __str__(self):
+ return "lvcreate of %d Megabyte lv \"%s\" on vg \"%s\" failed\n" \
+ "Log:\n%s" % ( \
+ self.size, self.lvname, self.vgname, self.log)
+
+class LVRemoveError(LvmError):
+ def __init__(self, vgname, lvname):
+ self.vgname = vgname
+ self.lvname = lvname
+ self.log = self.getLvmOutput()
+
+ def __str__(self):
+ return "lvremove of lv \"%s\" from vg \"%s\" failed\nLog:\n%s" % ( \
+ self.lvname, self.vgname, self.log)
+
+class VGCreateError(LvmError):
+ def __init__(self, vgname, PESize, nodes):
+ self.vgname = vgname
+ self.PESize = PESize
+ self.nodes = nodes
+ self.log = self.getLvmOutput()
+
+ def __str__(self):
+ nodes = string.join(self.nodes, ' ')
+ return "vgcreate failed creating vg \"%s\" (PESize=%dkB) on PVs: %s\n" \
+ "Log:\n%s" % ( \
+ self.vgname, self.PESize, nodes, self.log)
+
+class VGRemoveError(LvmError):
+ def __init__(self, vgname):
+ self.vgname = vgname
+ self.log = self.getLvmOutput()
+
+ def __str__(self):
+ return "vgremove of vg \"%s\" failed\nLog:\n%s" % ( \
+ self.vgname, self.log)
+
+class PVRemoveError(LvmError):
+ def __init__(self, pvname):
+ self.pvname = pvname
+ self.log = self.getLvmOutput()
+
+ def __str__(self):
+ return "pvremove of pv \"%s\" failed\nLog:\n%s" % ( \
+ self.pvname, self.log)
+
+class PVCreateError(LvmError):
+ def __init__(self, pvname):
+ self.pvname = pvname
+ self.log = self.getLvmOutput()
+
+ def __str__(self):
+ return "pvcreate of pv \"%s\" failed\nLog:\n%s" % ( \
+ self.pvname, self.log)
+