Skip to content

Commit 9ead61b

Browse files
committed
efi: Extend install() to support usr/lib/efi
1 parent c5f51a6 commit 9ead61b

File tree

2 files changed

+46
-17
lines changed

2 files changed

+46
-17
lines changed

src/efi.rs

Lines changed: 29 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,35 @@ 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 = Utf8Path::new(src_root);
373+
let efilib_path = src_path.join(EFILIB);
374+
let efi_comps = if efilib_path.exists() {
375+
get_efi_component_from_usr(&src_path, EFILIB)?
376+
} else {
377+
None
378+
};
379+
380+
let vendor_path = if let Some(efi_components) = efi_comps {
381+
for efi in efi_components {
382+
log::trace!("Copy {} to {}", efi.path, destpath.display());
383+
util::copy_in_fd(&src_dir, &efi.path, &destpath)?;
384+
}
385+
efilib_path
386+
} else {
387+
let updates = Utf8PathBuf::from_path_buf(component_updatedirname(self))
388+
.expect("Invalide UTF-8 path");
389+
390+
util::copy_in_fd(&src_dir, &updates, &destpath)?;
391+
updates
392+
};
393+
394+
let ft =
395+
crate::filetree::FileTree::new_from_dir(&src_dir.sub_dir(vendor_path.as_std_path())?)?;
396+
382397
if update_firmware {
383-
if let Some(vendordir) = self.get_efi_vendor(&Path::new(src_root))? {
398+
if let Some(vendordir) =
399+
self.get_efi_vendor(src_path.join(vendor_path).as_std_path())?
400+
{
384401
self.update_firmware(device, destd, &vendordir)?
385402
}
386403
}
@@ -449,12 +466,7 @@ impl Component for Efi {
449466
let mut packages = Vec::new();
450467
let sysroot_dir = Dir::open_ambient_dir(sysroot_path, cap_std::ambient_authority())?;
451468
for efi in efi_components {
452-
Command::new("cp")
453-
.args(["-rp", "--reflink=auto"])
454-
.arg(&efi.path)
455-
.arg(crate::model::BOOTUPD_UPDATES_DIR)
456-
.current_dir(format!("/proc/self/fd/{}", sysroot_dir.as_raw_fd()))
457-
.run()?;
469+
util::copy_in_fd(&sysroot_dir, &efi.path, crate::model::BOOTUPD_UPDATES_DIR)?;
458470
packages.push(format!("{}-{}", efi.name, efi.version));
459471
}
460472

src/util.rs

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

55
use anyhow::{bail, Context, Result};
6+
use bootc_internal_utils::CommandRunExt;
7+
use camino::Utf8Path;
68
use openat_ext::OpenatDirExt;
9+
use rustix::fd::AsRawFd;
710

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

0 commit comments

Comments
 (0)