Repository navigation
composefs: install --bootloader systemd creates no firmware boot entry (bootctl --root skips EFI variables) #2557
Description
Environment: bootc 1.17.1 (built from source, no selinux feature) in an Arch Linux based image (systemd 262), composefs backend, btrfs root, UEFI. Installed from a live ISO with podman run --privileged --pid=host -v /dev:/dev -v /var/lib/containers:/var/lib/containers -v <target>:/target <image> bootc install to-filesystem --composefs-backend --bootloader systemd --skip-finalize /target, reproduced in QEMU/OVMF and used on a ThinkPad T480.
What happens: systemd-boot is installed to EFI/systemd/systemd-bootx64.efi and EFI/BOOT/BOOTX64.EFI, but no firmware boot entry ("Linux Boot Manager") is created and BootOrder is not touched. On a machine whose NVRAM still lists the previous OS (here its GRUB entry, whose root partition was just reformatted), the firmware keeps booting that entry instead of the new system. We work around it with efibootmgr --create ... --loader '\EFI\systemd\systemd-bootx64.efi' after the install.
Why: install_systemd_boot runs bootctl install --root <target> --esp-path ... and passes --no-variables only for generic_image
bootc/crates/lib/src/bootloader.rs
Lines 281 to 301 in d01e723
| let mut bootctl_args = vec![ | |
| "install", | |
| "--root", | |
| root_path, | |
| "--esp-path", | |
| esp_path_in_root.as_str(), | |
| // If we supported XBOOTLDR in the future, that'd go here with --boot-path. | |
| ]; | |
| if configopts.generic_image { | |
| bootctl_args.push("--no-variables"); | |
| // `--random-seed` was only added to `bootctl install` in systemd 257. | |
| let systemd_version = systemd_version()?; | |
| if systemd_version >= BOOTCTL_RANDOM_SEED_MIN_VERSION { | |
| bootctl_args.extend(["--random-seed", "no"]); | |
| } else { | |
| tracing::debug!( | |
| "Skipping --random-seed: requires systemd >= {BOOTCTL_RANDOM_SEED_MIN_VERSION}, found {systemd_version}" | |
| ); | |
| } | |
| } |
--update-firmware --auto.bootc/crates/lib/src/bootloader.rs
Line 157 in d01e723
| let bootupd_opts = (!configopts.generic_image).then_some(["--update-firmware", "--auto"]); |
But bootctl skips EFI variable changes whenever
--root is given, unless --variables=yes is passed explicitly: touch_variables() in systemd's src/bootctl/bootctl-util.c logs "Operating on root directory, skipping EFI variable modifications."
Suggestion: pass --variables=yes when !configopts.generic_image. (#2512 would cover installs where bootupd handles systemd-boot, but not plain bootctl installs.)
Activity
bootctl: Pass `--variables=yes` when not a generic image
bootctl: Pass `--variables=yes` when not a generic image
bootctl: Pass `--variables=yes` when not a generic image