From 3ff32972f8193c02cdcfde6fd579ade9706db16c Mon Sep 17 00:00:00 2001 From: r-vdp Date: Mon, 4 May 2026 12:18:11 +0200 Subject: [PATCH] nixos/systemd-boot-builder: verify content of existing entry files A file named nixos-.conf whose content no longer hashes to is corrupt. Skip it so GC removes it and a fresh entry is written. --- .../loader/systemd-boot/systemd-boot-builder.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py b/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py index 2a0693f4d237..8194f771c5bb 100644 --- a/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py +++ b/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py @@ -194,14 +194,17 @@ class BootFile: ) -> tuple["BootFile", str]: contents_hash = hashlib.sha256(contents).hexdigest() path_prefix = f"nixos-{contents_hash}" + pat = re.compile(rf"{re.escape(path_prefix)}(\+[0-9]+(-[0-9]+)?)?\.conf") path = None for e in os.scandir(path=BOOT_MOUNT_POINT / "loader" / "entries"): - mat = re.fullmatch( - rf"{re.escape(path_prefix)}(\+[0-9]+(-[0-9]+)?)?\.conf", e.name - ) - if mat is not None: - path = Path("loader/entries") / e.name - break + if pat.fullmatch(e.name) is None: + continue + # Ignore files whose content does not match the hash in their + # name so GC removes them and a fresh entry is written. + if hashlib.sha256(Path(e.path).read_bytes()).hexdigest() != contents_hash: + continue + path = Path("loader/entries") / e.name + break if path is None: counters = f"+{BOOT_COUNTING_TRIES}" if BOOT_COUNTING else "" path = Path(f"loader/entries/{path_prefix}{counters}.conf")