Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 149352 Details for
Bug 134638
RFE: Installer support for creating new LVs with non-linear segment types
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
The diff
diff (text/plain), 46.00 KB, created by
Joel Andres Granados
on 2007-03-06 16:32:56 UTC
(
hide
)
Description:
The diff
Filename:
MIME Type:
Creator:
Joel Andres Granados
Created:
2007-03-06 16:32:56 UTC
Size:
46.00 KB
patch
obsolete
>diff -ubBr FC-6/fsset.py rfc6-3/fsset.py >--- FC-6/fsset.py 2006-09-27 23:16:56.000000000 +0200 >+++ rfc6-3/fsset.py 2007-03-06 14:16:38.000000000 +0100 >@@ -1604,12 +1604,23 @@ > vgs[entry.device.name] = entry.device > > # then set up the logical volumes >+ # Stripes first, then linear >+ linearEntries = [] > for entry in self.entries: > if isinstance(entry.device, LogicalVolumeDevice): >+ if not isinstance(entry.device, StripedLVD): >+ linearEntries.append(entry.device) > vg = None > if vgs.has_key(entry.device.vgname): > vg = vgs[entry.device.vgname] > entry.device.setupDevice(chroot, vgdevice = vg) >+ # then we add the linear volumes >+ for lentry in linearEntries: >+ vg = None >+ if vgs.has_key(lentry.vgname): >+ vg = vgs[lentry.vgname] >+ lentry.setupDevice(chroot, vgdevice = vg) >+ > self.volumesCreated = 1 > > >@@ -2280,25 +2291,79 @@ > class LogicalVolumeDevice(Device): > # note that size is in megabytes! > def __init__(self, vgname, size, lvname, vg, existing = 0): >+ """Create a new LogicalVolumeDevice Object >+ >+ vgname - Name of the volume group. >+ size - The Logical Volume Size (MB). >+ lvname - Name of logical Volume. >+ vg - The partition request. >+ existing - Whether the Logical Volume existed previously. >+ """ > Device.__init__(self) > self.vgname = vgname > self.size = size > self.name = lvname >- self.isSetup = 0 > self.isSetup = existing > self.doLabel = None > self.vg = vg > >- # these are attributes we might want to expose. or maybe not. >- # self.chunksize >- # self.stripes >- # self.stripesize >- # self.extents >- # self.readaheadsectors >+ def setupDevice(self, chroot="/", devPrefix='/tmp', vgdevice = None): >+ """This function must be implemented by the child classes.(StripedLVD, MirroredLVD, LinearLVD).""" >+ pass >+ >+ def getDevice(self, asBoot = 0): >+ return "%s/%s" % (self.vgname, self.name) >+ >+ def solidify(self): >+ return >+ >+class StripedLVD(LogicalVolumeDevice): >+ """Class Defenition for Striped Logical Volume Devices. """ >+ def __init__(self, vgname, size, lvname, vg, existing=0, pvs=[], stripeSize=4 ): >+ """Same as the LogicalVolumeDevice description. >+ >+ pvs - List of the physical volumes used for this striped logical volume. >+ The number of PV < (volume Group physical volumes) >+ stripeSize - The size in MB of the Stripes. (2^n)AND(2<n<9) >+ """ >+ LogicalVolumeDevice.__init__(self, vgname, size, lvname, vg, existing ) >+ self.usedpvs = pvs >+ self.stripeSize = stripeSize >+ >+ def setupDevice(self, chroot="/", devPrefix='/tmp', vgdevice=None): >+ if not self.isSetup: >+ lvm.writeForceConf() >+ devNum = len(self.usedpvs) >+ devString = "" >+ #Don't know how generic this is ...... >+ for dev in self.usedpvs:devString = devString+" /dev/"+str(dev) >+ log.debug("lvcreate -i%d -I%d -L %dM -n %s -An %s %s" % (devNum, self.stripeSize, self.size, self.name, self.vgname, devString)) >+ argument = ["lvcreate", "-i%d" % devNum,"-I%d" % self.stripeSize, >+ "-L", "%dM" % self.size,"-n", self.name, "-An",self.vgname] >+ for dev in self.usedpvs: >+ argument.append("%s"%"/dev/"+str(dev)) >+ rc = iutil.execWithRedirect("lvm",argument, >+ stdout = "/tmp/lvmout", >+ stderr = "/tmp/lvmout", >+ searchPath = 1) >+ if rc: >+ raise SystemError, "Striped lvcreate failed for %s" %(self.name,) >+ lvm.unlinkConf() >+ self.isSetup = 1 >+ >+ if vgdevice and vgdevice.isNetdev(): self.setAsNetdev() >+ return "/dev/%s" % (self.getDevice(),) >+ >+class LinearLVD(LogicalVolumeDevice): >+ """Class Definition for Linear Logical Volume Devices. """ >+ def __init__(self, vgname, size, lvname, vg, existing = 0 ): >+ """Same as the LogicalVolumeDevice description.""" >+ LogicalVolumeDevice.__init__(self, vgname, size, lvname, vg, existing ) > > def setupDevice(self, chroot="/", devPrefix='/tmp', vgdevice = None): > if not self.isSetup: > lvm.writeForceConf() >+ log.debug("lvcreate -L %dM -n %s -An %s " % (self.size, self.name, self.vgname)) > rc = iutil.execWithRedirect("lvm", > ["lvcreate", "-L", > "%dM" % (self.size,), >@@ -2313,16 +2378,8 @@ > self.isSetup = 1 > > if vgdevice and vgdevice.isNetdev(): self.setAsNetdev() >- > return "/dev/%s" % (self.getDevice(),) > >- def getDevice(self, asBoot = 0): >- return "%s/%s" % (self.vgname, self.name) >- >- def solidify(self): >- return >- >- > class PartitionDevice(Device): > def __init__(self, partition): > Device.__init__(self) >diff -ubBr FC-6/iw/lvm_dialog_gui.py rfc6-3/iw/lvm_dialog_gui.py >--- FC-6/iw/lvm_dialog_gui.py 2006-07-21 20:51:56.000000000 +0200 >+++ rfc6-3/iw/lvm_dialog_gui.py 2007-03-06 14:33:40.000000000 +0100 >@@ -294,6 +294,26 @@ > "volumes."), custom_icon="error") > return False > >+ # Look at the used volumes of this volume group. >+ # This trick works if the self.currentRequest is None when changing the vg list. (it should be that way) >+ usedpvs = self.getUsedPhysicalVolumes() >+ if not val: >+ for devs in usedpvs: >+ if devs[0] == id and devs[1] > 0: >+ self.intf.messageWindow(_("Currently used physical volume."), >+ _("This selected physical volume is currently " >+ "being used by another logical volume. You " >+ "cannot unselect it."), custom_icon="error") >+ return False >+ # its being used by some other lv. Don't unselect >+ >+ # So the physicalVolume is consitent with the change >+ if val: >+ self.origvgrequest.physicalVolumes.append(id) >+ log.debug("ClickCB:have added pv %s to physicalVolumes %s " %(id, self.origvgrequest.physicalVolumes)) >+ else: >+ self.origvgrequest.physicalVolumes.remove(id) >+ log.debug("ClickCB:have removed pv %s from physicalVolumes %s " %(id, self.origvgrequest.physicalVolumes)) > self.updateVGSpaceLabels(alt_pvlist = pvlist) > return True > >@@ -309,6 +328,8 @@ > sw.add(partlist) > sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC) > sw.set_shadow_type(gtk.SHADOW_IN) >+ log.debug("CreateList:The current physical volume is %s " % self.origvgrequest.physicalVolumes) >+ self.origvgrequest.physicalVolumes = [] > > for part in alllvmparts: > uid = part[0] >@@ -333,7 +354,80 @@ > > if preexist == 0 or selected == 1: > partlist.append_row((partname, partsize), selected) >+ # For a new LV add the pvs to the physicalVolume Structure >+ if selected == 1: >+ self.origvgrequest.physicalVolumes.append(uid) >+ log.debug("CreateList:have added %s to the pv.physicalvolumes %s" % (uid,self.origvgrequest.physicalVolumes)) >+ log.debug("CreateList:The resulting is physical volume is %s " % self.origvgrequest.physicalVolumes) >+ >+ return (partlist, sw) >+ >+ def clickLPL(self, row, data): >+ """When the physical volume list is clicked in the create lv window. >+ >+ Just change the values. Any checking will be done when the lv is >+ being changed or created. >+ """ >+ model = self.templvlist.get_model() >+ iter = model.get_iter((string.atoi(data),)) >+ >+ # we invert val because we get called before checklist >+ # changes the toggle state >+ val = not model.get_value(iter, 0) >+ partname = model.get_value(iter, 1) >+ if val:# He is adding a physical volume >+ pvid = self.partitions.getRequestByDeviceName(partname).getId() >+ i=0 >+ for dev in self.lvpvs: >+ if dev[0] is pvid: >+ self.lvpvs[i] = (dev[0], dev[1], dev[2], 1) >+ log.debug("clickPL: dev %s used %s total %s selected %s " % (self.lvpvs[i][0], >+ self.lvpvs[i][1], self.lvpvs[i][2], self.lvpvs[i][3])) >+ break >+ i+=1 >+ else:# He is removing a physical volume >+ pvid = self.partitions.getRequestByDeviceName(partname).getId() >+ i=0 >+ for dev in self.lvpvs: >+ if dev[0] is pvid: >+ self.lvpvs[i] = (dev[0], dev[1], dev[2], 0) >+ log.debug("clickPL: dev %s used %s total %s selected %s " % (self.lvpvs[i][0], >+ self.lvpvs[i][1], self.lvpvs[i][2], self.lvpvs[i][3])) >+ break >+ i+=1 >+ >+ return True >+ >+ def createUsedLvmPartitionList(self): >+ """Create the widget that houses the selectable partitions. > >+ The used physical volumes of the current request must be made available. >+ """ >+ store = gtk.TreeStore(gobject.TYPE_BOOLEAN, #checkbox >+ gobject.TYPE_STRING, #device name >+ gobject.TYPE_STRING) #usable size >+ partlist = WideCheckList(2, store, self.clickLPL) >+ >+ # Get the physical volumes used by the volume group. >+ sw = gtk.ScrolledWindow() >+ sw.add(partlist) >+ sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC) >+ sw.set_shadow_type(gtk.SHADOW_IN) >+ j = 0 >+ for element in self.lvpvs: >+ dev = self.partitions.getRequestByID(element[0]) >+ # If the self.currentRequest is new the required size will be 0 >+ availSize = element[2] - element[1] >+ strSize = "%s" % availSize >+ name = "%s" % dev.device >+ if availSize == 0: >+ selected = 0 >+ self.lvpvs[j] = (element[0], element[1], element[2], 0) >+ else: >+ selected = 1 >+ self.lvpvs[j] = (element[0], element[1], element[2], selected) >+ partlist.append_row((name, strSize), selected) >+ j += 1 > return (partlist, sw) > > def updateAllowedLvmPartitionsList(self, alllvmparts, partitions, partlist): >@@ -364,8 +458,76 @@ > (model, iter) = selection.get_selected() > return iter > >+ def toggleTypeRadioButton(self, radioButton, args): >+ """Change only the gui and not the object. >+ >+ The object will run a sanity check and other tests >+ when it is added to the list of lvs. >+ """ >+ (type, ) = args >+ if type is LogicalVolumeRequestSpec.LINEAR_LVR: >+ self.stripedRB.set_active(False) >+ self.linearRB.set_active(True) >+ self.stripedEntry.set_text("") >+ self.stripedEntry.set_editable(False) >+ return True >+ elif type is LogicalVolumeRequestSpec.STRIPED_LVR: >+ self.linearRB.set_active(False) >+ self.stripedRB.set_active(True) >+ self.stripedEntry.set_editable(True) >+ self.stripedEntry.set_text("4")# 4 is the default value. shouldn't be here. >+ return True >+ >+ def getUsedPhysicalVolumes(self): >+ """Returns the Physical Volume structure. >+ >+ This Strucutre expresses which physical volumes are being used by the >+ Logical volumes in the Volume group and how much memory each one has. >+ Also keeps the selected or unselected state in the lv pvlist. >+ """ >+ tempPV = {} >+ # The pv of the current vg. >+ log.debug("getUsedPhysicalVolumes: current self.origvgrequest.physicalVolumes %s " % self.origvgrequest.physicalVolumes) >+ for pvid in self.origvgrequest.physicalVolumes: >+ pvreq = self.partitions.getRequestByID(pvid) >+ size = pvreq.getActualSize(self.partitions, self.diskset) >+ size = lvm.clampPVSize(size, self.origvgrequest.pesize) -\ >+ (self.origvgrequest.pesize/1024) >+ tempPV[pvid] = (pvid, 0, size) >+ >+ # Look at al the lv in the vg. >+ for request in self.logvolreqs: >+ # If currently editing a lv don't count its used space. >+ if self.currentRequest is not None and self.currentRequest is request: >+ log.debug("getUsedPhysicalVolumes: ignored currentRequest") >+ continue >+ reqUsedDevs = request.getUsedPhysicalVolumes() >+ # Analyze all physical volumes for this logical volume request. >+ for dev in reqUsedDevs: >+ if not tempPV.has_key(dev[0]):tempPV[dev[0]] = dev# New entry. >+ else:tempPV[dev[0]] = (tempPV[dev[0]][0], tempPV[dev[0]][1]+dev[1], >+ tempPV[dev[0]][2])# Add used space. >+ # At start all the pv that are not 0 will be selected. >+ for key in tempPV: >+ if tempPV[key][1] is tempPV[key][2]: >+ tempPV[key] = (tempPV[key][0], tempPV[key][1], tempPV[key][2], 0)#not selected >+ elif 0 <= tempPV[key][2] - tempPV[key][1] <= tempPV[key][2]: >+ tempPV[key] = (tempPV[key][0], tempPV[key][1], tempPV[key][2], 1)#selected >+ else: >+ log.debug("getUsedPhysicalVolumes: enter the twilite zone used %s total %s " % (tempPV[key][1], tempPV[key][2])) >+ return [] >+ >+ # Create a list of sets. >+ retVal = [] >+ for key in tempPV:retVal.append(tempPV[key]) >+ log.debug("getUsedPhysicalvolumes: returnValue %s" % retVal) >+ return retVal > > def editLogicalVolume(self, logrequest, isNew = 0): >+ >+ # Refresh lvpvs for current lv. >+ self.lvpvs = self.getUsedPhysicalVolumes() >+ > if isNew: > tstr = _("Make Logical Volume") > else: >@@ -440,16 +602,58 @@ > > if not logrequest or not logrequest.getPreExisting(): > lbl = createAlignedLabel(_("_Size (MB):")) >- sizeEntry = gtk.Entry(16) >- lbl.set_mnemonic_widget(sizeEntry) >- if logrequest: >- sizeEntry.set_text("%g" % (logrequest.getActualSize(self.partitions, self.diskset),)) >+ self.sizeEntry = gtk.Entry(16) >+ lbl.set_mnemonic_widget(self.sizeEntry) >+ self.sizeEntry.set_text( "%s" % logrequest.getRequiredSize()) > else: > lbl = createAlignedLabel(_("Size (MB):")) >- sizeEntry = gtk.Label(str(logrequest.size)) >+ self.sizeEntry = gtk.Label(str(logrequest.size)) > > maintable.attach(lbl, 0, 1, row, row+1) >- maintable.attach(sizeEntry, 1, 2, row, row + 1) >+ maintable.attach(self.sizeEntry, 1, 2, row, row + 1) >+ row += 1 >+ >+ if not logrequest or not logrequest.getPreExisting(): >+ # FIXME: There is a warning to do with an assertion. >+ # We create the buttons for linear and striped functionalities >+ hbox = gtk.HBox() >+ # Radio button for the linear lv. >+ self.linearRB = gtk.RadioButton(group=None, label="Linear") >+ self.linearRB.connect("pressed", self.toggleTypeRadioButton, >+ (LogicalVolumeRequestSpec.LINEAR_LVR, )) >+ if logrequest.getType() is LogicalVolumeRequestSpec.LINEAR_LVR: >+ self.linearRB.set_active(True) >+ hbox.pack_start(self.linearRB, False, False) >+ # Radio button for the striped lv. >+ self.stripedRB = gtk.RadioButton(group=self.linearRB, label="Striped") >+ self.stripedRB.connect("pressed", self.toggleTypeRadioButton, >+ (LogicalVolumeRequestSpec.STRIPED_LVR, )) >+ if logrequest.getType() is LogicalVolumeRequestSpec.STRIPED_LVR: >+ self.stripedRB.set_active(True) >+ hbox.pack_start(self.stripedRB, False, False) >+ # Add box to maintable. >+ #maintable.attach(lbl, 0, 1, row, row+1) >+ maintable.attach(hbox, 1, 2, row, row+1) >+ row += 1 >+ >+ # We create the windo that will show all the physical volumes >+ (self.templvlist, sw) = self.createUsedLvmPartitionList() >+ self.templvlist.set_size_request(275, 80) >+ lbl = createAlignedLabel(_("Physical Volumes to Use:")) >+ lbl.set_mnemonic_widget(self.templvlist) >+ maintable.attach(lbl, 0, 1, row, row + 1) >+ maintable.attach(sw, 1, 2, row, row + 1) >+ row = row + 1 >+ >+ lbl = createAlignedLabel(_("StripSize (MB):")) >+ self.stripedEntry = gtk.Entry() >+ self.stripedEntry.set_max_length(3) >+ self.stripedEntry.set_editable(False) >+ if logrequest.getType() is LogicalVolumeRequestSpec.STRIPED_LVR: >+ self.stripedEntry.set_editable(True) >+ self.stripedEntry.set_text("%s" % logrequest.getStripedSize()) >+ maintable.attach(lbl, 0, 1, row, row+1) >+ maintable.attach(self.stripedEntry, 1, 2, row, row + 1) > row += 1 > > if not logrequest or not logrequest.getPreExisting(): >@@ -516,7 +720,7 @@ > # check size specification > badsize = 0 > try: >- size = long(sizeEntry.get_text()) >+ size = long(self.sizeEntry.get_text()) > except: > badsize = 1 > >@@ -677,6 +881,35 @@ > del tmplogreqs > continue > >+ if not logrequest.getPreExisting(): >+ # create the pv used pv list from the self.lvpvs variable. >+ usedPV = [] >+ for element in self.lvpvs: >+ if element[3] == 1: >+ usedPV.append(element[0]) >+ if self.linearRB.get_active(): >+ usedType=LogicalVolumeRequestSpec.LINEAR_LVR >+ usedStripeSize = None >+ elif self.stripedRB.get_active(): >+ usedType=LogicalVolumeRequestSpec.STRIPED_LVR >+ usedStripeSize = self.stripedEntry.get_text() >+ usedSize = self.sizeEntry.get_text() >+ >+ result = request.changeState(usedPV, >+ usedType, >+ usedSize, >+ usedStripeSize, >+ self.partitions, >+ self.diskset, >+ self.logvolreqs, >+ self.origvgrequest) >+ if not result[0]: >+ errorMessage = result[1] >+ self.intf.messageWindow(errorMessage[0], >+ errorMessage[1], >+ custom_icon=errorMessage[2]) >+ continue >+ > # everything ok > break > >@@ -698,6 +931,9 @@ > self.logvolstore.set_value(iter, 2, "%g" % (size,)) > > self.updateVGSpaceLabels() >+ self.currentRequest = None >+ # the self.lvpvs is invalid ouside the lv editing. >+ self.lvpvs = None > dialog.destroy() > > def editCurrentLogicalVolume(self): >@@ -715,7 +951,8 @@ > if logrequest is None: > return > >- self.editLogicalVolume(logrequest) >+ self.currentRequest = logrequest >+ self.editLogicalVolume(self.currentRequest) > > def addLogicalVolumeCB(self, widget): > if self.numAvailableLVSlots() < 1: >@@ -736,9 +973,14 @@ > "logical volumes"), custom_icon="error") > return > >- request = LogicalVolumeRequestSpec(fileSystemTypeGetDefault(), >- size = fspace) >- self.editLogicalVolume(request, isNew = 1) >+ # Get the current selected devices. >+ devs = [] >+ for dev in self.getSelectedPhysicalVolumes(self.lvmlist.get_model()):devs.append((dev,0)) >+ self.currentRequest = LogicalVolumeRequestSpec(fileSystemTypeGetDefault(), >+ size = fspace, >+ volgroup=self.origvgrequest.uniqueID, >+ devs=devs) >+ self.editLogicalVolume(self.currentRequest, isNew = 1) > return > > def editLogicalVolumeCB(self, widget): >@@ -947,6 +1189,23 @@ > self.logvolreqs = self.partitions.getLVMLVForVG(self.origvgrequest) > self.origvolreqs = copy.copy(self.logvolreqs) > >+ >+ # self.lvpvs contains the total and use size of the pv and wether its selected. >+ # set the varialbe when you enter the lv editing, unset it on exit. >+ # [(dev,totalSize, usedSizebylv, selected)...] >+ # self.lvpvs is only used in the lv editing. >+ self.lvpvs = None >+ # Variable for current lv request. >+ self.currentRequest = None >+ >+ # All gtk objects are class attributes. (so I can access them in any class method.) >+ # Only the needed lv editing window objects will be here. >+ self.sizeEntry = None >+ self.linearRB = None >+ self.stripedRB = None >+ self.templvlist = None >+ self.stripedEntry = None >+ > # if no PV exist, raise an error message and return > if len(self.availlvmparts) < 1: > self.intf.messageWindow(_("Not enough physical volumes"), >diff -ubBr FC-6/lvm.py rfc6-3/lvm.py >--- FC-6/lvm.py 2006-07-12 15:59:19.000000000 +0200 >+++ rfc6-3/lvm.py 2007-03-05 11:16:58.000000000 +0100 >@@ -25,7 +25,7 @@ > from constants import * > > MAX_LV_SLOTS=256 >- >+VALID_STRIPE_SIZE = ["2", "4", "8", "16", "32", "64", "128", "256"] > output = "/tmp/lvmout" > > lvmDevicePresent = 0 >diff -ubBr FC-6/partRequests.py rfc6-3/partRequests.py >--- FC-6/partRequests.py 2007-02-19 16:22:06.000000000 +0100 >+++ rfc6-3/partRequests.py 2007-03-06 15:09:45.000000000 +0100 >@@ -17,6 +17,7 @@ > # > """Partition request objects and management thereof.""" > >+import copy > import parted > import iutil > import string >@@ -172,6 +173,9 @@ > "fsopts": self.fsopts}) > return str > >+ def getId(self): >+ return self.uniqueID >+ > def getActualSize(self, partitions, diskset): > """Return the actual size allocated for the request in megabytes.""" > >@@ -704,7 +708,7 @@ > """Request to represent volume group devices.""" > > def __init__(self, fstype =None, format = None, >- vgname = None, physvols = None, >+ vgname = None, physvols = [], > pesize = 32768, preexist = 0, > preexist_size = 0): > """Create a new VolumeGroupRequestSpec object. >@@ -807,12 +812,18 @@ > return str > > class LogicalVolumeRequestSpec(RequestSpec): >- """Request to represent logical volume devices.""" >+ """Request to represent logical volume devices. >+ >+ This request must consider Linear, Striped and Mirrored Logical Volumes >+ """ >+ LINEAR_LVR = 1 >+ STRIPED_LVR = 2 >+ MIRRORED_LVR = 3 > > def __init__(self, fstype, format = None, mountpoint = None, > size = None, volgroup = None, lvname = None, > preexist = 0, percent = None, grow=0, maxSizeMB=0, >- bytesPerInode = 4096, fslabel = None): >+ bytesPerInode = 4096, fslabel = None, devs=[], sizeStripes=0): > """Create a new VolumeGroupRequestSpec object. > > fstype is the fsset filesystem type. >@@ -827,8 +838,17 @@ > maxSizeMB is max size to grow to. > bytesPerInode is the size of the inodes on the partition. > fslabel is the label of the filesystem on the logical volume. >+ devs - Its a list of the ids of the devices that make up the VolumeGroup. >+ This can be set for both Linear and Striped Logical Volumes >+ Structure -> [(<deviceID>, <UsedSizeByThisLogicalVolume>),..] >+ sizeStripes - The size of each stripe. This value must be (2^n)AND(2<n<9). >+ If the variable is set to 0 there is no stripes. > """ > >+ # Types of Logical Volume Requests >+ self.typeRequest = 0 >+ if sizeStripes == 0:self.typeRequest = self.LINEAR_LVR >+ else:self.typeRequest = self.STRIPED_LVR > # if it's preexisting, the original fstype should be set > if preexist == 1: > origfs = fstype >@@ -853,6 +872,10 @@ > self.grow = grow > self.maxSizeMB = maxSizeMB > self.startSize = size >+ self.reqSize = self.startSize >+ self.devs = devs >+ self.sizeStripes = sizeStripes >+ self.Clone = None > > 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) >@@ -884,13 +908,27 @@ > return str > > def getDevice(self, partitions): >- """Return a device which can be solidified.""" >+ """Return a device which can be solidified. >+ >+ Depending on the request the Device class will be called. >+ """ >+ > vg = partitions.getRequestByID(self.volumeGroup) > vgname = vg.volumeGroupName >- self.dev = fsset.LogicalVolumeDevice(vgname, self.size, >- self.logicalVolumeName, >- vg = vg, >- existing = self.preexist) >+ if self.typeRequest is self.LINEAR_LVR: >+ # Its a linear LV. >+ self.dev = fsset.LinearLVD(vgname, self.size, self.logicalVolumeName, >+ vg=vg, existing=self.preexist) >+ else: >+ # Its a striped LV. >+ # Construct the Device structure >+ devNames = [] >+ for pvid in self.devs: >+ d = partitions.getRequestByID(pvid[0]) >+ devNames.append(d.device) >+ self.dev = fsset.StripedLVD(vgname, self.reqSize, self.logicalVolumeName, >+ vg=vg, existing=self.preexist, >+ pvs=devNames, stripeSize=self.sizeStripes) > return self.dev > > def getActualSize(self, partitions, diskset): >@@ -899,7 +937,6 @@ > 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 > else: > return self.size >@@ -918,6 +955,121 @@ > > self.size = size > >+ def getUsedSpaceInVG(self, lvlist): >+ """Returns the space used by all the lvs in the vg.""" >+ tempDevs = {} >+ #and that are free in the volume group. >+ for lv in lvlist: >+ if lv.logicalVolumeName != self.logicalVolumeName: >+ devs = lv.getUsedPhysicalVolumes() >+ for dev in devs: >+ if tempDevs.has_key(dev[0]):#add to the total size >+ tempDevs[dev[0]] = (dev[0], dev[1]+tempDevs[dev[0]][1]) >+ else:#create a new one >+ tempDevs[dev[0]] = dev >+ return tempDevs >+ >+ def getPossibleLinearSize(self, partition, diskset, lvlist, volgroup): >+ """It is the maximum size that it can grow to. >+ >+ Look at all the selected devices and do the math: free = total - taken. >+ partirion - Partition object >+ diskset - Diskset object >+ lvlist - The current working lv list >+ volgroup - The volume group Object >+ >+ Return - maximum size that can be used for a linear volume >+ """ >+ tempDevs = self.getUsedSpaceInVG(lvlist) >+ retVal = 0 >+ for dev in self.devs: >+ #what is the total space for this Physical Volume? >+ pvreq = partition.getRequestByID(dev[0]) >+ size = pvreq.getActualSize(partition, diskset) >+ size = lvm.clampPVSize(size, volgroup.pesize) - (volgroup.pesize/1024) >+ additional = 0 >+ if tempDevs.has_key(dev[0]):additional=tempDevs[dev[0]][1] >+ #totalSize - (totalUsedSize+lvUsedSize) >+ retVal += (size - additional) >+ log.debug("getPossibleLinearSize: returnSize %s " % retVal) >+ return retVal >+ >+ def getPossibleStripedSize(self, partition, diskset, lvlist, volgroup): >+ """Maximum size of a striped lv with the current variables. >+ >+ Take the smallest availabe size in the selected physical volumes >+ and multiply it by the number of physical volumes selected. """ >+ # If there are no devices there is no size. >+ if len(self.devs) < 2:return 0 >+ >+ tempDevs = self.getUsedSpaceInVG(lvlist) >+ log.debug("getPossibleStripedSize: space taken by other lvs %s " % tempDevs) >+ >+ # Find out what the smallest available size is. >+ retVal = 0 >+ for dev in self.devs: >+ pvreq = partition.getRequestByID(dev[0]) >+ size = pvreq.getActualSize(partition, diskset) >+ size = lvm.clampPVSize(size, volgroup.pesize) - (volgroup.pesize/1024) >+ used = 0 >+ if tempDevs.has_key(dev[0]):used=tempDevs[dev[0]][1] >+ if retVal == 0:retVal = (size - used) >+ else:retVal = min(retVal, (size - used)) >+ retVal = retVal * len(self.devs) >+ log.debug("getPossibleStripedSize: returnSize %s " % retVal) >+ return retVal >+ >+ def getRequiredSize(self): >+ """Its the size that the requester wants for the logical volume.""" >+ return self.reqSize >+ >+ def setRequiredSize(self, size, partition, diskset, lvlist, volgroup): >+ """Change the size of the lv request. >+ >+ Be sure that the required sizes are ok and but dont change the devs var. >+ size - The final size >+ partition - The partition object >+ diskset - The diskset object >+ lvlist - A list of current logical volumes for the vg. >+ volgroup - the volgroup object. >+ """ >+ try: >+ size = int(size) >+ except: >+ errorMessage = (_("Cannot use the specified size."), >+ _("The size format is invalid, try changing the " >+ "size."), >+ "error") >+ log.debug("The set size was not an int") >+ return (False, errorMessage) >+ >+ if self.typeRequest is self.LINEAR_LVR: >+ ps = self.getPossibleLinearSize(partition, diskset, lvlist, volgroup) >+ if size <= ps: >+ self.reqSize = long(size) >+ log.debug("setRequiredSize: set size to %s " % self.reqSize) >+ return (True,None) >+ else: >+ errorMessage = (_("Cannot use size."), >+ _("Not enough free space in the logical volume. Try adding " >+ "a physical volume or changing the required size. "), >+ "error") >+ log.debug("The set size was less than possible linear size") >+ return (False, errorMessage) >+ elif self.typeRequest is self.STRIPED_LVR: >+ ps = self.getPossibleStripedSize(partition, diskset, lvlist, volgroup) >+ if size <= ps: >+ self.reqSize = long(size) >+ log.debug("setRequieredSize: set size to %s " % self.reqSize) >+ return (True,None) >+ else: >+ errorMessage = (_("Cannot use size for striped logical volume."), >+ _("Not enough free space on the logical volume. " >+ "Try adding a physical volume or reducing its size."), >+ "error") >+ log.debug("The set size was less than possible striped size") >+ return (False, errorMessage) >+ > def sanityCheckRequest(self, partitions, skipMntPtExistCheck=0, pesize=32768): > """Run the basic sanity checks on the request.""" > if not self.grow and not self.percent and self.size*1024 < pesize: >@@ -925,3 +1077,320 @@ > "group's physical extent size.") > > return RequestSpec.sanityCheckRequest(self, partitions, skipMntPtExistCheck) >+ >+ def getType(self): >+ return self.typeRequest >+ >+ def setType(self, type, partition, diskset, lvlist, volgroup): >+ """Change the type of the lv. >+ >+ partition - The partition object. >+ diskset - The diskset object. >+ lvlist - the list of all the logical volumes in the volume group. >+ volgroup - The volume gruop object representing the current activity >+ in the editing window. >+ >+ Return - (changed/notchanged, error message). >+ """ >+ if type is self.LINEAR_LVR: >+ log.debug("setType: changing to linear") >+ # Make sure that the required space is there. >+ pls = self.getPossibleLinearSize(partition, diskset, lvlist, volgroup) >+ if pls > 0: >+ # It is possible to change to a linear type. >+ self.typeRequest = type >+ log.debug("setType: possible size is %s changed to type %s " %(pls, self.typeRequest)) >+ return (True, None) >+ else: >+ errorMessage = (_("You cannot change to a linear partition."), >+ _("Currently there is no space for the " >+ "partition in the logical volume."), >+ "error") >+ log.debug("setType: there are no physical volumes") >+ return (False, errorMessage) >+ elif type is self.STRIPED_LVR: >+ log.debug("setType: changing to striped") >+ if len(self.devs) < 2: >+ errorMessage = (_("You cannot change to striped partition."), >+ _("There are not enough physical volumes for " >+ "the partition. Try adding a physical volume."), >+ "error") >+ log.debug("setType: There is less than 2 devices") >+ return (False, errorMessage) >+ else: >+ pls = self.getPossibleStripedSize(partition, diskset, lvlist, volgroup) >+ if pls > 0: >+ # It is possible to have a linear Volume. >+ self.typeRequest = type >+ log.debug("setType: possible size is %s changed to type %s " %(pls, self.typeRequest)) >+ return (True, None) >+ else: >+ errorMessage = (_("You cannot change to a striped partition."), >+ _("Currently there is no space for the " >+ "partition in the logical volume."), >+ "error") >+ log.debug("setType: the required size %s is less than the possible striped size %s " % ( self.reqSize, pls)) >+ return(False, errorMessage) >+ else: >+ errorMessage = (_("You cannot change the partition."), >+ _("The specified type is not a valid one."), >+ "error") >+ return (False, errorMessage) >+ >+ def getUsedPhysicalVolumes(self): >+ return self.devs >+ >+ def addUsedPhysicalVolume(self, pvname, partition, pvid=None, vg=None): >+ """Add a physical volume to the self.devs list. >+ >+ pvname - The name of the device >+ partition - the partition object >+ pvid - The id of the device >+ """ >+ if pvid is None: >+ pvid = partition.getRequestByDeviceName(pvname).uniqueID >+ if vg is None: >+ vg = partition.getRequestByID(self.volumeGroup) >+ # If self has it, don't add it. >+ for dev in self.devs: >+ if pvid is dev[0]:#its already included >+ return(True,) >+ if pvid not in vg.physicalVolumes: >+ # It cannot be appended. >+ errorMessage = (_("Not in Volume Group physical volumes."), >+ _("You cannot add a physical volume that " >+ "is not in the volume group List."), >+ "error") >+ log.debug("addUsedPhysicalVolume: cannot find %s in vg" % pvid) >+ return (False, errorMessage) >+ else: >+ log.debug("addUsedPhysicalVolume: going to add with 0 used size %s to list %s " %( pvid,self.devs)) >+ self.devs.append( (pvid,0) ) >+ return (True,) >+ >+ def removeUsedPhysicalVolume(self, pvname, partitions, diskset, lvlist, >+ volgroup, pvid=None): >+ """It can be remove if the logical volume is not using it >+ >+ pvname - The name of the device >+ partitions - the partition object >+ pvid - The id of the device >+ """ >+ if pvid is None: >+ pvid = partitions.getRequestByDeviceName(pvname).uniqueID >+ >+ #Check if it even exists. >+ found = False >+ for dev in self.devs: >+ if pvid is dev[0]: >+ found = True >+ break >+ if not found:return (True, None) >+ >+ temp = [] >+ for dev in self.devs: >+ if dev[0] != pvid: >+ temp.append((dev[0],0)) >+ self.devs = temp >+ temp = [] >+ log.debug("removeUsedPhysicalVolume: devs - %s" % self.devs) >+ return (True, None) >+ >+ def clone(self): >+ """Makes a copy of itself in a point in time.""" >+ self.Clone = copy.copy(self) >+ >+ def revertToClone(self): >+ """Change the current object to its former self.""" >+ if self.Clone is not None: >+ self = self.Clone >+ >+ def eraseClone(self): >+ """Dereference the copy of the curren object.""" >+ self.Clone = None >+ >+ def setStripedSize(self, size): >+ """Change the strip size of the request.""" >+ if size not in lvm.VALID_STRIPE_SIZE: >+ errorMessage = (_("Error adding locial volume."), >+ _("The striped size mush be one of the following numbers: " >+ "%s, %s, %s, %s, %s, %s, %s, %s.") % \ >+ (lvm.VALID_STRIPE_SIZE[0], >+ lvm.VALID_STRIPE_SIZE[1], >+ lvm.VALID_STRIPE_SIZE[2], >+ lvm.VALID_STRIPE_SIZE[3], >+ lvm.VALID_STRIPE_SIZE[4], >+ lvm.VALID_STRIPE_SIZE[5], >+ lvm.VALID_STRIPE_SIZE[6], >+ lvm.VALID_STRIPE_SIZE[7]), >+ "error") >+ return (False, errorMessage) >+ >+ try: >+ size = int(size) >+ except: >+ errorMessage = (_("Cannot use specified stripe size."), >+ _("The size format is invalid, try changing the " >+ "size in entry."), >+ "error") >+ return (False, errorMessage) >+ self.sizeStripes = size >+ return (True, None) >+ >+ def getStripedSize(self): >+ return self.sizeStripes >+ >+ def pruneObject(self, partition, diskset, volgroup): >+ """just check if additional physical volumes can be eliminated.""" >+ # Take out all devices that have no memory asigned to them. >+ temp = [] >+ for dev in self.devs: >+ if dev[1] > 0: >+ temp.append((dev[0], dev[1])) >+ # Just in linear type we can eliminate physical volumes. >+ return True >+ >+ def assignDevSize(self, partitions, diskset, lvlist, volgroup): >+ """Assigns the size of each device in whatever state the object is in.""" >+ # We will work with a blank list of devices. >+ temp = [] >+ for dev in self.devs: >+ temp.append((dev[0],0)) >+ >+ tempDevs = self.getUsedSpaceInVG(lvlist) >+ log.debug("assignDevSize: The used space in VG is: %s " % tempDevs) >+ if self.typeRequest is self.LINEAR_LVR: >+ #asign the sizes to every physical volume. >+ allocatedSize = 0 >+ temp = [] >+ log.debug("assignDevSize: the reqSize is %s " % self.reqSize) >+ for dev in self.devs: >+ pvreq = partitions.getRequestByID(dev[0]) >+ sizeD = pvreq.getActualSize(partitions, diskset) >+ sizeD = lvm.clampPVSize(sizeD, volgroup.pesize) - (volgroup.pesize/1024) >+ # Don't use the whole size of the device. >+ if tempDevs.has_key(dev[0]): >+ sizeD -= tempDevs[dev[0]][1]# sizeD will represent the available size >+ if sizeD - (self.reqSize-allocatedSize) <= 0: >+ # we need another device >+ # assign and continue >+ temp.append((dev[0], sizeD)) >+ allocatedSize += sizeD >+ log.debug("assignDevSize: %s amount of devices %s was used" %(sizeD, dev[0])) >+ continue >+ else: >+ # The current device is enough >+ temp.append((dev[0], self.reqSize-allocatedSize)) >+ allocatedSize += self.reqSize-allocatedSize >+ log.debug("assignDevSize: %s amount of device %s was used" % (sizeD, dev[0])) >+ break >+ >+ if allocatedSize != self.reqSize: >+ # Something is wrong!!! >+ errorMessage = (_("Cannot create space in devices."), >+ _("The space required is larger than the possible " >+ "space given by physical volumes."), >+ "error") >+ log.debug("assignDevSize: allocated size is %s self.reqSize is %s " % ( allocatedSize, self.reqSize)) >+ return (False, errorMessage) >+ log.debug("assignDevSize: the allocated size is %s " % allocatedSize ) >+ self.devs = temp >+ return (True, None) >+ else: >+ assignedSize = self.reqSize / len(self.devs) >+ temp = [] >+ # Should be ok but might have round up problems >+ log.debug("assignDevSize: size per device %s, number devices %s, self.reqSize %s " % (assignedSize, len(self.devs), self.reqSize)) >+ for dev in self.devs: >+ pvreq = partitions.getRequestByID(dev[0]) >+ sizeD = pvreq.getActualSize(partitions, diskset) >+ sizeD = lvm.clampPVSize(sizeD, volgroup.pesize) - (volgroup.pesize/1024) >+ # Don't use the whole size of the device. >+ if tempDevs.has_key(dev[0]): >+ sizeD -= tempDevs[dev[0]][1] >+ if sizeD < assignedSize: >+ # Something is wrong!!! >+ errorMessage = (_("Cannot create space in devices."), >+ _("The space required is larger than the possible " >+ "space given by physical volumes."), >+ "error") >+ log.debug("assignDevSize: free dev size %s, self.reqSize %s " % (sizeD, self.reqSize)) >+ return (False, errorMessage) >+ temp.append((dev[0],assignedSize)) >+ log.debug("%s size was used of device %s" % (assignedSize, dev[0])) >+ self.devs = temp >+ temp=[] >+ return (True, None) >+ >+ def changeState(self, pvs, type, size, stripeSize, >+ partitions, diskset, lvlist, volgroup): >+ """This function is the interface to the outside. >+ >+ pvs - A list of ids to which the lv is related. >+ type - The final type of the lv. >+ size - The final size of the lv. >+ stripeSize - The size of the stripes. >+ partitions - The partitions object. >+ diskset - The diskset object. >+ lvlist - The list of lv in vg. >+ volgroup - The volume group object. >+ """ >+ # Before changing clone valid object. >+ self.clone() >+ result = (True, (_(""), _(""),"result")) >+ >+ # 1.Add the physicalVolume. >+ for pv in pvs: >+ result = self.addUsedPhysicalVolume(None, partitions, pv, vg=volgroup) >+ if not result[0]:break >+ if not result[0]: >+ self.revertToClone() >+ return result >+ >+ # 2.Remove physical Volumes. >+ for dev in self.devs: >+ if dev[0] not in pvs: >+ result = self.removeUsedPhysicalVolume(None, partitions, diskset, lvlist, volgroup, pvid=dev[0]) >+ if not result[0]:break >+ if not result[0]: >+ self.revertToClone() >+ return result >+ >+ # 3.Change Type. >+ result = self.setType(type, partitions, diskset, lvlist, volgroup) >+ if not result[0]: >+ self.revertToClone() >+ return result >+ >+ # 4.Add size. >+ result = self.setRequiredSize(size, partitions, diskset, lvlist, volgroup) >+ if not result[0]: >+ self.revertToClone() >+ return result >+ >+ # 5.Add striped. >+ if self.getType() is self.STRIPED_LVR and stripeSize != None: >+ result = self.setStripedSize(stripeSize) >+ elif self.getType() is self.STRIPED_LVR: >+ result = self.setStripedSize(4) >+ if not result[0]: >+ self.revertToClone() >+ return result >+ >+ # 6.Modify dev size. >+ result = self.assignDevSize(partitions, diskset, lvlist, volgroup) >+ if not result[0]: >+ self.revertToClone() >+ return result >+ >+ # 7.Prune Object. >+ self.pruneObject(partitions, diskset, volgroup) >+ >+ # 8.Make compatible. >+ self.makeCompatible() >+ self.eraseClone() >+ return result >+ >+ def makeCompatible(self): >+ # Equal the sizes.... >+ self.size = self.reqSize
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 134638
:
149349
| 149352 |
150144
|
150145