Fix resizing of extended partitions: 1) Report minSize as size of extended partition - size of free space at the end of it. (Blivet now reports 0 B.) Fixes #1254875 2) Allow resizing of non-leaf partitions.
From: Vojtech Trefny vtrefny@redhat.com
--- blivet/devices/partition.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/blivet/devices/partition.py b/blivet/devices/partition.py index ed5e6c8..bbf965a 100644 --- a/blivet/devices/partition.py +++ b/blivet/devices/partition.py @@ -799,7 +799,18 @@ def readCurrentSize(self):
@property def minSize(self): - min_size = super(PartitionDevice, self).minSize + if self.isExtended: + logicals = self.disk.format.logicalPartitions + if logicals: + end_free = Size((self.partedPartition.geometry.end - logicals[-1].geometry.end) * \ + self.disk.format.sectorSize) + min_size = self.alignTargetSize(self.currentSize - end_free) + else: + min_size = self.alignTargetSize(max(Size("1 KiB"), self.disk.format.alignment.grainSize)) + + else: + min_size = super(PartitionDevice, self).minSize + if self.resizable and min_size: # Adjust the min size as needed so that aligning the end sector # won't drive the actual size below the formatting's minimum.
From: Vojtech Trefny vtrefny@redhat.com
Do not run _preDestroy when resizing partitions -- it raises exception when trying to resize non-leaf partitions (e.g. extended partition with logical partitions). --- blivet/devices/partition.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/blivet/devices/partition.py b/blivet/devices/partition.py index bbf965a..fab9b23 100644 --- a/blivet/devices/partition.py +++ b/blivet/devices/partition.py @@ -640,7 +640,7 @@ def _computeResize(self, partition, newsize=None):
def resize(self): log_method_call(self, self.name, status=self.status) - self._preDestroy() + self._preResize()
# partedDisk has been restored to _origPartedDisk, so # recalculate resize geometry because we may have new @@ -657,6 +657,20 @@ def resize(self): self.disk.format.commit() self.updateSize()
+ def _preResize(self): + if not self.exists: + raise errors.DeviceError("device has not been created", self.name) + + if not self.isleaf and not self.isExtended: + raise errors.DeviceError("Cannot destroy non-leaf device", self.name) + + self.teardown() + + if not self.sysfsPath: + return + + self.setupParents(orig=True) + def _preDestroy(self): StorageDevice._preDestroy(self) if not self.sysfsPath:
From: Vojtech Trefny vtrefny@redhat.com
Signed-off-by: Vojtech Trefny vtrefny@redhat.com --- tests/devices_test/partition_test.py | 42 ++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+)
diff --git a/tests/devices_test/partition_test.py b/tests/devices_test/partition_test.py index fb30906..f02dfc5 100644 --- a/tests/devices_test/partition_test.py +++ b/tests/devices_test/partition_test.py @@ -2,6 +2,9 @@
import os import unittest +import parted + +from unittest.mock import patch
from blivet.devices import DiskFile from blivet.devices import PartitionDevice @@ -154,3 +157,42 @@ def testMinMaxSizeAlignment(self): self.assertEqual( disk.format.endAlignment.isAligned(free, max_end_sector), True) + + @patch("blivet.devices.partition.PartitionDevice.readCurrentSize", lambda part: part.size) + def testExtendedMinSize(self): + with sparsetmpfile("extendedtest", Size("10 MiB")) as disk_file: + disk = DiskFile(disk_file) + disk.format = getFormat("disklabel", device=disk.path) + grain_size = Size(disk.format.alignment.grainSize) + sector_size = Size(disk.format.partedDevice.sectorSize) + + extended_start = int(grain_size) + extended_end = extended_start + int(Size("6 MiB") / sector_size) + disk.format.addPartition(extended_start, extended_end, parted.PARTITION_EXTENDED) + extended = disk.format.extendedPartition + self.assertNotEqual(extended, None) + + extended_device = PartitionDevice(os.path.basename(extended.path)) + extended_device.disk = disk + extended_device.exists = True + extended_device.partedPartition = extended + + # no logical partitions --> min size should be max of 1 KiB and grainSize + self.assertEqual(extended_device.minSize, + extended_device.alignTargetSize(max(grain_size, Size("1 KiB")))) + + logical_start = extended_start + 1 + logical_end = extended_end // 2 + disk.format.addPartition(logical_start, logical_end, parted.PARTITION_LOGICAL) + logical = disk.format.partedDisk.getPartitionBySector(logical_start) + self.assertNotEqual(logical, None) + + logical_device = PartitionDevice(os.path.basename(logical.path)) + logical_device.disk = disk + logical_device.exists = True + logical_device.partedPartition = logical + + # logical partition present --> min size should be based on its end sector + end_free = (extended_end - logical_end)*sector_size + self.assertEqual(extended_device.minSize, + extended_device.alignTargetSize(extended_device.currentSize - end_free))
Test added.
Nice! The test looks good to me.
Thanks for adding the test -- it looks good.
Pushed.
Closed.
anaconda-patches@lists.fedorahosted.org