Skip to content

Commit f5a32fc

Browse files
committed
efi: Extend install() to support usr/lib/efi
1 parent d337dca commit f5a32fc

File tree

2 files changed

+41
-17
lines changed

2 files changed

+41
-17
lines changed

src/efi.rs

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -349,8 +349,6 @@ impl Component for Efi {
349349
anyhow::bail!("No update metadata for component {} found", self.name());
350350
};
351351
log::debug!("Found metadata {}", meta.version);
352-
let srcdir_name = component_updatedirname(self);
353-
let ft = crate::filetree::FileTree::new_from_dir(&src_dir.sub_dir(&srcdir_name)?)?;
354352

355353
// Let's attempt to use an already mounted ESP at the target
356354
// dest_root if one is already mounted there in a known ESP location.
@@ -371,16 +369,31 @@ impl Component for Efi {
371369
.with_context(|| format!("opening dest dir {}", destpath.display()))?;
372370
validate_esp_fstype(destd)?;
373371

374-
// TODO - add some sort of API that allows directly setting the working
375-
// directory to a file descriptor.
376-
std::process::Command::new("cp")
377-
.args(["-rp", "--reflink=auto"])
378-
.arg(&srcdir_name)
379-
.arg(destpath)
380-
.current_dir(format!("/proc/self/fd/{}", src_dir.as_raw_fd()))
381-
.run()?;
372+
let src_path = Path::new(src_root);
373+
let efilib_path = src_path.join(EFILIB);
374+
let src_path_utf8 = Utf8Path::from_path(src_path).expect("Path must be valid UTF-8");
375+
let efi_comps = if efilib_path.exists() {
376+
get_efi_component_from_usr(&src_path_utf8, EFILIB)?
377+
} else {
378+
None
379+
};
380+
381+
let efi_path = if let Some(efi_components) = efi_comps {
382+
for efi in efi_components {
383+
log::trace!("Copy {} to {}", efi.path, destpath.display());
384+
util::copy_in_fd(&src_dir, &efi.path, &destpath)?;
385+
}
386+
efilib_path
387+
} else {
388+
let updates = component_updatedirname(self);
389+
util::copy_in_fd(&src_dir, &updates, &destpath)?;
390+
updates
391+
};
392+
393+
let ft = crate::filetree::FileTree::new_from_dir(&src_dir.sub_dir(&efi_path)?)?;
394+
382395
if update_firmware {
383-
if let Some(vendordir) = self.get_efi_vendor(&Path::new(src_root))? {
396+
if let Some(vendordir) = self.get_efi_vendor(&src_path.join(efi_path))? {
384397
self.update_firmware(device, destd, &vendordir)?
385398
}
386399
}
@@ -450,12 +463,7 @@ impl Component for Efi {
450463
let mut modules_vec: Vec<Module> = vec![];
451464
let sysroot_dir = Dir::open_ambient_dir(sysroot_path, cap_std::ambient_authority())?;
452465
for efi in efi_components {
453-
Command::new("cp")
454-
.args(["-rp", "--reflink=auto"])
455-
.arg(&efi.path)
456-
.arg(crate::model::BOOTUPD_UPDATES_DIR)
457-
.current_dir(format!("/proc/self/fd/{}", sysroot_dir.as_raw_fd()))
458-
.run()?;
466+
util::copy_in_fd(&sysroot_dir, &efi.path, crate::model::BOOTUPD_UPDATES_DIR)?;
459467
packages.push(format!("{}-{}", efi.name, efi.version));
460468
modules_vec.push(Module {
461469
name: efi.name,

src/util.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ use std::path::Path;
33
use std::process::Command;
44

55
use anyhow::{bail, Context, Result};
6+
use bootc_internal_utils::CommandRunExt;
67
use openat_ext::OpenatDirExt;
8+
use rustix::fd::AsRawFd;
79

810
/// Parse an environment variable as UTF-8
911
#[allow(dead_code)]
@@ -120,3 +122,17 @@ impl Drop for SignalTerminationGuard {
120122
signal_hook_registry::unregister(self.0);
121123
}
122124
}
125+
126+
pub(crate) fn copy_in_fd<F: AsRawFd, P1: AsRef<Path>, P2: AsRef<Path>>(
127+
fd: &F,
128+
src: P1,
129+
dest: P2,
130+
) -> Result<()> {
131+
let cwd = format!("/proc/self/fd/{}", fd.as_raw_fd());
132+
Command::new("cp")
133+
.args(["-rp", "--reflink=auto"])
134+
.arg(src.as_ref())
135+
.arg(dest.as_ref())
136+
.current_dir(cwd)
137+
.run()
138+
}

0 commit comments

Comments
 (0)