From 4e24c9926ffc1559fd10933bbc7ee2b67b89ce27 Mon Sep 17 00:00:00 2001 From: Huijing Hei Date: Sun, 30 Nov 2025 16:40:04 +0800 Subject: [PATCH 1/2] grubconfig: minor changes to replace variables using `const` --- src/grubconfigs.rs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/grubconfigs.rs b/src/grubconfigs.rs index 17be02a4..e80d7a3a 100644 --- a/src/grubconfigs.rs +++ b/src/grubconfigs.rs @@ -12,7 +12,7 @@ use crate::freezethaw::fsfreeze_thaw_cycle; /// The subdirectory of /boot we use const GRUB2DIR: &str = "grub2"; -const CONFIGDIR: &str = "/usr/lib/bootupd/grub2-static"; +const CONFIGDIR: &str = "usr/lib/bootupd/grub2-static"; const DROPINDIR: &str = "configs.d"; // The related grub files const GRUBENV: &str = "grubenv"; @@ -43,11 +43,10 @@ pub(crate) fn install( } let configdir = if let Some(src_root) = src_root { - // strip the leading `/` to make the path relative to the given - // source root - src_root.sub_dir(Path::new(CONFIGDIR).strip_prefix("/")?)? + src_root.sub_dir(CONFIGDIR)? } else { - openat::Dir::open(Path::new(CONFIGDIR))? + // Open / if there is no source root + openat::Dir::open("/")?.sub_dir(CONFIGDIR)? }; let mut config = String::from("# Generated by bootupd / do not edit\n\n"); @@ -58,7 +57,7 @@ pub(crate) fn install( .read_to_string(&mut pre)?; config.push_str(pre.as_str()); - let dropindir = configdir.sub_dir(Path::new(DROPINDIR))?; + let dropindir = configdir.sub_dir(DROPINDIR)?; // Sort the files for reproducibility let mut entries = dropindir .list_dir(".")? @@ -85,7 +84,7 @@ pub(crate) fn install( let grub2dir = bootdir.sub_dir(GRUB2DIR)?; grub2dir - .write_file_contents("grub.cfg", GRUBCONFIG_FILE_MODE, config.as_bytes()) + .write_file_contents(GRUBCONFIG, GRUBCONFIG_FILE_MODE, config.as_bytes()) .context("Copying grub-static.cfg")?; println!("Installed: grub.cfg"); @@ -113,7 +112,7 @@ pub(crate) fn install( if let Some(vendordir) = installed_efi_vendor { log::debug!("vendordir={:?}", &vendordir); let vendor = PathBuf::from(vendordir); - let target = &vendor.join("grub.cfg"); + let target = &vendor.join(GRUBCONFIG); let dest_efidir = target_root .sub_dir_optional("boot/efi/EFI") .context("Opening /boot/efi/EFI")?; From bb79b4dd6565cb7e483ba41e369b2e31b735a878 Mon Sep 17 00:00:00 2001 From: Huijing Hei Date: Sun, 30 Nov 2025 16:44:12 +0800 Subject: [PATCH 2/2] efi: install `grub.cfg` under new vendor during updates When doing switches from RHEL 10 to Fedora 43, after reboot, check `grub.cfg` and `bootuuid.cfg` are in old vendor, that will make the machine failed to boot a second time since `grub.cfg` cannot be found. We need to install the two files under new vendor during updates. See https://github.com/coreos/bootupd/issues/1024 --- src/efi.rs | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/src/efi.rs b/src/efi.rs index cb24c4c3..72b51d15 100644 --- a/src/efi.rs +++ b/src/efi.rs @@ -481,14 +481,46 @@ impl Component for Efi { anyhow::bail!("Failed to find all esp devices"); }; + // Get old vendor name from installed filetree + let old_vendor = { + let mut vendor = None; + for child in currentf.children.keys() { + if child.ends_with(SHIM) { + vendor = child.strip_suffix(&format!("/{SHIM}")); + break; + } + } + let Some(vendor) = vendor else { + anyhow::bail!("Failed to find current vendor"); + }; + vendor.to_owned() + }; + + // Get new vendor name + let new_vendor = { + let sysroot = rootcxt.path.as_std_path(); + let Some(vendor) = self.get_efi_vendor(&sysroot.join(&updated_path))? else { + anyhow::bail!("Failed to find efi vendor in new update"); + }; + vendor.to_owned() + }; + for esp in esp_devices { let destpath = &self.ensure_mounted_esp(rootcxt.path.as_ref(), Path::new(&esp))?; - let destdir = openat::Dir::open(&destpath.join("EFI")).context("opening EFI dir")?; + let dest_efi = destpath.join("EFI"); + let destdir = openat::Dir::open(&dest_efi).context("opening EFI dir")?; validate_esp_fstype(&destdir)?; + log::trace!("applying diff: {}", &diff); filetree::apply_diff(&updated, &destdir, &diff, None) .context("applying filesystem changes")?; + // Install grub.cfg under new vendor + if new_vendor != old_vendor { + grubconfigs::install(sysroot_dir, None, Some(&new_vendor), true)?; + destdir.remove_all(&old_vendor)?; + } + // Do the sync before unmount fsfreeze_thaw_cycle(destdir.open_file(".")?)?; drop(destdir); @@ -605,7 +637,7 @@ impl Component for Efi { // Does not support multiple shim for efi if shim_files.len() > 1 { - anyhow::bail!("Found multiple {SHIM} in the image"); + anyhow::bail!("Found multiple {SHIM} in the image: {:?}", shim_files); } if let Some(p) = shim_files.first() { let p = p