Skip to content

Commit 166a423

Browse files
committed
composefs: Fix uki boot with grub2 on fedora aarch64
In Fedora 44 (at least), the grub2 EFI binary for aarch64 doesn't include the chainloader module (but the x84 one does). We insmod this in our menu files, which means we get this at boot: ``` error: ../../grub-core/fs/fshelp.c:find_file:257:file `/grub2/arm64-efi/chain.mod' not found. error: ../../grub-core/script/function.c:grub_script_function_find:119:can't find command `chainloader'. ``` In general, we don't know what modules are built in for any particular bootc image, so to be safe we copy all the modules we're using (that exist) into /boot/grub2. Signed-off-by: Alexander Larsson <alexl@redhat.com>
1 parent 7d6df9a commit 166a423

1 file changed

Lines changed: 33 additions & 0 deletions

File tree

  • crates/lib/src/bootc_composefs

‎crates/lib/src/bootc_composefs/boot.rs‎

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,18 @@ const AUTH_EXT: &str = "auth";
142142
/// This is relative to the ESP
143143
pub(crate) const BOOTC_UKI_DIR: &str = "EFI/Linux/bootc";
144144

145+
// These are the modules we insmod in out menu config files
146+
const GRUB_MODULES_USED: [&str; 2] = ["fat.mod", "chain.mod"];
147+
148+
fn grub_efi_module_dir() -> Option<&'static str> {
149+
match std::env::consts::ARCH {
150+
"aarch64" => Some("arm64-efi"),
151+
"x86_64" => Some("x86_64-efi"),
152+
"riscv64" => Some("riscv64-efi"),
153+
_ => None,
154+
}
155+
}
156+
145157
/// Directory (relative to the ESP) where systemd-stub looks for UKI addons that apply
146158
/// to *every* UKI, as opposed to addons scoped to a single UKI (which live alongside
147159
/// it under [`BOOTC_UKI_DIR`]). Unlike per-UKI addons, these aren't tied to a single
@@ -2158,6 +2170,27 @@ pub(crate) async fn setup_composefs_boot(
21582170
Some(bind_boot_path.as_path()),
21592171
)?;
21602172

2173+
if matches!(postfetch.detected_bootloader, Bootloader::Grub) {
2174+
// The menu config files insmod some modules, these may be either built
2175+
// into the GRUB EFI binary, or loaded from /boot/grub2. For example, the
2176+
// fedora aarch64 grub doesn't include chain.mod. We install all the modules
2177+
// we can find to avoid potential problems.
2178+
if let Some(module_dir) = grub_efi_module_dir() {
2179+
for module in GRUB_MODULES_USED {
2180+
let source = format!("usr/lib/grub/{module_dir}/{module}");
2181+
if mounted_root.dir().try_exists(&source)? {
2182+
let target = format!("boot/grub2/{module_dir}");
2183+
root_setup.physical_root.create_dir_all(&target)?;
2184+
let target = root_setup.physical_root.open_dir(&target)?;
2185+
mounted_root
2186+
.dir()
2187+
.copy(&source, &target, module)
2188+
.with_context(|| format!("Installing GRUB module {module}"))?;
2189+
}
2190+
}
2191+
}
2192+
}
2193+
21612194
// FIXME: Remove this hack once we have support in bootupd
21622195
if matches!(postfetch.detected_bootloader, Bootloader::GrubCC) {
21632196
// bootupctl wrote this under the physical root's real /boot (via

0 commit comments

Comments
 (0)