filesystem: renumber logicals on deletion

This commit is contained in:
Dan Bungert 2022-07-14 14:46:54 -06:00
parent f0c23f659f
commit 832caeda55
2 changed files with 38 additions and 16 deletions

View File

@ -668,6 +668,14 @@ class Disk(_Device):
return None return None
return id.encode('utf-8').decode('unicode_escape').strip() return id.encode('utf-8').decode('unicode_escape').strip()
def renumber_logical_partitions(self):
parts = [p for p in self._partitions if p.is_logical]
primary_limit = self.alignment_data().primary_part_limit
next_num = primary_limit + 1
for part in parts:
part.number = next_num
next_num += 1
@fsobj("partition") @fsobj("partition")
class Partition(_Formattable): class Partition(_Formattable):
@ -689,23 +697,17 @@ class Partition(_Formattable):
if self.number is not None: if self.number is not None:
return return
def is_logical(part): if self.is_logical:
return part.flag == 'logical' self.device.renumber_logical_partitions()
primary_limit = self.device.alignment_data().primary_part_limit
used_nums = {p.number for p in self.device._partitions
if p.number is not None
if is_logical(p) == is_logical(self)}
if is_logical(self):
possibles = range(primary_limit + 1, 129)
else: else:
possibles = range(1, primary_limit + 1) used_nums = {p.number for p in self.device._partitions
if p.number is not None and not p.is_logical}
for num in possibles: primary_limit = self.device.alignment_data().primary_part_limit
for num in range(1, primary_limit + 1):
if num not in used_nums: if num not in used_nums:
self.number = num self.number = num
return return
raise Exception('Failed to allocate partition number') raise Exception('Exceeded number of available primary partitions')
def available(self): def available(self):
if self.flag in ['bios_grub', 'prep'] or self.grub_device: if self.flag in ['bios_grub', 'prep'] or self.grub_device:
@ -759,6 +761,10 @@ class Partition(_Formattable):
return None return None
return OsProber(**os_data) return OsProber(**os_data)
@property
def is_logical(self):
return self.flag == 'logical'
ok_for_lvm_vg = ok_for_raid ok_for_lvm_vg = ok_for_raid
@ -1457,6 +1463,7 @@ class FilesystemModel(object):
for p2 in movable_trailing_partitions_and_gap_size(part)[0]: for p2 in movable_trailing_partitions_and_gap_size(part)[0]:
p2.offset -= part.size p2.offset -= part.size
self._remove(part) self._remove(part)
part.device.renumber_logical_partitions()
if len(part.device._partitions) == 0: if len(part.device._partitions) == 0:
part.device.ptable = None part.device.ptable = None

View File

@ -714,6 +714,21 @@ class TestPartitionNumbering(unittest.TestCase):
for _ in range(3): for _ in range(3):
self.assert_next(make_partition(m, d1, flag='logical')) self.assert_next(make_partition(m, d1, flag='logical'))
@parameterized.expand([[0], [1], [2]])
def test_msdos_delete_logical(self, idx_to_remove):
m, d1 = make_model_and_disk(ptable='msdos')
self.assert_next(make_partition(m, d1))
self.assert_next(make_partition(m, d1, flag='extended'))
self.cur_idx = 5
parts = [make_partition(m, d1, flag='logical') for _ in range(3)]
for p in parts:
self.assert_next(p)
to_remove = parts.pop(idx_to_remove)
m.remove_partition(to_remove)
self.cur_idx = 5
for p in parts:
self.assert_next(p)
def test_msdos_no_fifth_primary(self): def test_msdos_no_fifth_primary(self):
m, d1 = make_model_and_disk(ptable='msdos') m, d1 = make_model_and_disk(ptable='msdos')
for _ in range(4): for _ in range(4):