From 45dd2e34e2fae01767ad51bf908370dda91c1c59 Mon Sep 17 00:00:00 2001 From: Josevi Canet Date: Fri, 26 Jun 2026 21:45:42 +0200 Subject: [PATCH] Alinear el final de las particiones "resto-del-disco" a MiB parted marca como misaligned las particiones cuyo final no cae en la rejilla de 1 MiB. En la VM los discos miden GiB exactos y el final encaja; en hardware real el tamano no es multiplo de MiB (p.ej. 250_059_350_016 B), asi que terminar en total-1MiB dejaba la particion fuera de rejilla. usable_end() redondea el final hacia abajo a MiB (se pierden <2 MiB). Aplica a / (btrfs) y a /home. Los starts ya estaban en rejilla. Cubre cualquier sector size. Anade casos al --selftest. Co-Authored-By: Claude Opus 4.8 --- shared/gen-disk-config.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/shared/gen-disk-config.py b/shared/gen-disk-config.py index 6ada3a7..3f3750d 100644 --- a/shared/gen-disk-config.py +++ b/shared/gen-disk-config.py @@ -33,6 +33,13 @@ except ImportError: MiB = 1024 ** 2 END_MARGIN = MiB # deja 1 MiB al final para la cabecera GPT de respaldo +def usable_end(total): + # Final alineado a la rejilla de 1 MiB. Los discos reales tienen tamanos que + # no son multiplo de MiB (p.ej. 250_059_350_016 B), asi que terminar en + # total-END_MARGIN deja la particion fuera de rejilla y parted la marca como + # "misaligned". Redondeamos el final hacia abajo a MiB (se pierden <2 MiB). + return ((int(total) - END_MARGIN) // MiB) * MiB + def part(status, ptype, start_b, len_b, ss, fs=None, mnt=None, flags=()): return PartitionModification( status=status, type=ptype, @@ -48,7 +55,7 @@ def nvme_mods(dev): esp_start, esp_len = 1 * MiB, 511 * MiB # 1 -> 512 MiB boot_start, boot_len = 512 * MiB, 1024 * MiB # 512 -> 1536 MiB root_start = boot_start + boot_len # 1536 MiB - root_len = total - root_start - END_MARGIN + root_len = usable_end(total) - root_start return DeviceModification(device=dev, wipe=True, partitions=[ part(ModificationStatus.CREATE, PartitionType.PRIMARY, esp_start, esp_len, ss, FilesystemType.FAT32, "/boot/efi", (PartitionFlag.BOOT, PartitionFlag.ESP)), @@ -64,7 +71,7 @@ def sda_mods(dev): start = 1 * MiB return DeviceModification(device=dev, wipe=True, partitions=[ part(ModificationStatus.CREATE, PartitionType.PRIMARY, start, - total - start - END_MARGIN, ss, FilesystemType.EXT4, "/home"), + usable_end(total) - start, ss, FilesystemType.EXT4, "/home"), ]) def pick_fixed(lsblk_out): @@ -119,6 +126,12 @@ def _selftest(): assert pick_fixed(two) == ["/dev/nvme0n1", "/dev/sda"], pick_fixed(two) # solo USB conectado -> sin discos fijos (main aborta) assert pick_fixed("sdb 1 disk\nsr0 1 rom") == [] + # final alineado: disco "feo" -> end multiplo de MiB, dentro del disco + real = 250_059_350_016 # SSD 250G tipico, no multiplo de MiB + e = usable_end(real) + assert e % MiB == 0 and 0 < e <= real - END_MARGIN, e + # disco MiB-exacto (VM 40G) -> pierde justo END_MARGIN, nada mas + assert usable_end(40 * 1024 * MiB) == 40 * 1024 * MiB - MiB print("ok") if __name__ == "__main__":