[PATCH 2/2] Change all disklabel manipulations to use the DiskLabel format class.

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

 



The DiskDevice class no longer has any implicit requirement that the
device contain a disklabel. The disklabel is now represented as a
device format. This provides the basis for future support for device
types that can optionally be partitioned, as well as whole-disk formats
such as filesystems.
---
 iw/partition_gui.py     |    8 +-
 platform.py             |    2 +-
 storage/__init__.py     |    4 +-
 storage/deviceaction.py |    8 +-
 storage/devices.py      |  173 ++++-----------------------------
 storage/devicetree.py   |  242 +++++++++++++++++++++--------------------------
 storage/partitioning.py |   92 +++++++++---------
 7 files changed, 186 insertions(+), 343 deletions(-)

diff --git a/iw/partition_gui.py b/iw/partition_gui.py
index bffc5a9..831c04d 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 7e8e34f..2c3e8cf 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 094c079..e30182b 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 838b500..df84c2d 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 3b4de0b..3cb65aa 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 0dec5e0..0aee84b 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 \
-                    rs.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):
         log.info("devices to scan for multipath: %s" % [d['name'] for d in devices])
         serials = {}
diff --git a/storage/partitioning.py b/storage/partitioning.py
index 7e7a5cf..65c1f5d 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
-- 
1.6.0.6

_______________________________________________
Anaconda-devel-list mailing list
Anaconda-devel-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/anaconda-devel-list

[Index of Archives]     [Kickstart]     [Fedora Users]     [Fedora Legacy List]     [Fedora Maintainers]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [Yosemite Photos]     [KDE Users]     [Fedora Tools]
  Powered by Linux