From fcba9b43ab1249840ec2b7dd8097145d55d39aaf Mon Sep 17 00:00:00 2001 From: Jeremy Katz Date: Thu, 6 Jun 2002 21:54:09 +0000 Subject: start reading in preexisting volume group information and logical volumes --- fsset.py | 35 +++++++++++++------ lvm.py | 40 ++++++++++++++++++++++ partRequests.py | 20 ++++++++--- partitions.py | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 182 insertions(+), 16 deletions(-) create mode 100644 lvm.py diff --git a/fsset.py b/fsset.py index dd85dd2be..4267457d6 100644 --- a/fsset.py +++ b/fsset.py @@ -1813,13 +1813,23 @@ def readFstab (path): fsset.add(entry) return fsset -def isValidExt2(device): - file = '/tmp/' + device - isys.makeDevInode(device, file) +def getDevFD(device): try: - fd = os.open(file, os.O_RDONLY) + fd = os.open(device, os.O_RDONLY) except: - return 0 + file = '/tmp/' + device + isys.makeDevInode(device, file) + try: + fd = os.open(file, os.O_RDONLY) + except: + return -1 + return fd + + +def isValidExt2(device): + fd = getDevFD(device) + if fd == -1: + return 0 buf = os.read(fd, 2048) os.close(fd) @@ -1833,11 +1843,8 @@ def isValidExt2(device): return 0 def isValidXFS(device): - file = '/tmp/' + device - isys.makeDevInode(device, file) - try: - fd = os.open(file, os.O_RDONLY) - except: + fd = getDevFD(device) + if fd == -1: return 0 buf = os.read(fd, 4) @@ -1860,10 +1867,16 @@ def getFStoTry(device): rc.append("xfs") if isValidExt2(device): - if isys.ext2HasJournal(device): + if os.access(device, os.O_RDONLY): + create = 0 + else: + create = 1 + if isys.ext2HasJournal(device, makeDevNode = create): rc.append("ext3") rc.append("ext2") + # FIXME: need to check for swap + # XXX check for reiserfs signature, jfs signature, and others ? return rc diff --git a/lvm.py b/lvm.py new file mode 100644 index 000000000..3e1cf6eee --- /dev/null +++ b/lvm.py @@ -0,0 +1,40 @@ +# lvm.py - lvm probing control +# +# Jeremy Katz +# +# Copyright 2002 Red Hat, Inc. +# +# This software may be freely redistributed under the terms of the GNU +# general public license. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +import iutil +import os,sys +import string + +def vgscan(): + """Runs vgscan.""" + + rc = iutil.execWithRedirect("/usr/sbin/vgscan", + ["vgscan", "-v"], + stdout = "/tmp/lvmout", + stderr = "/tmp/lvmout", + searchPath = 1) + if rc: + raise SystemError, "vgscan failed" + +def vgactivate(): + """Activate volume groups by running vgchange -ay.""" + + rc = iutil.execWithRedirect("/usr/sbin/vgchange", + ["vgchange", "-ay"], + stdout = "/tmp/lvmout", + stderr = "/tmp/lvmout", + searchPath = 1) + if rc: + raise SystemError, "vgchange failed" + + diff --git a/partRequests.py b/partRequests.py index 7095c7aa2..af0a6645a 100644 --- a/partRequests.py +++ b/partRequests.py @@ -576,13 +576,16 @@ class VolumeGroupRequestSpec(RequestSpec): """Request to represent volume group devices.""" def __init__(self, fstype =None, format = None, - vgname = None, physvols = None): + vgname = None, physvols = None, + pesize = 4096, preexist = 0): """Create a new VolumeGroupRequestSpec object. fstype is the fsset filesystem type. format is whether or not the volume group should be created. vgname is the name of the volume group. physvols is a list of the ids for the physical volumes in the vg. + pesize is the size of a physical extent in kilobytes. + preexist is whether the volume group is preexisting. """ if not fstype: @@ -592,6 +595,8 @@ class VolumeGroupRequestSpec(RequestSpec): self.volumeGroupName = vgname self.physicalVolumes = physvols + self.pesize = pesize + self.preexist = preexist def __str__(self): physvols = [] @@ -600,9 +605,11 @@ class VolumeGroupRequestSpec(RequestSpec): physvols.append(i) str = ("VG Request -- name: %(vgname)s uniqueID: %(id)s\n" - " format: %(format)s physvols: %(physvol)s" % + " format: %(format)s pesize: %(pesize)s \n" + " physvols: %(physvol)s" % {"vgname": self.volumeGroupName, "id": self.uniqueID, - "format": self.format, "physvol": physvols}) + "format": self.format, "physvol": physvols, + "pesize": self.pesize}) return str def getDevice(self, partitions): @@ -632,7 +639,8 @@ class LogicalVolumeRequestSpec(RequestSpec): """Request to represent logical volume devices.""" def __init__(self, fstype, format = None, mountpoint = None, - size = None, volgroup = None, lvname = None): + size = None, volgroup = None, lvname = None, + preexist = 0): """Create a new VolumeGroupRequestSpec object. fstype is the fsset filesystem type. @@ -641,10 +649,12 @@ class LogicalVolumeRequestSpec(RequestSpec): size is the size of the request in MB. volgroup is the request ID of the volume group. lvname is the name of the logical volume. + preexist is whether the logical volume previously existed or not. """ RequestSpec.__init__(self, fstype = fstype, format = format, - mountpoint = mountpoint, size = size) + mountpoint = mountpoint, size = size, + preexist = preexist) self.type = REQUEST_LV self.logicalVolumeName = lvname diff --git a/partitions.py b/partitions.py index 393253fcf..78783be5c 100644 --- a/partitions.py +++ b/partitions.py @@ -19,6 +19,7 @@ import parted import iutil +import isys import string import os, sys @@ -26,6 +27,7 @@ from constants import * import fsset import raid +import lvm import partedUtils import partRequests @@ -133,6 +135,107 @@ class Partitions: self.addRequest(spec) part = disk.next_partition(part) + # now we need to read in all pre-existing RAID stuff + # XXX still needs implementing + + # now to read in pre-existing LVM stuff + lvm.vgscan() + lvm.vgactivate() + + log("looking for logical volumes") + vgs = [] + if os.path.isdir("/proc/lvm/VGs"): + vgs = os.listdir("/proc/lvm/VGs") + log("found vgs %s" %(vgs,)) + + for vg in vgs: + log("looking at VG: %s" %(vg,)) + # first find the PE size + f = open("/proc/lvm/VGs/%s/group" %(vg,), "r") + lines = f.readlines() + f.close() + pesize = 0 + for line in lines: + fields = line.split(':',1) + if len(fields) < 2: + continue + if fields[0].strip() == "PE size": + pesize = fields[1].strip() + + if not pesize: + log("Unable to find PE size for %s, defaulting to 4096" (vg,)) + pesize = 4096 + + # Now find the physical volumes associated with this VG + if not os.path.isdir("/proc/lvm/VGs/%s/PVs" % (vg,)): + log("Unable to find PVs for %s" % (vg,)) + continue + pvs = os.listdir("/proc/lvm/VGs/%s/PVs/" % (vg,)) + pvids = [] + for pv in pvs: + req = self.getRequestByDeviceName(pv) + if not req: + log("Volume group %s using non-existent partition %s" + %(vg, pv)) + continue + pvids.append(req.uniqueID) + spec = partRequests.VolumeGroupRequestSpec(format = 0, + vgname = vg, + physvols = pvids, + pesize = pesize, + preexist = 1) + vgid = self.addRequest(spec) + + # now we need to find out about the logical volumes + if not os.path.isdir("/proc/lvm/VGs/%s/LVs" %(vg,)): + log("Unable to find LVs for %s" % (lv,)) + continue + lvs = os.listdir("/proc/lvm/VGs/%s/LVs" % (vg,)) + for lv in lvs: + f = open("/proc/lvm/VGs/%s/LVs/%s" % (vg,lv), "r") + lines = f.readlines() + f.close() + lvsize = None + for line in lines: + fields = line.split(':',1) + if len(fields) < 2: + continue + if fields[0].strip() == "size": + lvsize = fields[1].strip() + if lvsize is None: + log("Unable to find LV size for %s/%s" % (vg, lv)) + continue + lvsize = int(lvsize) / 1024.0 + + found = 0 + try: + os.mkdir("/tmp/testmnt") + except: + pass + for fs in fsset.getFStoTry("/dev/%s/%s" %(vg, lv)): + try: + isys.mount("/dev/%s/%s" % (vg, lv), + "/tmp/testmnt", fs, readOnly = 1) + isys.umount("/tmp/testmnt") + found = 1 + break + except SystemError, (errno, msg): + pass + if not found: + fsystem = fsset.fileSystemTypeGet("foreign") + else: + fsystem = fsset.fileSystemTypeGet(fs) + + spec = partRequests.LogicalVolumeRequestSpec(fsystem, + format = 0, + size = lvsize, + volgroup = vgid, + lvname = lv, + preexist = 1) + self.addRequest(spec) + + + def addRequest (self, request): """Add a new request to the list.""" if not request.uniqueID: -- cgit