Skip to content

composefs: install --bootloader systemd creates no firmware boot entry (bootctl --root skips EFI variables) #2557

Open

Description

@vonbloom

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

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}"
);
}
}
so for a non-generic install the intent is to update the EFI variables, like the bootupd path does with --update-firmware --auto.
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

  1. added 3 commits that reference this issue on Oct 14, 2026
    8d7e895
    c4c3aab
    69488fd
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions