[PATCH 2/3] Add proper support for destruction of disklabels.

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

 



With this patch we can destroy a disklabel of one type and then create
a disklabel of a different type in the process of partitioning.
---
 storage/devices.py           |   42 ++++++++++++++++++++++++++++++------------
 storage/devicetree.py        |   12 ++++++++----
 storage/formats/disklabel.py |    5 +++++
 3 files changed, 43 insertions(+), 16 deletions(-)

diff --git a/storage/devices.py b/storage/devices.py
index 2e36df0..8cfe692 100644
--- a/storage/devices.py
+++ b/storage/devices.py
@@ -1107,16 +1107,6 @@ class PartitionDevice(StorageDevice):
         return spec
 
     def _getPartedPartition(self):
-        if not self.exists:
-            return self._partedPartition
-
-        partitionDisk = self._partedPartition.disk.getPedDisk()
-        disklabelDisk = self.disk.format.partedDisk.getPedDisk()
-        if partitionDisk is not disklabelDisk:
-            # The disklabel's parted disk has been reset, reget our partition
-            log.debug("regetting partedPartition %s for %s because of PartedDisk reset" % (self._origPath, self.path))
-            self._setPartedPartition(self.disk.format.partedDisk.getPartitionByPath(self._origPath))
-
         return self._partedPartition
 
     def _setPartedPartition(self, partition):
@@ -1138,6 +1128,31 @@ class PartitionDevice(StorageDevice):
     partedPartition = property(lambda d: d._getPartedPartition(),
                                lambda d,p: d._setPartedPartition(p))
 
+    def resetPartedPartition(self):
+        """ Re-get self.partedPartition from the original disklabel. """
+        log_method_call(self, self.name)
+        if not self.exists:
+            return
+
+        # find the correct partition on the original parted.Disk since the
+        # name/number we're now using may no longer match
+        _disklabel = self.disk.originalFormat
+
+        if self.isExtended:
+            # getPartitionBySector doesn't work on extended partitions
+            _partition = _disklabel.extendedPartition
+            log.debug("extended lookup found partition %s"
+                        % devicePathToName(getattr(_partition, "path", None)))
+        else:
+            # lookup the partition by sector to avoid the renumbering
+            # nonsense entirely
+            _sector = self.partedPartition.geometry.start + 1
+            _partition = _disklabel.partedDisk.getPartitionBySector(_sector)
+            log.debug("sector-based lookup found partition %s"
+                        % devicePathToName(getattr(_partition, "path", None)))
+
+        self.partedPartition = _partition
+
     def _getWeight(self):
         return self.req_base_weight
 
@@ -1341,8 +1356,11 @@ class PartitionDevice(StorageDevice):
             raise DeviceError("Cannot destroy non-leaf device", self.name)
 
         self.setupParents(orig=True)
-        self.disk.format.removePartition(self.partedPartition)
-        self.disk.format.commit()
+
+        # we should have already set self.partedPartition to point to the
+        # partition on the original disklabel
+        self.disk.originalFormat.removePartition(self.partedPartition)
+        self.disk.originalFormat.commit()
 
         self.exists = False
 
diff --git a/storage/devicetree.py b/storage/devicetree.py
index 75dde9c..c96bfbd 100644
--- a/storage/devicetree.py
+++ b/storage/devicetree.py
@@ -627,16 +627,20 @@ class DeviceTree(object):
         for device in self.devices:
             if device.partitioned:
                 device.format.resetPartedDisk()
+                if device.originalFormat.type == "disklabel" and \
+                   device.originalFormat != device.format:
+                    device.originalFormat.resetPartedDisk()
 
         # reget parted.Partition for remaining preexisting devices
         for device in self.devices:
-            if isinstance(device, PartitionDevice):
-                p = device.partedPartition
+            if isinstance(device, PartitionDevice) and device.exists:
+                device.resetPartedPartition()
 
         # reget parted.Partition for existing devices we're removing
         for action in self._actions:
-            if isinstance(action.device, PartitionDevice):
-                p = action.device.partedPartition
+            if isinstance(action.device, PartitionDevice) and \
+               action.device.exists:
+                action.device.resetPartedPartition()
 
         # setup actions to create any extended partitions we added
         #
diff --git a/storage/formats/disklabel.py b/storage/formats/disklabel.py
index d4a706d..a76e452 100644
--- a/storage/formats/disklabel.py
+++ b/storage/formats/disklabel.py
@@ -219,6 +219,11 @@ class DiskLabel(DeviceFormat):
             raise DeviceFormatError("device exists and is active")
 
         DeviceFormat.create(self, *args, **kwargs)
+
+        # We're relying on someone having called resetPartedDisk -- we
+        # could ensure a fresh disklabel by setting self._partedDisk to
+        # None right before calling self.commit(), but that might hide
+        # other problems.
         self.commit()
         self.exists = True
 
-- 
1.6.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