[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

Re: [rhel6-branch] allow GPT usage on non-EFI systems when size >2TB [REVISED]



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 redhat com>
Supervisor, Installer Engineering Team
Red Hat, Inc. | Westford, MA | EST5EDT


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]