On 08/10/2011 03:27 PM, David Lehman wrote:
On Wed, 2011-08-10 at 14:30 -0400, David Cantrell wrote:
SSIA.
I'm not actually sure if this is all that is required as I do not have a disk
larger than 2TB and HP has, as of yet, failed to test my updates.img containing
these changes. So here they are for review.
Take a look at cc388b628aa912d7 on master. The only thing it needs
that's missing from rhel6-branch, I think, is the ordered list of
disklabel types in the Platform classes. Preferred/default type goes
first.
Nice. Here's a new patch incorporating those changes plus adding in the
ordered list of disklabel types:
[PATCH] Use GPT on non-UEFI for disks larger than 2TB (#671230)
Allow the use of GPT for disks larger than 2TB on non-UEFI systems.
Based on patch cc388b628aa912d7 from master.
---
platform.py | 53
++++++++++++++++++++++++++++-------------
storage/devicetree.py | 6 ++++
storage/formats/disklabel.py | 16 +++++++++---
storage/partitioning.py | 11 +++++++-
4 files changed, 63 insertions(+), 23 deletions(-)
diff --git a/platform.py b/platform.py
index bdb2357..48e0739 100644
--- a/platform.py
+++ b/platform.py
@@ -40,7 +40,7 @@ class Platform(object):
architecture quirks in one place to avoid lots of platform checks
throughout anaconda."""
_bootFSTypes = ["ext3"]
- _diskLabelType = "msdos"
+ _diskLabelTypes = ["msdos"]
_isEfi = iutil.isEfi()
_minimumSector = 0
_packages = []
@@ -143,9 +143,28 @@ class Platform(object):
return errors
- def diskLabelType(self, deviceType):
- """Return the disk label type as a string."""
- return self._diskLabelType
+ @property
+ def diskLabelTypes(self):
+ return self._diskLabelTypes
+
+ 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
@property
def isEfi(self):
@@ -203,7 +222,7 @@ class Platform(object):
class EFI(Platform):
_bootFSTypes = ["ext4", "ext3", "ext2"]
- _diskLabelType = "gpt"
+ _diskLabelTypes = ["gpt"]
_minBootPartSize = 50
def bootDevice(self):
@@ -284,7 +303,7 @@ class EFI(Platform):
return 0
class Alpha(Platform):
- _diskLabelType = "bsd"
+ _diskLabelTypes = ["bsd"]
def checkBootRequest(self, req):
errors = Platform.checkBootRequest(self, req)
@@ -295,7 +314,7 @@ class Alpha(Platform):
disk = req.disk.format.partedDisk
# Check that we're a BSD disk label
- if not disk.type == self._diskLabelType.name:
+ if not disk.type in self.diskLabelTypes:
errors.append(_("%s must have a bsd disk label.") %
req.disk.name)
# The first free space should start at the beginning of the
drive and
@@ -396,7 +415,7 @@ class IPSeriesPPC(PPC):
return 0
class NewWorldPPC(PPC):
- _diskLabelType = "mac"
+ _diskLabelTypes = ["mac"]
_minBootPartSize = (800.00 / 1024.00)
_maxBootPartSize = 1
@@ -438,7 +457,7 @@ class NewWorldPPC(PPC):
disk = req.disk.format.partedDisk
# Check that we're a Mac disk label
- if not disk.type == self._diskLabelType.name:
+ if not disk.type in self.diskLabelTypes:
errors.append(_("%s must have a mac disk label.") %
req.disk.name)
# All of the above just checks the appleboot partitions. We still
@@ -468,7 +487,7 @@ class NewWorldPPC(PPC):
return 0
class PS3(PPC):
- _diskLabelType = "msdos"
+ _diskLabelTypes = ["msdos"]
def __init__(self, anaconda):
PPC.__init__(self, anaconda)
@@ -481,12 +500,12 @@ class S390(Platform):
def __init__(self, anaconda):
Platform.__init__(self, anaconda)
- def diskLabelType(self, deviceType):
- """Return the disk label type as a string."""
+ def requiredDiskLabelType(self, device_type):
+ """The required disklabel type for the specified device type."""
if deviceType == parted.DEVICE_DASD:
return "dasd"
- else:
- return Platform.diskLabelType(self, deviceType)
+
+ return super(S390, self).requiredDiskLabelType(device_type)
def setDefaultPartitioning(self):
"""Return the default platform-specific partitioning
information."""
@@ -501,7 +520,7 @@ class S390(Platform):
return 0
class Sparc(Platform):
- _diskLabelType = "sun"
+ _diskLabelTypes = ["sun"]
@property
def minimumSector(self, disk):
@@ -519,9 +538,9 @@ class X86(EFI):
EFI.__init__(self, anaconda)
if self.isEfi:
- self._diskLabelType = "gpt"
+ self._diskLabelTypes = ["gpt"]
else:
- self._diskLabelType = "msdos"
+ self._diskLabelTypes = ["msdos", "gpt"]
def bootDevice(self):
if self.isEfi:
diff --git a/storage/devicetree.py b/storage/devicetree.py
index e9ff36a..a4e1526 100644
--- a/storage/devicetree.py
+++ b/storage/devicetree.py
@@ -38,6 +38,7 @@ import devicelibs.mpath
from udev import *
from .storage_log import log_method_call
import iutil
+import platform
import parted
import _ped
@@ -170,6 +171,7 @@ class DeviceTree(object):
self.reinitializeDisks = reinitializeDisks
self.iscsi = iscsi
self.dasd = dasd
+ self.platform = platform.getPlatform(None)
self.mpathFriendlyNames = mpathFriendlyNames
# protected device specs as provided by the user
@@ -1431,15 +1433,19 @@ class DeviceTree(object):
device.size,
details)
+ 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/storage/formats/disklabel.py b/storage/formats/disklabel.py
index f1fb1f0..c6927ec 100644
--- a/storage/formats/disklabel.py
+++ b/storage/formats/disklabel.py
@@ -50,6 +50,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 +58,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 +125,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 +144,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/storage/partitioning.py b/storage/partitioning.py
index d9a9dc9..2561702 100644
--- a/storage/partitioning.py
+++ b/storage/partitioning.py
@@ -384,6 +384,9 @@ def clearPartitions(storage):
# not much to do
return
+ if not hasattr(storage.platform, "diskLabelTypes"):
+ raise StorageError("can't clear partitions without platform data")
+
# we are only interested in partitions that physically exist
partitions = [p for p in storage.partitions if p.exists]
# Sort partitions by descending partition number to minimize confusing
@@ -438,7 +441,7 @@ def clearPartitions(storage):
if filter(lambda p: p.dependsOn(disk), storage.protectedDevices):
continue
- nativeLabelType = _platform.diskLabelType(disk.partedDevice.type)
+ nativeLabelType = storage.platform.bestDiskLabelType(disk)
if disk.format.labelType == nativeLabelType:
continue
@@ -453,7 +456,8 @@ def clearPartitions(storage):
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)
@@ -852,6 +856,9 @@ def doPartitioning(storage, exclusiveDisks=None):
exclusiveDisks -- list of names of disks to use
"""
+ if not hasattr(storage.platform, "diskLabelTypes"):
+ raise StorageError("can't allocate partitions without platform
data")
+
anaconda = storage.anaconda
disks = storage.partitioned
if exclusiveDisks:
--
1.7.1
--
David Cantrell <dcantrell@xxxxxxxxxx>
Supervisor, Installer Engineering Team
Red Hat, Inc. | Westford, MA | EST5EDT
_______________________________________________
Anaconda-devel-list mailing list
Anaconda-devel-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/anaconda-devel-list