Skip to content

Commit d2f206e

Browse files
committed
Add copy-to-boot functionality
This is part of Fedora BootLoaderUpdatesPhase1: https://fedoraproject.org/wiki/Changes/BootLoaderUpdatesPhase1
1 parent 5e94f83 commit d2f206e

File tree

3 files changed

+97
-0
lines changed

3 files changed

+97
-0
lines changed

src/bootupd.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -683,6 +683,23 @@ pub(crate) fn client_run_migrate_static_grub_config() -> Result<()> {
683683
Ok(())
684684
}
685685

686+
/// Copy bootloader files from /usr/lib/efi to boot/ESP for package mode installations.
687+
pub(crate) fn copy_to_boot() -> Result<()> {
688+
let all_components = get_components_impl(false);
689+
if all_components.is_empty() {
690+
println!("No components available for this platform.");
691+
return Ok(());
692+
}
693+
694+
for component in all_components.values() {
695+
component
696+
.package_mode_copy_to_boot()
697+
.with_context(|| format!("Failed to copy component {} to boot", component.name()))?;
698+
}
699+
700+
Ok(())
701+
}
702+
686703
/// Writes a stripped GRUB config to `stripped_config_name`, removing lines between
687704
/// `### BEGIN /etc/grub.d/15_ostree ###` and `### END /etc/grub.d/15_ostree ###`.
688705
fn strip_grub_config_file(

src/component.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,11 @@ pub(crate) trait Component {
7979

8080
/// Locating efi vendor dir
8181
fn get_efi_vendor(&self, sysroot: &Path) -> Result<Option<String>>;
82+
83+
/// Copy from /usr/lib/efi to boot/ESP.
84+
fn package_mode_copy_to_boot(&self) -> Result<()> {
85+
Ok(())
86+
}
8287
}
8388

8489
/// Given a component name, create an implementation.

src/efi.rs

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,76 @@ impl Efi {
183183
clear_efi_target(&product_name)?;
184184
create_efi_boot_entry(device, esp_part_num.trim(), &loader, &product_name)
185185
}
186+
187+
/// Copy from /usr/lib/efi to boot/ESP.
188+
fn package_mode_copy_to_boot_impl(&self) -> Result<()> {
189+
let sysroot = Path::new("/");
190+
let sysroot_path =
191+
Utf8Path::from_path(sysroot).context("Sysroot path is not valid UTF-8")?;
192+
193+
// Find components in /usr/lib/efi
194+
let efi_comps = match get_efi_component_from_usr(sysroot_path, EFILIB)? {
195+
Some(comps) if !comps.is_empty() => comps,
196+
_ => {
197+
log::debug!("No EFI components found in /usr/lib/efi");
198+
return Ok(());
199+
}
200+
};
201+
202+
// Find all ESP devices
203+
let devices = blockdev::get_devices(sysroot)?;
204+
let Some(esp_devices) = blockdev::find_colocated_esps(&devices)? else {
205+
anyhow::bail!("No ESP found");
206+
};
207+
208+
let sysroot_dir = openat::Dir::open(sysroot).context("Opening sysroot for reading")?;
209+
210+
// Copy to all ESPs
211+
for esp in esp_devices {
212+
let esp_path = self.ensure_mounted_esp(sysroot, Path::new(&esp))?;
213+
214+
let esp_dir = openat::Dir::open(&esp_path)
215+
.with_context(|| format!("Opening ESP at {}", esp_path.display()))?;
216+
validate_esp_fstype(&esp_dir)?;
217+
218+
// Copy each component
219+
for efi_comp in &efi_comps {
220+
log::info!(
221+
"Copying EFI component {} version {} to ESP at {}",
222+
efi_comp.name,
223+
efi_comp.version,
224+
esp_path.display()
225+
);
226+
227+
let dest_str = esp_path
228+
.to_str()
229+
.context("ESP path contains invalid UTF-8")?;
230+
filetree::copy_dir_with_args(
231+
&sysroot_dir,
232+
efi_comp.path.as_str(),
233+
dest_str,
234+
OPTIONS,
235+
)
236+
.with_context(|| {
237+
format!(
238+
"Failed to copy {} from {} to {}",
239+
efi_comp.name, efi_comp.path, dest_str
240+
)
241+
})?;
242+
}
243+
244+
// Sync filesystem
245+
let efidir = openat::Dir::open(&esp_path.join("EFI"))
246+
.context("Opening EFI directory for sync")?;
247+
fsfreeze_thaw_cycle(efidir.open_file(".")?)?;
248+
}
249+
250+
log::info!(
251+
"Successfully copied {} EFI component(s) to all ESPs",
252+
efi_comps.len()
253+
);
254+
Ok(())
255+
}
186256
}
187257

188258
#[context("Get product name")]
@@ -622,6 +692,11 @@ impl Component for Efi {
622692
anyhow::bail!("Failed to find {SHIM} in the image")
623693
}
624694
}
695+
696+
/// Package mode copy: Simple copy from /usr/lib/efi to boot/ESP.
697+
fn package_mode_copy_to_boot(&self) -> Result<()> {
698+
self.package_mode_copy_to_boot_impl()
699+
}
625700
}
626701

627702
impl Drop for Efi {

0 commit comments

Comments
 (0)