filesystem: don't suggest target resize if part is mounted

When a partition is mounted in the live environment (either by casper or
another process) and is selected for resize, curtin will fail when
running e2fsck (or equivalent) with an error such as:

  Resize requested for format ext4
  Resizing /dev/sdb4 of type ext4 down to 12546211840
  Running command ['e2fsck', '-p', '-f', '/dev/sdb4'] with allowed return codes [0] (capture=False)
  /dev/sdb4 is mounted.
  e2fsck: Cannot continue, aborting.

  An error occured handling 'disk-sdb': ProcessExecutionError - Unexpected error while running command.
  Command: ['e2fsck', '-p', '-f', '/dev/sdb4']
  Exit code: 8

This is what happens when casper creates a partition on the installer
media to store /var/log and /var/crash. Usually the partition is large
enough to install Ubuntu so a GuidedStorageTargetResize scenario gets
emitted.

This patch prevents the emission of a GuidedStorageTargetResize scenario
if the partition is marked as mounted already.

Signed-off-by: Olivier Gayot <olivier.gayot@canonical.com>
This commit is contained in:
Olivier Gayot 2024-03-27 18:19:20 +01:00
parent cdb56a0d9f
commit c093059919
2 changed files with 21 additions and 0 deletions

View File

@ -1141,6 +1141,8 @@ class FilesystemController(SubiquityController, FilesystemManipulator):
for disk in self.potential_boot_disks(check_boot=False):
part_align = disk.alignment_data().part_align
for partition in disk.partitions():
if partition._is_in_use:
continue
vals = sizes.calculate_guided_resize(
partition.estimated_min_size,
partition.size,

View File

@ -902,6 +902,25 @@ class TestGuidedV2(IsolatedAsyncioTestCase):
self.assertTrue(isinstance(resize, GuidedStorageTargetResize))
self.assertEqual(1, len(resp.targets))
@parameterized.expand(bootloaders_and_ptables)
async def test_used_half_disk_mounted(self, bootloader, ptable):
# When a partition is already mounted, it can't be resized.
await self._setup(bootloader, ptable, size=100 << 30)
p = make_partition(
self.model, self.disk, preserve=True, size=50 << 30, is_in_use=True
)
self.fs_probe[p._path()] = {"ESTIMATED_MIN_SIZE": 1 << 20}
resp = await self.fsc.v2_guided_GET()
reformat = resp.targets.pop(0)
self.assertEqual(
GuidedStorageTargetReformat(
disk_id=self.disk.id, allowed=default_capabilities
),
reformat,
)
self.assertEqual(1, len(resp.targets))
@parameterized.expand(bootloaders_and_ptables)
async def test_used_full_disk(self, bootloader, ptable):
await self._setup(bootloader, ptable)