--- fsset.py | 32 +++++++++++++++++++++++++++----- lvm.py | 24 ++++++++++++++++++++---- lvmErrors.py | 10 ++++++++++ packages.py | 5 +++-- partRequests.py | 23 +++++++++++++++++++++-- partitions.py | 23 ++++++++++++++++++++++- 6 files changed, 103 insertions(+), 14 deletions(-) diff --git a/fsset.py b/fsset.py index 9a93726..867906c 100644 --- a/fsset.py +++ b/fsset.py @@ -1482,7 +1482,8 @@ MAILADDR root if bootPart: del bootPart - def resizeFilesystems (self, chroot = '/', shrink = False, grow = False): + def resizeFilesystems (self, diskset, chroot = '/', shrink = False, grow = False): + todo = [] for entry in self.entries: if not entry.fsystem or not entry.fsystem.isResizable(): continue @@ -1492,13 +1493,34 @@ MAILADDR root continue if grow and not (entry.resizeTargetSize > entry.resizeOrigSize): continue + todo.append(entry) + if len(todo) == 0: + return + + # we have to have lvm activated to be able to do resizes of LVs + active = lvm.vgcheckactive() + if not active: + diskset.startMPath() + diskset.startDmRaid() + diskset.startMdRaid() + + lvm.vgscan() + lvm.vgactivate() + + for entry in todo: entry.fsystem.resize(entry, entry.resizeTargetSize, self.progressWindow, chroot) - def shrinkFilesystems (self, chroot): - self.resizeFilesystems(chroot, shrink = True) - def growFilesystems (self, chroot): - self.resizeFilesystems(chroot, grow = True) + if not active: + lvm.vgdeactivate() + diskset.stopMPath() + diskset.stopDmRaid() + diskset.stopMdRaid() + + def shrinkFilesystems (self, diskset, chroot): + self.resizeFilesystems(diskset, chroot, shrink = True) + def growFilesystems (self, diskset, chroot): + self.resizeFilesystems(diskset, chroot, grow = True) def formatSwap (self, chroot, forceFormat=False): formatted = [] diff --git a/lvm.py b/lvm.py index e1ead92..4e14ac4 100644 --- a/lvm.py +++ b/lvm.py @@ -200,6 +200,22 @@ def lvremove(lvname, vgname): if rc: raise LVRemoveError(vgname, lvname) +def lvresize(lvname, vgname, size): + global lvmDevicePresent + if flags.test or lvmDevicePresent == 0: + return + + args = ["lvresize", "-An", "-L", "%dM" %(size,), "-v", + "/dev/%s/%s" %(vgname, lvname,)] + + try: + rc = lvmExec(*args) + except: + rc = 1 + if rc: + raise LVMResizeError(vgname, lvname) + + def vgcreate(vgname, PESize, nodes): """Creates a new volume group." @@ -364,18 +380,18 @@ def vglist(): vgs = [] args = ["vgdisplay", "-C", "--noheadings", "--units", "b", "--nosuffix", "--separator", ":", "--options", - "vg_name,vg_size,vg_extent_size" + "vg_name,vg_size,vg_extent_size,vg_free" ] for line in lvmCapture(*args): try: - (vg, size, pesize) = line + (vg, size, pesize, free) = line size = long(math.floor(long(size) / (1024 * 1024))) pesize = long(pesize)/1024 + free = math.floor(long(free) / (1024 * 1024)) except: continue log.info("vg %s, size is %s, pesize is %s" %(vg, size, pesize)) - vgs.append( (vg, size, pesize) ) - + vgs.append( (vg, size, pesize, free) ) return vgs def partialvgs(): diff --git a/lvmErrors.py b/lvmErrors.py index 3371c05..c69e9b5 100644 --- a/lvmErrors.py +++ b/lvmErrors.py @@ -59,6 +59,16 @@ class LVRemoveError(LvmError): return "lvremove of lv \"%s\" from vg \"%s\" failed\nLog:\n%s" % ( \ self.lvname, self.vgname, self.log) +class LVResizeError(LvmError): + def __init__(self, vgname, lvname): + self.vgname = vgname + self.lvname = lvname + self.log = self.getLvmOutput() + + def __str__(self): + return "lvresize 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 diff --git a/packages.py b/packages.py index 99f9a38..42dc12b 100644 --- a/packages.py +++ b/packages.py @@ -148,10 +148,11 @@ def turnOnFilesystems(anaconda): searchPath = 1) anaconda.id.partitions.doMetaDeletes(anaconda.id.diskset) anaconda.id.fsset.setActive(anaconda.id.diskset) - anaconda.id.fsset.shrinkFilesystems(anaconda.rootPath) + anaconda.id.fsset.shrinkFilesystems(anaconda.id.diskset, anaconda.rootPath) if not anaconda.id.fsset.isActive(): anaconda.id.diskset.savePartitions () - anaconda.id.fsset.growFilesystems(anaconda.rootPath) + anaconda.id.partitions.doMetaResizes(anaconda.id.diskset) + anaconda.id.fsset.growFilesystems(anaconda.id.diskset, anaconda.rootPath) if not anaconda.id.fsset.volumesCreated: anaconda.id.fsset.createLogicalVolumes(anaconda.rootPath) anaconda.id.fsset.formatSwap(anaconda.rootPath) diff --git a/partRequests.py b/partRequests.py index 84ff18a..a766404 100644 --- a/partRequests.py +++ b/partRequests.py @@ -795,6 +795,7 @@ class VolumeGroupRequestSpec(RequestSpec): self.physicalVolumes = physvols self.pesize = pesize self.preexist = preexist + self.free = 0 # FIXME: this is a hack so that we can set the vg name automagically # with autopartitioning to not conflict with existing vgs @@ -915,13 +916,15 @@ class LogicalVolumeRequestSpec(RequestSpec): self.grow = grow self.maxSizeMB = maxSizeMB self.startSize = size + + self.minResizeSize = None + self.resizable = True if not percent and not size and not preexist: raise RuntimeError, "Error with Volume Group:Logical Volume %s:%s - Logical Volume must specify either percentage of vgsize or size" % (volgroup, lvname) if percent and grow: raise RuntimeError, "Error with Volume Group:Logical Volume %s:%s - Logical Volume cannot grow if percentage given" % (volgroup, lvname) - def __str__(self): if self.fstype: @@ -955,14 +958,19 @@ class LogicalVolumeRequestSpec(RequestSpec): existing = self.preexist) return self.dev - def getActualSize(self, partitions, diskset): + def getActualSize(self, partitions = None, diskset = None, target = False): """Return the actual size allocated for the request in megabytes.""" if self.percent: + if partitions is None or diskset is None: + raise RuntimeError, "trying to get a percentage lv size on resize path" vgreq = partitions.getRequestByID(self.volumeGroup) vgsize = vgreq.getActualSize(partitions, diskset) lvsize = int(self.percent * 0.01 * vgsize) #lvsize = lvm.clampLVSizeRequest(lvsize, vgreq.pesize) return lvsize + # FIXME: the target bit here is a bit of a hack... + elif self.targetSize is not None and target: + return self.targetSize else: return self.size @@ -996,3 +1004,14 @@ class LogicalVolumeRequestSpec(RequestSpec): "containing encrypted physical volumes.") return RequestSpec.sanityCheckRequest(self, partitions, skipMntPtExistCheck) + + def getMaximumResizeMB(self, partitions): + vg = partitions.getRequestByID(self.volumeGroup) + print "max is", self.getActualSize(), vg.free, self.getActualSize() + vg.free + return self.getActualSize() + vg.free + + def getMinimumResizeMB(self, partitions): + if self.minResizeSize is None: + log.warning("don't know the minimum size of %s" %(self.logicalVolumeName,)) + return 1 + return self.minResizeSize diff --git a/partitions.py b/partitions.py index 25871a7..b19b4e3 100644 --- a/partitions.py +++ b/partitions.py @@ -278,7 +278,7 @@ class Partitions: lvm.vgactivate() pvs = lvm.pvlist() - for (vg, size, pesize) in lvm.vglist(): + for (vg, size, pesize, vgfree) in lvm.vglist(): try: preexist_size = float(size) except: @@ -301,6 +301,7 @@ class Partitions: pesize = pesize, preexist = 1, preexist_size = preexist_size) + spec.free = vgfree vgid = self.addRequest(spec) for (lvvg, lv, size, lvorigin) in lvm.lvlist(): @@ -332,6 +333,8 @@ class Partitions: format = format, size = lvsize, volgroup = vgid, lvname = lv, mountpoint = mnt, fslabel = fslabel, preexist = 1) + if fsystem.isResizable(): + spec.minResizeSize = fsystem.getMinimumSize("%s/%s" %(vg, lv)) self.addRequest(spec) for vg in lvm.partialvgs(): @@ -1460,6 +1463,24 @@ class Partitions: lvm.vgdeactivate() diskset.stopMdRaid() + def doMetaResizes(self, diskset): + """Does resizing of non-physical volumes.""" + # NOTE: this should be called with volumes active + + # we only support resizing LVM of these types of things currently + for lv in self.getLVMLVRequests(): + if not lv.preexist: + continue + if lv.targetSize is None: + continue + + vg = self.getRequestByID(lv.volumeGroup) + if vg is None: + continue + + lvm.lvresize(lv.logicalVolumeName, vg.volumeGroupName, + lv.targetSize) + def deleteDependentRequests(self, request): """Handle deletion of this request and all requests which depend on it. -- 1.5.3.4 _______________________________________________ Anaconda-devel-list mailing list Anaconda-devel-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/anaconda-devel-list