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