Skip to content

Commit 0abd8e6

Browse files
committed
efi: extend support for run_update(), adopt_update(), and
`validate()` across all ESPs
1 parent f667aed commit 0abd8e6

File tree

1 file changed

+39
-58
lines changed

1 file changed

+39
-58
lines changed

src/efi.rs

Lines changed: 39 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -256,32 +256,26 @@ impl Component for Efi {
256256
anyhow::bail!("Failed to find adoptable system")
257257
};
258258

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)?;
275259
let updated = rootcxt
276260
.sysroot
277261
.sub_dir(&component_updatedirname(self))
278262
.context("opening update dir")?;
279263
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")?;
264+
265+
let esp_devices = esp_devices.unwrap_or_default();
266+
for esp in esp_devices {
267+
let destpath = &self.ensure_mounted_esp(rootcxt.path.as_ref(), Path::new(&esp))?;
268+
269+
let esp = openat::Dir::open(&destpath.join("EFI")).context("opening EFI dir")?;
270+
validate_esp_fstype(&esp)?;
271+
272+
// For adoption, we should only touch files that we know about.
273+
let diff = updatef.relative_diff_to(&esp)?;
274+
log::trace!("applying adoption diff: {}", &diff);
275+
filetree::apply_diff(&updated, &esp, &diff, None)
276+
.context("applying filesystem changes")?;
277+
self.unmount().context("unmount after adopt")?;
278+
}
285279
Ok(InstalledContent {
286280
meta: updatemeta.clone(),
287281
filetree: Some(updatef),
@@ -354,24 +348,17 @@ impl Component for Efi {
354348
let Some(esp_devices) = blockdev::find_colocated_esps(&rootcxt.devices)? else {
355349
anyhow::bail!("Failed to find all esp devices");
356350
};
357-
let mut devices = esp_devices.iter();
358-
let Some(esp) = devices.next() else {
359-
anyhow::bail!("Failed to find esp device");
360-
};
361351

362-
if let Some(next_esp) = devices.next() {
363-
anyhow::bail!(
364-
"Found multiple esp devices {esp} and {next_esp}; not currently supported"
365-
);
352+
for esp in esp_devices {
353+
let destpath = &self.ensure_mounted_esp(rootcxt.path.as_ref(), Path::new(&esp))?;
354+
let destdir = openat::Dir::open(&destpath.join("EFI")).context("opening EFI dir")?;
355+
validate_esp_fstype(&destdir)?;
356+
log::trace!("applying diff: {}", &diff);
357+
filetree::apply_diff(&updated, &destdir, &diff, None)
358+
.context("applying filesystem changes")?;
359+
self.unmount().context("unmount after update")?;
366360
}
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")?;
361+
375362
let adopted_from = None;
376363
Ok(InstalledContent {
377364
meta: updatemeta,
@@ -430,31 +417,25 @@ impl Component for Efi {
430417
.as_ref()
431418
.ok_or_else(|| anyhow::anyhow!("No filetree for installed EFI found!"))?;
432419

420+
let mut errs = Vec::new();
433421
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-
};
422+
for esp in esp_devices.iter() {
423+
let destpath = &self.ensure_mounted_esp(Path::new("/"), Path::new(&esp))?;
438424

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))?;
425+
let efidir = &openat::Dir::open(&destpath.join("EFI"))
426+
.with_context(|| format!("opening EFI dir {}", destpath.display()))?;
427+
let diff = currentf.relative_diff_to(&efidir)?;
445428

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));
429+
for f in diff.changes.iter() {
430+
errs.push(format!("Changed: {}", f));
431+
}
432+
for f in diff.removals.iter() {
433+
errs.push(format!("Removed: {}", f));
434+
}
435+
assert_eq!(diff.additions.len(), 0);
436+
self.unmount().context("unmount after validate")?;
456437
}
457-
assert_eq!(diff.additions.len(), 0);
438+
458439
if !errs.is_empty() {
459440
Ok(ValidationResult::Errors(errs))
460441
} else {

0 commit comments

Comments
 (0)