diff options
-rw-r--r-- | iw/partition_gui.py | 8 | ||||
-rw-r--r-- | platform.py | 2 | ||||
-rw-r--r-- | storage/__init__.py | 4 | ||||
-rw-r--r-- | storage/deviceaction.py | 8 | ||||
-rw-r--r-- | storage/devices.py | 173 | ||||
-rw-r--r-- | storage/devicetree.py | 242 | ||||
-rw-r--r-- | storage/partitioning.py | 92 |
7 files changed, 186 insertions, 343 deletions
diff --git a/iw/partition_gui.py b/iw/partition_gui.py index bffc5a9ec..831c04dc8 100644 --- a/iw/partition_gui.py +++ b/iw/partition_gui.py @@ -797,16 +797,14 @@ class PartitionWindow(InstallWindow): self.tree[drvparent]['Device'] = _("Hard Drives") for disk in disks: # add a disk stripe to the graph - stripe = self.diskStripeGraph.add(disk.name, disk.partedDisk) + stripe = self.diskStripeGraph.add(disk.name, disk.format.partedDisk) # add a parent node to the tree parent = self.tree.append(drvparent) self.tree[parent]['Device'] = "%s" % disk.path self.tree[parent]['PyObject'] = disk - (cylinders, heads, sectors) = disk.partedDisk.device.biosGeometry - sectorsPerCyl = heads * sectors - part = disk.partedDisk.getFirstPartition() + part = disk.format.firstPartition extendedParent = None while part: if part.type & parted.PARTITION_METADATA: @@ -982,7 +980,7 @@ class PartitionWindow(InstallWindow): devices. This will need some work when that time comes. """ device = self.tree.getCurrentDevice() - if hasattr(device, "partedDisk"): + if device.format.type == "disklabel": if doDeleteDependentDevices(self.intf, self.storage, device): diff --git a/platform.py b/platform.py index 7e8e34f0b..2c3e8cfc7 100644 --- a/platform.py +++ b/platform.py @@ -258,7 +258,7 @@ class Alpha(Platform): if not disk: raise DeviceError("Boot partition has no disk") - disk = disk.partedDisk + disk = disk.format.partedDisk # Check that we're a BSD disk label if not disk.type == self.diskType.name: diff --git a/storage/__init__.py b/storage/__init__.py index 094c079d6..e30182b8b 100644 --- a/storage/__init__.py +++ b/storage/__init__.py @@ -238,7 +238,7 @@ class Storage(object): else: if hasattr(boot, "bootable"): boot.bootable = True - boot.disk.commit() + boot.disk.format.commit() @property def nextID(self): @@ -697,7 +697,7 @@ class Storage(object): def extendedPartitionsSupported(self): """ Return whether any disks support extended partitions.""" for disk in self.disks: - if disk.partedDisk.supportsFeature(parted.DISK_TYPE_EXTENDED): + if disk.format.partedDisk.supportsFeature(parted.DISK_TYPE_EXTENDED): return True return False diff --git a/storage/deviceaction.py b/storage/deviceaction.py index 838b5007f..df84c2d04 100644 --- a/storage/deviceaction.py +++ b/storage/deviceaction.py @@ -264,7 +264,7 @@ class ActionCreateFormat(DeviceAction): if isinstance(self.device, PartitionDevice): if self.format.partedFlag is not None: self.device.setFlag(self.format.partedFlag) - self.device.disk.commit() + self.device.disk.format.commit() udev_settle() self.device.setup() @@ -308,11 +308,11 @@ class ActionDestroyFormat(DeviceAction): def execute(self, intf=None): """ wipe the filesystem signature from the device """ if self.origFormat: - if isinstance(self.device, PartitionDevice) and \ + if isinstance(self._device, PartitionDevice) and \ self.origFormat.partedFlag is not None: # unset partition flags and commit - self.device.unsetFlag(self.origFormat.partedFlag) - self.device.disk.commit() + self._device.unsetFlag(self.origFormat.partedFlag) + self._device.disk.format.commit() udev_settle() # set up our copy of the original device stack since the diff --git a/storage/devices.py b/storage/devices.py index 3b4de0b48..3cb65aa0b 100644 --- a/storage/devices.py +++ b/storage/devices.py @@ -236,9 +236,7 @@ class Device(object): """ new = self.__class__.__new__(self.__class__) memo[id(self)] = new - shallow_copy_attrs = ('_partedDisk', '_partedDevice', - '_partedPartition', '_origPartedDisk', - '_raidSet') + shallow_copy_attrs = ('_partedDevice', '_partedPartition', '_raidSet') for (attr, value) in self.__dict__.items(): if attr in shallow_copy_attrs: setattr(new, attr, copy.copy(value)) @@ -451,9 +449,6 @@ class StorageDevice(Device): self.protected = False - # this may be handy for disk, dmraid, mpath, mdraid - self.diskLabel = None - self.format = format self.fstabComment = "" self._targetSize = self._size @@ -490,12 +485,12 @@ class StorageDevice(Device): s = Device.__str__(self) s += (" uuid = %(uuid)s format = %(format)r size = %(size)s\n" " major = %(major)s minor = %(minor)r exists = %(exists)s\n" - " sysfs path = %(sysfs)s label = %(diskLabel)s\n" + " sysfs path = %(sysfs)s partedDevice = %(partedDevice)r\n" " target size = %(targetSize)s path = %(path)s\n" " format args = %(formatArgs)s" % {"uuid": self.uuid, "format": self.format, "size": self.size, "major": self.major, "minor": self.minor, "exists": self.exists, - "sysfs": self.sysfsPath, "diskLabel": self.diskLabel, + "sysfs": self.sysfsPath, "partedDevice": self.partedDevice, "targetSize": self.targetSize, "path": self.path, "formatArgs": self.formatArgs}) return s @@ -715,78 +710,19 @@ class DiskDevice(StorageDevice): parents -- a list of required Device instances removable -- whether or not this is a removable device - initcb -- the call back to be used when initiating disk. - initlabel -- whether to start with a fresh disklabel - DiskDevices always exist. """ StorageDevice.__init__(self, device, format=format, size=size, major=major, minor=minor, exists=True, sysfsPath=sysfsPath, parents=parents) - self._partedDisk = None - self._initlabel = initlabel - self._initcb = initcb - - # We save the actual state of the disk here. Before the first - # modification (addPartition or removePartition) to the partition - # table we reset self.partedPartition to this state so we can - # perform the modifications one at a time. - if self.partedDisk: - self._origPartedDisk = self.partedDisk.duplicate() - else: - self._origPartedDisk = None - - - @property - def partedDisk(self): - if self._partedDisk: - return self._partedDisk - - log.debug("looking up parted Device: %s" % self.path) - - if self.partedDevice: - log.debug("creating parted Disk: %s" % self.path) - if self._initlabel: - self._partedDisk = self.freshPartedDisk() - else: - try: - self._partedDisk = parted.Disk(device=self.partedDevice) - except _ped.DiskLabelException: - # if we have a cb function use it. else an error. - if self._initcb is not None and self._initcb(): - self._partedDisk = parted.freshDisk( \ - device=self.partedDevice, \ - ty = platform.getPlatform(None).diskType) - else: - raise DeviceUserDeniedFormatError("User prefered to not format.") - - # When the device has no partition table but it has a FS, it - # will be created with label type loop. Treat the same as if - # the device had no label (cause it really doesn't). - if self._partedDisk.type == "loop": - if self._initcb is not None and self._initcb(): - self._partedDisk = parted.freshDisk( \ - device=self.partedDevice, \ - ty = platform.getPlatform(None).diskType) - else: - raise DeviceUserDeniedFormatError("User prefered to not format.") - - return self._partedDisk def __str__(self): s = StorageDevice.__str__(self) - s += (" removable = %(removable)s partedDevice = %(partedDevice)r\n" - " partedDisk = %(partedDisk)r" % - {"removable": self.removable, "partedDisk": self.partedDisk, - "partedDevice": self.partedDevice}) + s += (" removable = %(removable)s partedDevice = %(partedDevice)r" % + {"removable": self.removable, "partedDevice": self.partedDevice}) return s - def freshPartedDisk(self): - log_method_call(self, self.name) - labelType = platform.getPlatform(None).diskType - return parted.freshDisk(device=self.partedDevice, ty=labelType) - @property def mediaPresent(self): return self.partedDevice is not None @@ -805,38 +741,6 @@ class DiskDevice(StorageDevice): return super(DiskDevice, self).size #size = property(StorageDevice._getSize) - def resetPartedDisk(self): - """ Reset parted.Disk to reflect the actual layout of the disk. """ - log_method_call(self, self.name) - self._partedDisk = self._origPartedDisk - - def removePartition(self, device): - log_method_call(self, self.name, part=device.name) - if not self.mediaPresent: - raise DeviceError("cannot remove partition from disk %s which has no media" % self.name, self.path) - - partition = self.partedDisk.getPartitionByPath(device.path) - if partition: - self.partedDisk.removePartition(partition) - - def addPartition(self, device): - log_method_call(self, self.name, part=device.name) - if not self.mediaPresent: - raise DeviceError("cannot add partition to disk with no media", self.path) - - for part in self.partedDisk.partitions: - log.debug("disk %s: partition %s has geom %s" % (self.name, - part.getDeviceNodeName(), - part.geometry)) - - geometry = device.partedPartition.geometry - constraint = parted.Constraint(exactGeom=geometry) - partition = parted.Partition(disk=self.partedDisk, - type=device.partedPartition.type, - geometry=geometry) - self.partedDisk.addPartition(partition, - constraint=constraint) - def probe(self): """ Probe for any missing information about this device. @@ -844,38 +748,6 @@ class DiskDevice(StorageDevice): size, disklabel type, maybe even partition layout """ log_method_call(self, self.name, size=self.size, partedDevice=self.partedDevice) - if not self.diskLabel: - log.debug("setting %s diskLabel to %s" % (self.name, - self.partedDisk.type)) - self.diskLabel = self.partedDisk.type - - def commit(self, intf=None): - """ Commit changes to the device. """ - log_method_call(self, self.name, status=self.status) - if not self.mediaPresent: - raise DeviceError("cannot commit to disk with no media", self.path) - - self.setupParents() - self.setup() - - # give committing 5 tries, failing that, raise an exception - attempt = 1 - maxTries = 5 - keepTrying = True - - while keepTrying and (attempt <= maxTries): - try: - self.partedDisk.commit() - keepTrying = False - except parted.DiskException as msg: - log.warning(msg) - attempt += 1 - - if keepTrying: - raise DeviceError("cannot commit to disk after %d attempts" % (maxTries,), self.path) - - # commit makes the kernel re-scan the partition table - udev_settle() def destroy(self): """ Destroy the device. """ @@ -883,13 +755,8 @@ class DiskDevice(StorageDevice): if not self.mediaPresent: raise DeviceError("cannot destroy disk with no media", self.path) - self.partedDisk.deleteAllPartitions() - # this is perhaps a separate operation (wiping the disklabel) - self.partedDisk.clobber() - self.partedDisk.commit() self.teardown() - def setup(self, intf=None): """ Open, or set up, a device. """ log_method_call(self, self.name, status=self.status) @@ -978,8 +845,7 @@ class PartitionDevice(StorageDevice): if self.exists: log.debug("looking up parted Partition: %s" % self.path) - #self.partedPartition = parted.getPartitionByName(self.path) - self._partedPartition = self.disk.partedDisk.getPartitionByPath(self.path) + self._partedPartition = self.disk.format.partedDisk.getPartitionByPath(self.path) if not self._partedPartition: raise DeviceError("cannot find parted partition instance", self.path) @@ -1052,7 +918,7 @@ class PartitionDevice(StorageDevice): # change this partition's geometry in-memory so that other # partitioning operations can complete (e.g., autopart) self._targetSize = newsize - disk = self.disk.partedDisk + disk = self.disk.format.partedDisk # resize the partition's geometry in memory (constraint, geometry) = self._computeResize(self.partedPartition) @@ -1248,14 +1114,15 @@ class PartitionDevice(StorageDevice): self.createParents() self.setupParents() - self.disk.addPartition(self) - self.disk.commit() + self.disk.format.addPartition(self.partedPartition) + self.disk.format.commit() + udev_settle(timeout=10) # Ensure old metadata which lived in freespace so did not get # explictly destroyed by a destroyformat action gets wiped DeviceFormat(device=self.path, exists=True).destroy() - self.partedPartition = self.disk.partedDisk.getPartitionByPath(self.path) + self.partedPartition = self.disk.format.partedDisk.getPartitionByPath(self.path) self.exists = True self.setup() @@ -1285,15 +1152,16 @@ class PartitionDevice(StorageDevice): # partedDisk has been restored to _origPartedDisk, so # recalculate resize geometry because we may have new # partitions on the disk, which could change constraints - partition = self.disk.partedDisk.getPartitionByPath(self.path) + partedDisk = self.disk.format.partedDisk + partition = partedDisk.getPartitionByPath(self.path) (constraint, geometry) = self._computeResize(partition) - self.disk.partedDisk.setPartitionGeometry(partition=partition, - constraint=constraint, - start=geometry.start, - end=geometry.end) + partedDisk.setPartitionGeometry(partition=partition, + constraint=constraint, + start=geometry.start, + end=geometry.end) - self.disk.commit() + self.disk.format.commit() self.notifyKernel() def destroy(self): @@ -1309,8 +1177,9 @@ class PartitionDevice(StorageDevice): raise DeviceError("Cannot destroy non-leaf device", self.path) self.setupParents() - self.disk.removePartition(self) - self.disk.commit() + partition = self.disk.format.partedDisk.getPartitionByPath(self.path) + self.disk.format.removePartition(partition) + self.disk.format.commit() self.exists = False diff --git a/storage/devicetree.py b/storage/devicetree.py index 721f1240f..7a8257a8d 100644 --- a/storage/devicetree.py +++ b/storage/devicetree.py @@ -691,8 +691,8 @@ class DeviceTree(object): log.debug("resetting parted disks...") for device in self.devices: - if isinstance(device, DiskDevice): - device.resetPartedDisk() + if device.format.type == "disklabel": + device.format.resetPartedDisk() for action in self._actions: log.info("executing action: %s" % action) @@ -737,11 +737,11 @@ class DeviceTree(object): # if this partition hasn't been allocated it could not have # a disk attribute if dev.partedPartition.type == parted.PARTITION_EXTENDED and \ - len(dev.disk.partedDisk.getLogicalPartitions()) > 0: + len(dev.disk.format.logicalPartitions) > 0: raise ValueError("Cannot remove extended partition %s. " "Logical partitions present." % dev.name) - dev.disk.partedDisk.removePartition(dev.partedPartition) + dev.disk.format.removePartition(dev.partedPartition) # adjust all other PartitionDevice instances belonging to the # same disk so the device name matches the potentially altered @@ -1135,44 +1135,11 @@ class DeviceTree(object): diskType = DiskDevice log.debug("%s is a disk" % name) - if self.zeroMbr: - cb = lambda: True - else: - cb = lambda: questionInitializeDisk(self.intf, name) - - # if the disk contains protected partitions we will - # not wipe the disklabel even if clearpart --initlabel - # was specified - if not self.clearPartDisks or name in self.clearPartDisks: - initlabel = self.reinitializeDisks - for protected in self.protectedDevNames: - _p = "/sys/%s/%s" % (sysfs_path, protected) - if os.path.exists(os.path.normpath(_p)): - initlabel = False - break - else: - initlabel = False - - try: - device = diskType(name, - major=udev_device_get_major(info), - minor=udev_device_get_minor(info), - sysfsPath=sysfs_path, - initcb=cb, initlabel=initlabel, **kwargs) - except DeviceUserDeniedFormatError: #drive not initialized? - self.addIgnoredDisk(name) - return - + device = diskType(name, + major=udev_device_get_major(info), + minor=udev_device_get_minor(info), + sysfsPath=sysfs_path, **kwargs) self._addDevice(device) - - # If this is a mac-formatted disk we just initialized, make sure the - # partition table partition gets added to the device tree. - if device.partedDisk and device.partedDisk.type == "mac" and len(device.partedDisk.partitions) == 1: - name = device.partedDisk.partitions[0].getDeviceNodeName() - if not self.getDeviceByName(name): - partDevice = PartitionDevice(name, exists=True, parents=[device]) - self._addDevice(partDevice) - return device def addUdevOpticalDevice(self, info): @@ -1266,9 +1233,98 @@ class DeviceTree(object): if device and device.name in self.protectedDevNames: device.protected = True + # Now, if the device is a disk, see if there is a usable disklabel. + # If not, see if the user would like to create one. + # XXX this is the bit that forces disklabels on disks. Lame. + if isinstance(device, DiskDevice) or \ + isinstance(device, DMRaidArrayDevice) or \ + isinstance(device, MultipathDevice): + self.handleUdevDiskLabelFormat(info, device) + return + # now handle the device's formatting self.handleUdevDeviceFormat(info, device) + def handleUdevDiskLabelFormat(self, info, device): + log_method_call(self, device=device.name) + if device.format.type == "disklabel": + # this device is already set up + log.debug("disklabel format on %s already set up" % device.name) + return + + try: + device.setup() + except Exception as e: + log.debug("setup of %s failed: %s" % (device.name, e)) + log.warning("aborting disklabel handler for %s" % device.name) + return + + # if the disk contains protected partitions we will not wipe the + # disklabel even if clearpart --initlabel was specified + if not self.clearPartDisks or device.name in self.clearPartDisks: + initlabel = self.reinitializeDisks + sysfs_path = udev_device_get_sysfs_path(info) + for protected in self.protectedDevNames: + # check for protected partition + _p = "/sys/%s/%s" % (sysfs_path, protected) + if os.path.exists(os.path.normpath(_p)): + initlabel = False + break + + # check for protected partition on a device-mapper disk + disk_name = re.sub(r'p\d+$', '', protected) + if disk_name != protected and disk_name == device.name: + initlabel = False + break + else: + initlabel = False + + + if self.zeroMbr: + initcb = lambda: True + else: + initcb = lambda: questionInitializeDisk(self.intf, device.name, + device.description) + + try: + format = getFormat("disklabel", + device=device.path, + exists=not initlabel) + except InvalidDiskLabelError: + # if we have a cb function use it. else we ignore the device. + if initcb is not None and initcb(): + format = getFormat("disklabel", + device=device.path, + exists=False) + else: + self._removeDevice(device) + if isinstance(device, DMRaidArrayDevice): + # We should ignore the dmraid members as well + self.addIgnoredDisk(device.raidSet.name) + self.addIgnoredDisk(device.name) + return + else: + if not format.exists: + # if we just initialized a disklabel we should schedule + # actions for destruction of the previous format and creation + # of the new one + self.registerAction(ActionDestroyFormat(device)) + self.registerAction(ActionCreateFormat(device, format)) + + # If this is a mac-formatted disk we just initialized, make + # sure the partition table partition gets added to the device + # tree. + if device.format.partedDisk.type == "mac" and \ + len(device.format.partitions) == 1: + name = device.format.partitions[0].getDeviceNodeName() + if not self.getDeviceByName(name): + partDevice = PartitionDevice(name, exists=True, + parents=[device]) + self._addDevice(partDevice) + + else: + device.format = format + def handleUdevLUKSFormat(self, info, device): log_method_call(self, name=device.name, type=device.format.type) if not device.format.uuid: @@ -1445,32 +1501,7 @@ class DeviceTree(object): mp.addParent(device) else: name = generateMultipathDeviceName() - devname = "/dev/mapper/%s" % (name,) - - if self.zeroMbr: - cb = lambda: True - else: - desc = [] - serialtmp = serial - while serialtmp: - desc.append(serialtmp[:2]) - serialtmp = serialtmp[2:] - desc = "WWID %s" % (":".join(desc),) - - cb = lambda: questionInitializeDisk(self.intf, devname, desc) - - initlabel = False - if not self.clearPartDisks or \ - name in self.clearPartDisks: - initlabel = self.reinitializeDisks - for protected in self.protectedDevNames: - disk_name = re.sub(r'p\d+$', '', protected) - if disk_name != protected and \ - disk_name == name: - initlabel = False - break - mp = MultipathDevice(name, info, parents=[device], initcb=cb, - initlabel=initlabel) + mp = MultipathDevice(name, info, parents=[device]) self.__multipaths[serial] = mp def handleUdevDMRaidMemberFormat(self, info, device): @@ -1512,49 +1543,18 @@ class DeviceTree(object): else: # Activate the Raid set. rs.activate(mknod=True) - - # Create the DMRaidArray - if self.zeroMbr: - cb = lambda: True - else: - cb = lambda: questionInitializeDisk(self.intf, - rs.name) - - # Create the DMRaidArray - if not self.clearPartDisks or \ - rs.name in self.clearPartDisks: - # if the disk contains protected partitions - # we will not wipe the disklabel even if - # clearpart --initlabel was specified - initlabel = self.reinitializeDisks - for protected in self.protectedDevNames: - disk_name = re.sub(r'p\d+$', '', protected) - if disk_name != protected and \ - disk_name == rs.name: - initlabel = False - break - - try: - dm_array = DMRaidArrayDevice(rs.name, - raidSet=rs, - parents=[device], - initcb=cb, - initlabel=initlabel) - - self._addDevice(dm_array) - # Use the rs's object on the device. - # pyblock can return the memebers of a set and the - # device has the attribute to hold it. But ATM we - # are not really using it. Commenting this out until - # we really need it. - #device.format.raidmem = block.getMemFromRaidSet(dm_array, - # major=major, minor=minor, uuid=uuid, name=name) - except DeviceUserDeniedFormatError: - # We should ignore the dmraid and its components - self.addIgnoredDisk(rs.name) - if _all_ignored(rss): - self.addIgnoredDisk(device.name) - rs.deactivate() + dm_array = DMRaidArrayDevice(rs.name, + raidSet=rs, + parents=[device]) + + self._addDevice(dm_array) + # Use the rs's object on the device. + # pyblock can return the memebers of a set and the + # device has the attribute to hold it. But ATM we + # are not really using it. Commenting this out until + # we really need it. + #device.format.raidmem = block.getMemFromRaidSet(dm_array, + # major=major, minor=minor, uuid=uuid, name=name) def handleUdevDeviceFormat(self, info, device): log_method_call(self, name=getattr(device, "name", None)) @@ -1629,14 +1629,6 @@ class DeviceTree(object): device.format = formats.DeviceFormat() return - if getattr(device, "partedDisk", None): - # Any detected formatting is spurious. Ignore it. - # We don't want to try to remove it since that could wipe out - # valid data like the partition table or data in existing - # partitions. - device.format = None - return - if shouldClear(device, self.clearPartType, clearPartDisks=self.clearPartDisks): # if this is a partition that will be cleared by clearpart, @@ -1760,20 +1752,6 @@ class DeviceTree(object): for leaf in self.leaves: leafInconsistencies(leaf) - # Automatically handle the cases where we find a format on a - # disk with partitions. I trust that the partitions list - # avoids the ignored devices. - for part in self.getDevicesByInstance(PartitionDevice): - if part.parents[0].format.type is not None: - disk = part.parents[0] - format = formats.getFormat(None, - device=disk.path, - exists=True) - log.warning("Automatically corrected fomrat error on %s. " - "Changed from %s to %s." % - (disk.name, disk.format, format)) - disk.format = format - def identifyMultipaths(self, devices): # this function does a couple of things # 1) identifies multipath disks diff --git a/storage/partitioning.py b/storage/partitioning.py index 7e7a5cf6d..65c1f5dcc 100644 --- a/storage/partitioning.py +++ b/storage/partitioning.py @@ -48,8 +48,7 @@ def _createFreeSpacePartitions(anaconda): (disk.name not in anaconda.id.storage.clearPartDisks): continue - partedDisk = disk.partedDisk - part = disk.partedDisk.getFirstPartition() + part = disk.format.firstPartition while part: if not part.type & parted.PARTITION_FREESPACE: part = part.nextPartition() @@ -267,7 +266,7 @@ def shouldClear(part, clearPartType, clearPartDisks=None): # Never clear the special first partition on a Mac disk label, as that # holds the partition table itself. - if part.disk.partedDisk.type == "mac" and \ + if part.disk.format.partedDisk.type == "mac" and \ part.partedPartition.number == 1 and \ part.partedPartition.name == "Apple": return False @@ -354,8 +353,8 @@ def clearPartitions(storage): def removeEmptyExtendedPartitions(storage): for disk in storage.disks: log.debug("checking whether disk %s has an empty extended" % disk.name) - extended = disk.partedDisk.getExtendedPartition() - logical_parts = disk.partedDisk.getLogicalPartitions() + extended = disk.format.extendedPartition + logical_parts = disk.format.logicalPartitions log.debug("extended is %s ; logicals is %s" % (extended, [p.getDeviceNodeName() for p in logical_parts])) if extended and not logical_parts: log.debug("removing empty extended partition from %s" % disk.name) @@ -602,7 +601,7 @@ def doPartitioning(storage, exclusiveDisks=None): # XXX hack -- if we created any extended partitions we need to add # them to the tree now for disk in disks: - extended = disk.partedDisk.getExtendedPartition() + extended = disk.format.extendedPartition if not extended: continue @@ -643,10 +642,10 @@ def allocatePartitions(disks, partitions): new_partitions.sort(cmp=partitionCompare) # XXX is this needed anymore? - partedDisks = {} + disklabels = {} for disk in disks: - if disk.path not in partedDisks.keys(): - partedDisks[disk.path] = disk.partedDisk #.duplicate() + if disk.path not in disklabels.keys(): + disklabels[disk.path] = disk.format # remove all newly added partitions from the disk log.debug("removing all non-preexisting from disk(s)") @@ -655,24 +654,18 @@ def allocatePartitions(disks, partitions): if _part.isExtended: # these get removed last continue - #_part.disk.partedDisk.removePartition(_part.partedPartition) - partedDisk = partedDisks[_part.disk.partedDisk.device.path] - #log.debug("removing part %s (%s) from disk %s (%s)" % - # (_part.partedPartition.path, - # [p.path for p in _part.partedPartition.disk.partitions], - # partedDisk.device.path, - # [p.path for p in partedDisk.partitions])) - - partedDisk.removePartition(_part.partedPartition) + + disklabel = disklabels[_part.partedPartition.disk.device.path] + disklabel.partedDisk.removePartition(_part.partedPartition) _part.partedPartition = None _part.disk = None # remove empty extended so it doesn't interfere - extended = partedDisk.getExtendedPartition() - if extended and not partedDisk.getLogicalPartitions(): + extended = disklabel.extendedPartition + if extended and not disklabel.logicalPartitions: log.debug("removing empty extended partition") #partedDisk.minimizeExtendedPartition() - partedDisk.removePartition(extended) + disklabel.partedDisk.removePartition(extended) for _part in new_partitions: if _part.partedPartition and _part.isExtended: @@ -700,15 +693,15 @@ def allocatePartitions(disks, partitions): part_type = None # loop through disks for _disk in req_disks: - disk = partedDisks[_disk.path] + disklabel = disklabels[_disk.path] #for p in disk.partitions: # log.debug("disk %s: part %s" % (disk.device.path, p.path)) - sectorSize = disk.device.physicalSectorSize + sectorSize = disklabel.partedDevice.physicalSectorSize best = None log.debug("checking freespace on %s" % _disk.name) - new_part_type = getNextPartitionType(disk) + new_part_type = getNextPartitionType(disklabel.partedDisk) if new_part_type is None: # can't allocate any more partitions on this disk log.debug("no free partition slots on %s" % _disk.name) @@ -724,7 +717,7 @@ def allocatePartitions(disks, partitions): log.debug("no primary slots available on %s" % _disk.name) continue - best = getBestFreeSpaceRegion(disk, + best = getBestFreeSpaceRegion(disklabel.partedDisk, new_part_type, _part.req_size, best_free=free, @@ -734,9 +727,10 @@ def allocatePartitions(disks, partitions): new_part_type == parted.PARTITION_NORMAL: # see if we can do better with a logical partition log.debug("not enough free space for primary -- trying logical") - new_part_type = getNextPartitionType(disk, no_primary=True) + new_part_type = getNextPartitionType(disklabel.partedDisk, + no_primary=True) if new_part_type: - best = getBestFreeSpaceRegion(disk, + best = getBestFreeSpaceRegion(disklabel.partedDisk, new_part_type, _part.req_size, best_free=free, @@ -773,22 +767,23 @@ def allocatePartitions(disks, partitions): raise PartitioningError("not enough free space on disks") _disk = use_disk - disk = _disk.partedDisk + disklabel = _disk.format # create the extended partition if needed # TODO: move to a function (disk, free) if part_type == parted.PARTITION_EXTENDED: log.debug("creating extended partition") - geometry = parted.Geometry(device=disk.device, + geometry = parted.Geometry(device=disklabel.partedDevice, start=free.start, length=free.length, end=free.end) - extended = parted.Partition(disk=disk, + extended = parted.Partition(disk=disklabel.partedDisk, type=parted.PARTITION_EXTENDED, geometry=geometry) - constraint = parted.Constraint(device=disk.device) + constraint = parted.Constraint(device=disklabel.partedDevice) # FIXME: we should add this to the tree as well - disk.addPartition(extended, constraint) + disklabel.partedDisk.addPartition(partition=extended, + constraint=constraint) # end proposed function @@ -797,7 +792,7 @@ def allocatePartitions(disks, partitions): # recalculate freespace log.debug("recalculating free space") - free = getBestFreeSpaceRegion(disk, + free = getBestFreeSpaceRegion(disklabel.partedDisk, part_type, _part.req_size, boot=_part.req_bootable) @@ -807,31 +802,34 @@ def allocatePartitions(disks, partitions): # create minimum geometry for this request # req_size is in MB - sectors_per_track = disk.device.biosGeometry[2] + sectors_per_track = disklabel.partedDevice.biosGeometry[2] length = (_part.req_size * (1024 * 1024)) / sectorSize - new_geom = parted.Geometry(device=disk.device, + new_geom = parted.Geometry(device=disklabel.partedDevice, start=max(sectors_per_track, free.start), length=length) # create maximum and minimum geometries for constraint start = max(0 , free.start - 1) - max_geom = parted.Geometry(device=disk.device, + max_len = min(length + 1, disklabel.partedDevice.length - start) + min_len = length - 1 + max_geom = parted.Geometry(device=disklabel.partedDevice, start=start, - length=min(length + 1, disk.device.length - start)) - min_geom = parted.Geometry(device=disk.device, + length=max_len) + min_geom = parted.Geometry(device=disklabel.partedDevice, start=free.start + 1, - length=length-1) + length=min_len) # create the partition and add it to the disk - partition = parted.Partition(disk=disk, + partition = parted.Partition(disk=disklabel.partedDisk, type=part_type, geometry=new_geom) constraint = parted.Constraint(maxGeom=max_geom, minGeom=min_geom) - disk.addPartition(partition=partition, - constraint=constraint) + disklabel.partedDisk.addPartition(partition=partition, + constraint=constraint) log.debug("created partition %s of %dMB and added it to %s" % - (partition.getDeviceNodeName(), partition.getSize(), disk)) + (partition.getDeviceNodeName(), partition.getSize(), + disklabel.partedDisk)) # this one sets the name _part.partedPartition = partition @@ -839,7 +837,7 @@ def allocatePartitions(disks, partitions): # parted modifies the partition in the process of adding it to # the disk, so we need to grab the latest version... - _part.partedPartition = disk.getPartitionByPath(_part.path) + _part.partedPartition = disklabel.partedDisk.getPartitionByPath(_part.path) def growPartitions(disks, partitions): """ Grow all growable partition requests. @@ -883,12 +881,12 @@ def growPartitions(disks, partitions): for disk in disks: log.debug("growing requests on %s" % disk.name) - for p in disk.partedDisk.partitions: + for p in disk.format.partitions: log.debug(" %s: %s (%dMB)" % (disk.name, p.getDeviceNodeName(), p.getSize())) - sectorSize = disk.partedDisk.device.physicalSectorSize + sectorSize = disk.format.partedDevice.physicalSectorSize # get a list of free space regions on the disk - free = disk.partedDisk.getFreeSpaceRegions() + free = disk.format.partedDisk.getFreeSpaceRegions() if not free: log.debug("no free space on %s" % disk.name) continue |