@@ -63,6 +63,9 @@ pub(crate) const EFI_LINUX: &str = "EFI/Linux";
6363const SYSTEMD_TIMEOUT : & str = "timeout 5" ;
6464const 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