lvm_partition: align down all remaining space to chunk size

If an autoinstall storage config with the last lvm_partition
is set to use all remaining space in the volgroup (size: -1)
and it is not aligned with the lvm chunk size, lvcreate will
round it up, and that will not fit into the actual free size.

That might happen depending on the size used by the previous
(lvm) partitions (e.g., may use percentage) and size of disk.

Fix that by rounding it down to the LVM chunk size.
This passed 'make check' and 'make lint' with exit code 0.

LP: #1919053

Before:

    Running command ['lvcreate', 'vg', '--name', 'lv-root', '--zero=y',
    '--wipesignatures=y', '--size', '6435110912.0B'] with allowed return
    codes [0] (capture=False)
      Rounding up size to full physical extent <6.00 GiB
      Volume group "vg" has insufficient free space (1534 extents): 1535
    required.
    An error occured handling 'lvm-lv-root': ProcessExecutionError -
    Unexpected error while running command.

After:

    Running command ['lvcreate', 'vg', '--name', 'lv-root', '--zero=y',
    '--wipesignatures=y', '--size', '6434062336.0B'] with allowed return
    codes [0] (capture=False)
    Logical volume "lv-root" created.

Check:

    $ python3 -q
    >>> 6435110912 / (4*1024**2)
    1534.25

    >>> 6435110912 & ~(4*1024**2-1)
    6434062336
    >>> _ / (4*1024**2)
    1534.0

Signed-off-by: Mauricio Faria de Oliveira <mfo@canonical.com>
This commit is contained in:
Mauricio Faria de Oliveira 2021-03-13 21:28:09 -03:00
parent 6d091b054a
commit 0205a74fc6
2 changed files with 7 additions and 1 deletions

View File

@ -1476,6 +1476,8 @@ class FilesystemModel(object):
"of {}".format(p, parent))
p.size = 0
p.size = parent.free_for_partitions
if p.type == 'lvm_partition':
p.size = align_down(p.size, LVM_CHUNK_SIZE)
elif isinstance(p.size, str):
if p.size.endswith("%"):
percentage = int(p.size[:-1])

View File

@ -27,6 +27,8 @@ from subiquity.models.filesystem import (
get_raid_size,
humanize_size,
Partition,
align_down,
LVM_CHUNK_SIZE,
)
@ -1135,7 +1137,9 @@ class TestAutoInstallConfig(unittest.TestCase):
vg = model._one(type="lvm_volgroup")
lv2 = model._one(type="lvm_partition", id='lv2')
self.assertEqual(
lv2.size, vg.available_for_partitions - dehumanize_size("50M"))
lv2.size, align_down(
vg.available_for_partitions - dehumanize_size("50M"),
LVM_CHUNK_SIZE))
def test_render_does_not_include_unreferenced(self):
model = make_model(Bootloader.NONE)