This allows us to choose the most appropriate type of disklabel for a device based on the device's size, along with the platform and device type. --- pyanaconda/platform.py | 29 +++++++++++++++++++++++------ pyanaconda/storage/devicetree.py | 8 ++++++++ pyanaconda/storage/formats/disklabel.py | 17 ++++++++++++----- pyanaconda/storage/partitioning.py | 13 ++++++++----- 4 files changed, 51 insertions(+), 16 deletions(-) diff --git a/pyanaconda/platform.py b/pyanaconda/platform.py index 6d24e3f..c680fd7 100644 --- a/pyanaconda/platform.py +++ b/pyanaconda/platform.py @@ -20,6 +20,8 @@ # Authors: Chris Lumens <clumens@xxxxxxxxxx> # +import parted + from pyanaconda import bootloader import iutil @@ -79,9 +81,24 @@ class Platform(object): """The default disklabel type for this architecture.""" return self.diskLabelTypes[0] - def diskLabelType(self, device_type): - """The default disklabel type for the specified device type.""" - return self.defaultDiskLabelType + def requiredDiskLabelType(self, device_type): + return None + + def bestDiskLabelType(self, device): + """The best disklabel type for the specified device.""" + # if there's a required type for this device type, use that + labelType = self.requiredDiskLabelType(device.partedDevice.type) + if not labelType: + # otherwise, use the first supported type for this platform + # that is large enough to address the whole device + labelType = self.defaultDiskLabelType + for lt in self.diskLabelTypes: + l = parted.freshDisk(device=device.partedDevice, ty=lt) + if l.maxPartitionStartSector < device.partedDevice.length: + labelType = lt + break + + return labelType def checkBootRequest(self): """Perform an architecture-specific check on the boot device. Not all @@ -240,12 +257,12 @@ class S390(Platform): weight=self.weight(mountpoint="/boot"), asVol=True, singlePV=True)] - def diskLabelType(self, device_type): - """The default disklabel type for the specified device type.""" + def requiredDiskLabelType(self, device_type): + """The required disklabel type for the specified device type.""" if device_type == "dasd": return "dasd" - return self.defaultDiskLabelType + return super(S390, self).requiredDiskLabelType(device_type) class Sparc(Platform): _bootloaderClass = bootloader.SILO diff --git a/pyanaconda/storage/devicetree.py b/pyanaconda/storage/devicetree.py index 72da38c..bc7d248 100644 --- a/pyanaconda/storage/devicetree.py +++ b/pyanaconda/storage/devicetree.py @@ -39,6 +39,7 @@ import devicelibs.mpath import devicelibs.loop from udev import * from pyanaconda import iutil +from pyanaconda import platform from pyanaconda import tsort from pyanaconda.anaconda_log import log_method_call, log_method_return import parted @@ -168,6 +169,8 @@ class DeviceTree(object): self.iscsi = iscsi self.dasd = dasd + self.platform = platform.getPlatform(None) + self.diskImages = {} images = getattr(conf, "diskImages", {}) if images: @@ -1097,15 +1100,20 @@ class DeviceTree(object): initcb = lambda: self.intf.questionInitializeDisk(bypath, description, device.size) + + labelType = self.platform.bestDiskLabelType(device) + try: format = getFormat("disklabel", device=device.path, + labelType=labelType, 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, + labelType=labelType, exists=False) else: self._removeDevice(device) diff --git a/pyanaconda/storage/formats/disklabel.py b/pyanaconda/storage/formats/disklabel.py index e986b5e..49bdfe1 100644 --- a/pyanaconda/storage/formats/disklabel.py +++ b/pyanaconda/storage/formats/disklabel.py @@ -26,7 +26,6 @@ import copy from pyanaconda.anaconda_log import log_method_call import parted import _ped -from pyanaconda import platform from ..errors import * from ..udev import udev_settle from . import DeviceFormat, register_device_format @@ -50,6 +49,7 @@ class DiskLabel(DeviceFormat): Keyword Arguments: + labelType -- type of disklabel to create device -- path to the underlying device exists -- indicates whether this is an existing format @@ -57,6 +57,11 @@ class DiskLabel(DeviceFormat): log_method_call(self, *args, **kwargs) DeviceFormat.__init__(self, *args, **kwargs) + if not self.exists: + self._labelType = kwargs.get("labelType", "msdos") + else: + self._labelType = None + self._size = None self._partedDevice = None @@ -119,10 +124,8 @@ class DiskLabel(DeviceFormat): def freshPartedDisk(self): """ Return a new, empty parted.Disk instance for this device. """ - log_method_call(self, device=self.device) - platf = platform.getPlatform(None) - labelType = platf.diskLabelType(self.partedDevice.type) - return parted.freshDisk(device=self.partedDevice, ty=labelType) + log_method_call(self, device=self.device, labelType=self._labelType) + return parted.freshDisk(device=self.partedDevice, ty=self._labelType) @property def partedDisk(self): @@ -140,6 +143,10 @@ class DiskLabel(DeviceFormat): # same as if the device had no label (cause it really # doesn't). raise InvalidDiskLabelError() + + # here's where we correct the ctor-supplied disklabel type for + # preexisting disklabels if the passed type was wrong + self._labelType = self._partedDisk.type else: self._partedDisk = self.freshPartedDisk() diff --git a/pyanaconda/storage/partitioning.py b/pyanaconda/storage/partitioning.py index a5279d8..80ba4ca 100644 --- a/pyanaconda/storage/partitioning.py +++ b/pyanaconda/storage/partitioning.py @@ -369,7 +369,7 @@ def clearPartitions(storage, bootloader=None): # not much to do return - if not hasattr(storage.platform, "diskLabelType"): + if not hasattr(storage.platform, "diskLabelTypes"): raise StorageError("can't clear partitions without platform data") # we are only interested in partitions that physically exist @@ -414,7 +414,9 @@ def clearPartitions(storage, bootloader=None): devices.remove(leaf) destroy_action = ActionDestroyFormat(disk) - newLabel = getFormat("disklabel", device=disk.path) + labelType = storage.platform.bestDiskLabelType(disk) + newLabel = getFormat("disklabel", device=disk.path, + labelType=labelType) create_action = ActionCreateFormat(disk, format=newLabel) storage.devicetree.registerAction(destroy_action) storage.devicetree.registerAction(create_action) @@ -444,7 +446,7 @@ def clearPartitions(storage, bootloader=None): if filter(lambda p: p.dependsOn(disk), storage.protectedDevices): continue - nativeLabelType = storage.platform.diskLabelType(disk.partedDevice.type) + nativeLabelType = storage.platform.bestDiskLabelType(disk) if disk.format.labelType == nativeLabelType: continue @@ -459,7 +461,8 @@ def clearPartitions(storage, bootloader=None): storage.devicetree._removeDevice(part, moddisk=False) destroy_action = ActionDestroyFormat(disk) - newLabel = getFormat("disklabel", device=disk.path) + newLabel = getFormat("disklabel", device=disk.path, + labelType=nativeLabelType) create_action = ActionCreateFormat(disk, format=newLabel) storage.devicetree.registerAction(destroy_action) storage.devicetree.registerAction(create_action) @@ -837,7 +840,7 @@ def doPartitioning(storage, bootloader=None): bootloader - BootLoader instance """ - if not hasattr(storage.platform, "diskLabelType"): + if not hasattr(storage.platform, "diskLabelTypes"): raise StorageError("can't allocate partitions without platform data") disks = storage.partitioned -- 1.7.3.4 _______________________________________________ Anaconda-devel-list mailing list Anaconda-devel-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/anaconda-devel-list