neil / rpms / python-blivet

Forked from rpms/python-blivet a year ago
Clone

Blame SOURCES/0027-Align-base-partition-sizes-in-PartitionFactory.patch

0b05ab
From 16db72b7adc5e1a295ecd52c0a53ee5a12111878 Mon Sep 17 00:00:00 2001
0b05ab
From: David Lehman <dlehman@redhat.com>
0b05ab
Date: Tue, 7 Jan 2020 17:10:24 -0500
0b05ab
Subject: [PATCH 1/2] Make minimal and optimal alignment getters public.
0b05ab
0b05ab
Related: rhbz#1781106
0b05ab
---
0b05ab
 blivet/formats/disklabel.py          | 10 +++++-----
0b05ab
 tests/formats_test/disklabel_test.py |  6 +++---
0b05ab
 2 files changed, 8 insertions(+), 8 deletions(-)
0b05ab
0b05ab
diff --git a/blivet/formats/disklabel.py b/blivet/formats/disklabel.py
0b05ab
index a435bc59..a3f9d04b 100644
0b05ab
--- a/blivet/formats/disklabel.py
0b05ab
+++ b/blivet/formats/disklabel.py
0b05ab
@@ -462,7 +462,7 @@ class DiskLabel(DeviceFormat):
0b05ab
 
0b05ab
         return self._disk_label_alignment
0b05ab
 
0b05ab
-    def _get_minimal_alignment(self):
0b05ab
+    def get_minimal_alignment(self):
0b05ab
         """ Return the device's minimal alignment for new partitions.
0b05ab
 
0b05ab
             :rtype: :class:`parted.Alignment`
0b05ab
@@ -484,7 +484,7 @@ class DiskLabel(DeviceFormat):
0b05ab
 
0b05ab
         return self._minimal_alignment
0b05ab
 
0b05ab
-    def _get_optimal_alignment(self):
0b05ab
+    def get_optimal_alignment(self):
0b05ab
         """ Return the device's optimal alignment for new partitions.
0b05ab
 
0b05ab
             :rtype: :class:`parted.Alignment`
0b05ab
@@ -502,7 +502,7 @@ class DiskLabel(DeviceFormat):
0b05ab
                 # if there is no optimal alignment, use the minimal alignment,
0b05ab
                 # which has already been intersected with the disklabel
0b05ab
                 # alignment
0b05ab
-                alignment = self._get_minimal_alignment()
0b05ab
+                alignment = self.get_minimal_alignment()
0b05ab
             else:
0b05ab
                 try:
0b05ab
                     alignment = optimal_alignment.intersect(disklabel_alignment)
0b05ab
@@ -524,13 +524,13 @@ class DiskLabel(DeviceFormat):
0b05ab
                                                          small to be aligned
0b05ab
         """
0b05ab
         # default to the optimal alignment
0b05ab
-        alignment = self._get_optimal_alignment()
0b05ab
+        alignment = self.get_optimal_alignment()
0b05ab
         if size is None:
0b05ab
             return alignment
0b05ab
 
0b05ab
         # use the minimal alignment if the requested size is smaller than the
0b05ab
         # optimal io size
0b05ab
-        minimal_alignment = self._get_minimal_alignment()
0b05ab
+        minimal_alignment = self.get_minimal_alignment()
0b05ab
         optimal_grain_size = Size(alignment.grainSize * self.sector_size)
0b05ab
         minimal_grain_size = Size(minimal_alignment.grainSize * self.sector_size)
0b05ab
         if size < minimal_grain_size:
0b05ab
diff --git a/tests/formats_test/disklabel_test.py b/tests/formats_test/disklabel_test.py
0b05ab
index 93ce8c4a..6a1187e1 100644
0b05ab
--- a/tests/formats_test/disklabel_test.py
0b05ab
+++ b/tests/formats_test/disklabel_test.py
0b05ab
@@ -41,8 +41,8 @@ class DiskLabelTestCase(unittest.TestCase):
0b05ab
 
0b05ab
         # make sure the private methods all return the expected values
0b05ab
         self.assertEqual(dl._get_disk_label_alignment(), disklabel_alignment)
0b05ab
-        self.assertEqual(dl._get_minimal_alignment(), minimal_alignment)
0b05ab
-        self.assertEqual(dl._get_optimal_alignment(), optimal_alignment)
0b05ab
+        self.assertEqual(dl.get_minimal_alignment(), minimal_alignment)
0b05ab
+        self.assertEqual(dl.get_optimal_alignment(), optimal_alignment)
0b05ab
 
0b05ab
         # validate result when passing a start alignment to get_end_alignment
0b05ab
         self.assertEqual(dl.get_end_alignment(alignment=optimal_alignment),
0b05ab
@@ -61,7 +61,7 @@ class DiskLabelTestCase(unittest.TestCase):
0b05ab
                          minimal_end_alignment)
0b05ab
 
0b05ab
         # test the old deprecated properties' values
0b05ab
-        self.assertEqual(dl.alignment, dl._get_optimal_alignment())
0b05ab
+        self.assertEqual(dl.alignment, dl.get_optimal_alignment())
0b05ab
         self.assertEqual(dl.end_alignment, dl.get_end_alignment())
0b05ab
 
0b05ab
     @patch("blivet.formats.disklabel.arch")
0b05ab
-- 
0b05ab
2.24.1
0b05ab
0b05ab
0b05ab
From f5810a412048bd445dbed02ce0d01e50a1d083ec Mon Sep 17 00:00:00 2001
0b05ab
From: David Lehman <dlehman@redhat.com>
0b05ab
Date: Tue, 7 Jan 2020 17:11:43 -0500
0b05ab
Subject: [PATCH 2/2] Align base sizes up if smaller than min I/O size.
0b05ab
0b05ab
Resolves: rhbz#1781106
0b05ab
---
0b05ab
 blivet/partitioning.py     | 18 +++++++++++++++---
0b05ab
 tests/partitioning_test.py | 34 ++++++++++++++++++++++++++++++++++
0b05ab
 2 files changed, 49 insertions(+), 3 deletions(-)
0b05ab
0b05ab
diff --git a/blivet/partitioning.py b/blivet/partitioning.py
0b05ab
index 026a3f8c..bc0fe237 100644
0b05ab
--- a/blivet/partitioning.py
0b05ab
+++ b/blivet/partitioning.py
0b05ab
@@ -408,7 +408,11 @@ def add_partition(disklabel, free, part_type, size, start=None, end=None):
0b05ab
         else:
0b05ab
             _size = size
0b05ab
 
0b05ab
-        alignment = disklabel.get_alignment(size=_size)
0b05ab
+        try:
0b05ab
+            alignment = disklabel.get_alignment(size=_size)
0b05ab
+        except AlignmentError:
0b05ab
+            alignment = disklabel.get_minimal_alignment()
0b05ab
+
0b05ab
         end_alignment = disklabel.get_end_alignment(alignment=alignment)
0b05ab
     else:
0b05ab
         alignment = parted.Alignment(grainSize=1, offset=0)
0b05ab
@@ -646,7 +650,12 @@ def do_partitioning(storage, boot_disk=None):
0b05ab
 
0b05ab
 def align_size_for_disklabel(size, disklabel):
0b05ab
     # Align the base size to the disk's grain size.
0b05ab
-    grain_size = Size(disklabel.alignment.grainSize)
0b05ab
+    try:
0b05ab
+        alignment = disklabel.get_alignment(size=size)
0b05ab
+    except AlignmentError:
0b05ab
+        alignment = disklabel.get_minimal_alignment()
0b05ab
+
0b05ab
+    grain_size = Size(alignment.grainSize)
0b05ab
     grains, rem = divmod(size, grain_size)
0b05ab
     return (grains * grain_size) + (grain_size if rem else Size(0))
0b05ab
 
0b05ab
@@ -751,7 +760,10 @@ def allocate_partitions(storage, disks, partitions, freespace, boot_disk=None):
0b05ab
             disklabel = disklabels[_disk.path]
0b05ab
             best = None
0b05ab
             current_free = free
0b05ab
-            alignment = disklabel.get_alignment(size=_part.req_size)
0b05ab
+            try:
0b05ab
+                alignment = disklabel.get_alignment(size=_part.req_size)
0b05ab
+            except AlignmentError:
0b05ab
+                alignment = disklabel.get_minimal_alignment()
0b05ab
 
0b05ab
             # for growable requests, we don't want to pass the current free
0b05ab
             # geometry to get_best_free_region -- this allows us to try the
0b05ab
diff --git a/tests/partitioning_test.py b/tests/partitioning_test.py
0b05ab
index ebd05260..4fe87ebe 100644
0b05ab
--- a/tests/partitioning_test.py
0b05ab
+++ b/tests/partitioning_test.py
0b05ab
@@ -179,6 +179,8 @@ class PartitioningTestCase(unittest.TestCase):
0b05ab
             min_str = 'parted.Device.minimumAlignment'
0b05ab
             opt_al = parted.Alignment(offset=0, grainSize=8192)  # 4 MiB
0b05ab
             min_al = parted.Alignment(offset=0, grainSize=2048)  # 1 MiB
0b05ab
+            disk.format._minimal_alignment = None  # drop cache
0b05ab
+            disk.format._optimal_alignment = None  # drop cache
0b05ab
             with patch(opt_str, opt_al) as optimal, patch(min_str, min_al) as minimal:
0b05ab
                 optimal_end = disk.format.get_end_alignment(alignment=optimal)
0b05ab
                 minimal_end = disk.format.get_end_alignment(alignment=minimal)
0b05ab
@@ -201,6 +203,38 @@ class PartitioningTestCase(unittest.TestCase):
0b05ab
                 disk.format.remove_partition(part)
0b05ab
                 self.assertEqual(len(disk.format.partitions), 0)
0b05ab
 
0b05ab
+            #
0b05ab
+            # adding a partition smaller than the minimal io size should yield
0b05ab
+            # a partition whose size is aligned up to the minimal io size
0b05ab
+            #
0b05ab
+            opt_str = 'parted.Device.optimumAlignment'
0b05ab
+            min_str = 'parted.Device.minimumAlignment'
0b05ab
+            opt_al = parted.Alignment(offset=0, grainSize=8192)  # 4 MiB
0b05ab
+            min_al = parted.Alignment(offset=0, grainSize=2048)  # 1 MiB
0b05ab
+            disk.format._minimal_alignment = None  # drop cache
0b05ab
+            disk.format._optimal_alignment = None  # drop cache
0b05ab
+            with patch(opt_str, opt_al) as optimal, patch(min_str, min_al) as minimal:
0b05ab
+                optimal_end = disk.format.get_end_alignment(alignment=optimal)
0b05ab
+                minimal_end = disk.format.get_end_alignment(alignment=minimal)
0b05ab
+
0b05ab
+                sector_size = Size(disk.format.sector_size)
0b05ab
+                length = 1024  # 512 KiB
0b05ab
+                size = Size(sector_size * length)
0b05ab
+                part = add_partition(disk.format, free, parted.PARTITION_NORMAL,
0b05ab
+                                     size)
0b05ab
+                self.assertEqual(part.geometry.length, min_al.grainSize)
0b05ab
+                self.assertEqual(optimal.isAligned(free, part.geometry.start),
0b05ab
+                                 False)
0b05ab
+                self.assertEqual(minimal.isAligned(free, part.geometry.start),
0b05ab
+                                 True)
0b05ab
+                self.assertEqual(optimal_end.isAligned(free, part.geometry.end),
0b05ab
+                                 False)
0b05ab
+                self.assertEqual(minimal_end.isAligned(free, part.geometry.end),
0b05ab
+                                 True)
0b05ab
+
0b05ab
+                disk.format.remove_partition(part)
0b05ab
+                self.assertEqual(len(disk.format.partitions), 0)
0b05ab
+
0b05ab
             #
0b05ab
             # add a partition with an unaligned start sector
0b05ab
             #
0b05ab
-- 
0b05ab
2.24.1
0b05ab