Skip to content

Commit 923c594

Browse files
committed
efi: extend support for update(), adopt_update(), and
`validate()` across all ESPs
1 parent 0f9d1ac commit 923c594

File tree

1 file changed

+50
-59
lines changed

1 file changed

+50
-59
lines changed

src/efi.rs

Lines changed: 50 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use std::path::{Path, PathBuf};
1010
use std::process::Command;
1111

1212
use anyhow::{bail, Context, Result};
13+
use bootc_utils::CommandRunExt;
1314
use cap_std::fs::Dir;
1415
use cap_std_ext::cap_std;
1516
use fn_error_context::context;
@@ -22,7 +23,7 @@ use widestring::U16CString;
2223
use crate::bootupd::RootContext;
2324
use crate::model::*;
2425
use crate::ostreeutil;
25-
use crate::util::{self, CommandRunExt};
26+
use crate::util;
2627
use crate::{blockdev, filetree};
2728
use crate::{component::*, packagesystem};
2829

@@ -256,32 +257,30 @@ impl Component for Efi {
256257
return Ok(None);
257258
};
258259

259-
let esp_devices = esp_devices.unwrap_or_default();
260-
let mut devices = esp_devices.iter();
261-
let Some(esp) = devices.next() else {
262-
anyhow::bail!("Failed to find esp device");
263-
};
264-
265-
if let Some(next_esp) = devices.next() {
266-
anyhow::bail!(
267-
"Found multiple esp devices {esp} and {next_esp}; not currently supported"
268-
);
269-
}
270-
let destpath = &self.ensure_mounted_esp(rootcxt.path.as_ref(), Path::new(&esp))?;
271-
272-
let destdir = &openat::Dir::open(&destpath.join("EFI"))
273-
.with_context(|| format!("opening EFI dir {}", destpath.display()))?;
274-
validate_esp_fstype(&destdir)?;
275260
let updated = rootcxt
276261
.sysroot
277262
.sub_dir(&component_updatedirname(self))
278263
.context("opening update dir")?;
279264
let updatef = filetree::FileTree::new_from_dir(&updated).context("reading update dir")?;
280-
// For adoption, we should only touch files that we know about.
281-
let diff = updatef.relative_diff_to(&destdir)?;
282-
log::trace!("applying adoption diff: {}", &diff);
283-
filetree::apply_diff(&updated, &destdir, &diff, None)
284-
.context("applying filesystem changes")?;
265+
266+
let esp_devices = esp_devices.unwrap_or_default();
267+
for esp in esp_devices {
268+
let destpath = &self.ensure_mounted_esp(rootcxt.path.as_ref(), Path::new(&esp))?;
269+
270+
let efidir = openat::Dir::open(&destpath.join("EFI")).context("opening EFI dir")?;
271+
validate_esp_fstype(&efidir)?;
272+
273+
// For adoption, we should only touch files that we know about.
274+
let diff = updatef.relative_diff_to(&efidir)?;
275+
log::trace!("applying adoption diff: {}", &diff);
276+
filetree::apply_diff(&updated, &efidir, &diff, None)
277+
.context("applying filesystem changes")?;
278+
279+
// Do the sync before unmount
280+
efidir.syncfs()?;
281+
drop(efidir);
282+
self.unmount().context("unmount after adopt")?;
283+
}
285284
Ok(Some(InstalledContent {
286285
meta: updatemeta.clone(),
287286
filetree: Some(updatef),
@@ -354,24 +353,21 @@ impl Component for Efi {
354353
let Some(esp_devices) = blockdev::find_colocated_esps(&rootcxt.devices)? else {
355354
anyhow::bail!("Failed to find all esp devices");
356355
};
357-
let mut devices = esp_devices.iter();
358-
let Some(esp) = devices.next() else {
359-
anyhow::bail!("Failed to find esp device");
360-
};
361356

362-
if let Some(next_esp) = devices.next() {
363-
anyhow::bail!(
364-
"Found multiple esp devices {esp} and {next_esp}; not currently supported"
365-
);
357+
for esp in esp_devices {
358+
let destpath = &self.ensure_mounted_esp(rootcxt.path.as_ref(), Path::new(&esp))?;
359+
let destdir = openat::Dir::open(&destpath.join("EFI")).context("opening EFI dir")?;
360+
validate_esp_fstype(&destdir)?;
361+
log::trace!("applying diff: {}", &diff);
362+
filetree::apply_diff(&updated, &destdir, &diff, None)
363+
.context("applying filesystem changes")?;
364+
365+
// Do the sync before unmount
366+
destdir.syncfs()?;
367+
drop(destdir);
368+
self.unmount().context("unmount after update")?;
366369
}
367-
let destpath = &self.ensure_mounted_esp(rootcxt.path.as_ref(), Path::new(&esp))?;
368-
369-
let destdir = &openat::Dir::open(&destpath.join("EFI"))
370-
.with_context(|| format!("opening EFI dir {}", destpath.display()))?;
371-
validate_esp_fstype(&destdir)?;
372-
log::trace!("applying diff: {}", &diff);
373-
filetree::apply_diff(&updated, &destdir, &diff, None)
374-
.context("applying filesystem changes")?;
370+
375371
let adopted_from = None;
376372
Ok(InstalledContent {
377373
meta: updatemeta,
@@ -430,31 +426,26 @@ impl Component for Efi {
430426
.as_ref()
431427
.ok_or_else(|| anyhow::anyhow!("No filetree for installed EFI found!"))?;
432428

429+
let mut errs = Vec::new();
433430
let esp_devices = esp_devices.unwrap_or_default();
434-
let mut devices = esp_devices.iter();
435-
let Some(esp) = devices.next() else {
436-
anyhow::bail!("Failed to find esp device");
437-
};
431+
for esp in esp_devices.iter() {
432+
let destpath = &self.ensure_mounted_esp(Path::new("/"), Path::new(&esp))?;
438433

439-
if let Some(next_esp) = devices.next() {
440-
anyhow::bail!(
441-
"Found multiple esp devices {esp} and {next_esp}; not currently supported"
442-
);
443-
}
444-
let destpath = &self.ensure_mounted_esp(Path::new("/"), Path::new(&esp))?;
434+
let efidir = openat::Dir::open(&destpath.join("EFI"))
435+
.with_context(|| format!("opening EFI dir {}", destpath.display()))?;
436+
let diff = currentf.relative_diff_to(&efidir)?;
445437

446-
let efidir = &openat::Dir::open(&destpath.join("EFI"))
447-
.with_context(|| format!("opening EFI dir {}", destpath.display()))?;
448-
449-
let diff = currentf.relative_diff_to(&efidir)?;
450-
let mut errs = Vec::new();
451-
for f in diff.changes.iter() {
452-
errs.push(format!("Changed: {}", f));
453-
}
454-
for f in diff.removals.iter() {
455-
errs.push(format!("Removed: {}", f));
438+
for f in diff.changes.iter() {
439+
errs.push(format!("Changed: {}", f));
440+
}
441+
for f in diff.removals.iter() {
442+
errs.push(format!("Removed: {}", f));
443+
}
444+
assert_eq!(diff.additions.len(), 0);
445+
drop(efidir);
446+
self.unmount().context("unmount after validate")?;
456447
}
457-
assert_eq!(diff.additions.len(), 0);
448+
458449
if !errs.is_empty() {
459450
Ok(ValidationResult::Errors(errs))
460451
} else {

0 commit comments

Comments
 (0)