Skip to content

Commit 05ed1c0

Browse files
Johan-Liebert1cgwalters
authored andcommitted
composefs/boot: Fix kernel path in grub cfg if /boot is a partition
If `/boot` is a separate partition, the kernel + initrd paths need to be absolute to `/`, which was not the case until now as they were always absolute to the actual rootfs Signed-off-by: Pragyan Poudyal <[email protected]>
1 parent 27b6189 commit 05ed1c0

File tree

1 file changed

+37
-27
lines changed
  • crates/lib/src/bootc_composefs

1 file changed

+37
-27
lines changed

crates/lib/src/bootc_composefs/boot.rs

Lines changed: 37 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ pub(crate) const EFI_LINUX: &str = "EFI/Linux";
6363
const SYSTEMD_TIMEOUT: &str = "timeout 5";
6464
const SYSTEMD_LOADER_CONF_PATH: &str = "loader/loader.conf";
6565

66+
const INITRD: &str = "initrd";
67+
const VMLINUZ: &str = "vmlinuz";
68+
6669
/// We want to be able to control the ordering of UKIs so we put them in a directory that's not the
6770
/// directory specified by the BLS spec. We do this because we want systemd-boot to only look at
6871
/// our config files and not show the actual UKIs in the bootloader menu
@@ -280,7 +283,7 @@ fn write_bls_boot_entries_to_disk(
280283

281284
entries_dir
282285
.atomic_write(
283-
"vmlinuz",
286+
VMLINUZ,
284287
read_file(&entry.vmlinuz, &repo).context("Reading vmlinuz")?,
285288
)
286289
.context("Writing vmlinuz to path")?;
@@ -291,7 +294,7 @@ fn write_bls_boot_entries_to_disk(
291294

292295
entries_dir
293296
.atomic_write(
294-
"initrd",
297+
INITRD,
295298
read_file(initramfs, &repo).context("Reading initrd")?,
296299
)
297300
.context("Writing initrd to path")?;
@@ -351,12 +354,11 @@ fn osrel_title_and_version(
351354
Ok(Some((title, version)))
352355
}
353356

354-
struct BLSEntryPath<'a> {
357+
struct BLSEntryPath {
355358
/// Where to write vmlinuz/initrd
356359
entries_path: Utf8PathBuf,
357360
/// The absolute path, with reference to the partition's root, where the vmlinuz/initrd are written to
358-
/// We need this as when installing, the mounted path will not
359-
abs_entries_path: &'a str,
361+
abs_entries_path: Utf8PathBuf,
360362
/// Where to write the .conf files
361363
config_path: Utf8PathBuf,
362364
}
@@ -419,14 +421,29 @@ pub(crate) fn setup_composefs_bls_boot(
419421
let is_upgrade = matches!(setup_type, BootSetupType::Upgrade(..));
420422

421423
let (entry_paths, _tmpdir_guard) = match bootloader {
422-
Bootloader::Grub => (
423-
BLSEntryPath {
424-
entries_path: root_path.join("boot"),
425-
config_path: root_path.join("boot"),
426-
abs_entries_path: "boot",
427-
},
428-
None,
429-
),
424+
Bootloader::Grub => {
425+
let root = Dir::open_ambient_dir(&root_path, ambient_authority())
426+
.context("Opening root path")?;
427+
428+
// Grub wants the paths to be absolute against the mounted drive that the kernel +
429+
// initrd live in
430+
//
431+
// If "boot" is a partition, we want the paths to be absolute to "/"
432+
let entries_path = match root.is_mountpoint("boot")? {
433+
Some(true) => "/",
434+
// We can be fairly sure that the kernels we target support `statx`
435+
Some(false) | None => "/boot",
436+
};
437+
438+
(
439+
BLSEntryPath {
440+
entries_path: root_path.join("boot"),
441+
config_path: root_path.join("boot"),
442+
abs_entries_path: entries_path.into(),
443+
},
444+
None,
445+
)
446+
}
430447

431448
Bootloader::Systemd => {
432449
let efi_mount = mount_esp(&esp_device).context("Mounting ESP")?;
@@ -438,7 +455,7 @@ pub(crate) fn setup_composefs_bls_boot(
438455
BLSEntryPath {
439456
entries_path: efi_linux_dir,
440457
config_path: mounted_efi.clone(),
441-
abs_entries_path: EFI_LINUX,
458+
abs_entries_path: Utf8PathBuf::from("/").join(EFI_LINUX),
442459
},
443460
Some(efi_mount),
444461
)
@@ -474,10 +491,8 @@ pub(crate) fn setup_composefs_bls_boot(
474491
.with_sort_key(default_sort_key.into())
475492
.with_version(version)
476493
.with_cfg(BLSConfigType::NonEFI {
477-
linux: format!("/{}/{id_hex}/vmlinuz", entry_paths.abs_entries_path).into(),
478-
initrd: vec![
479-
format!("/{}/{id_hex}/initrd", entry_paths.abs_entries_path).into()
480-
],
494+
linux: entry_paths.abs_entries_path.join(&id_hex).join(VMLINUZ),
495+
initrd: vec![entry_paths.abs_entries_path.join(&id_hex).join(INITRD)],
481496
options: Some(cmdline_refs),
482497
});
483498

@@ -491,15 +506,10 @@ pub(crate) fn setup_composefs_bls_boot(
491506
ref mut initrd,
492507
..
493508
} => {
494-
*linux =
495-
format!("/{}/{symlink_to}/vmlinuz", entry_paths.abs_entries_path)
496-
.into();
497-
498-
*initrd = vec![format!(
499-
"/{}/{symlink_to}/initrd",
500-
entry_paths.abs_entries_path
501-
)
502-
.into()];
509+
*linux = entry_paths.abs_entries_path.join(&symlink_to).join(VMLINUZ);
510+
511+
*initrd =
512+
vec![entry_paths.abs_entries_path.join(&symlink_to).join(INITRD)];
503513
}
504514

505515
_ => unreachable!(),

0 commit comments

Comments
 (0)