Skip to content

Commit 798f2a2

Browse files
committed
efi: Extend install() to support usr/lib/efi
1 parent 56eb7d6 commit 798f2a2

File tree

2 files changed

+40
-17
lines changed

2 files changed

+40
-17
lines changed

src/efi.rs

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -365,8 +365,6 @@ impl Component for Efi {
365365
anyhow::bail!("No update metadata for component {} found", self.name());
366366
};
367367
log::debug!("Found metadata {}", meta.version);
368-
let srcdir_name = component_updatedirname(self);
369-
let ft = crate::filetree::FileTree::new_from_dir(&src_dir.sub_dir(&srcdir_name)?)?;
370368

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

390-
// TODO - add some sort of API that allows directly setting the working
391-
// directory to a file descriptor.
392-
std::process::Command::new("cp")
393-
.args(["-rp", "--reflink=auto"])
394-
.arg(&srcdir_name)
395-
.arg(destpath)
396-
.current_dir(format!("/proc/self/fd/{}", src_dir.as_raw_fd()))
397-
.run()?;
388+
let src_path = Path::new(src_root);
389+
let efilib_path = src_path.join(EFILIB);
390+
let efi_comps = if efilib_path.exists() {
391+
get_efi_component_from_usr(&Utf8Path::new(src_root), EFILIB)?
392+
} else {
393+
None
394+
};
395+
396+
let efi_path = if let Some(efi_components) = efi_comps {
397+
for efi in efi_components {
398+
log::trace!("Copy {} to {}", efi.path, destpath.display());
399+
util::copy_in_fd(&src_dir, &efi.path, &destpath)?;
400+
}
401+
PathBuf::from(EFILIB)
402+
} else {
403+
let updates = component_updatedirname(self);
404+
util::copy_in_fd(&src_dir, &updates, &destpath)?;
405+
updates
406+
};
407+
408+
let ft = crate::filetree::FileTree::new_from_dir(&src_dir.sub_dir(&efi_path)?)?;
409+
398410
if update_firmware {
399-
if let Some(vendordir) = self.get_efi_vendor(&Path::new(src_root))? {
411+
if let Some(vendordir) = self.get_efi_vendor(&src_path.join(efi_path))? {
400412
self.update_firmware(device, destd, &vendordir)?
401413
}
402414
}
@@ -466,12 +478,7 @@ impl Component for Efi {
466478
let mut modules_vec: Vec<Module> = vec![];
467479
let sysroot_dir = Dir::open_ambient_dir(sysroot_path, cap_std::ambient_authority())?;
468480
for efi in efi_components {
469-
Command::new("cp")
470-
.args(["-rp", "--reflink=auto"])
471-
.arg(&efi.path)
472-
.arg(crate::model::BOOTUPD_UPDATES_DIR)
473-
.current_dir(format!("/proc/self/fd/{}", sysroot_dir.as_raw_fd()))
474-
.run()?;
481+
util::copy_in_fd(&sysroot_dir, &efi.path, crate::model::BOOTUPD_UPDATES_DIR)?;
475482
packages.push(format!("{}-{}", efi.name, efi.version));
476483
modules_vec.push(Module {
477484
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)