Skip to content

Commit 86c404f

Browse files
authored
Merge pull request #923 from HuijingHei/get-parent-devices
Add `struct RootContext` with devices
2 parents 12011d3 + d8e4ddd commit 86c404f

File tree

1 file changed

+41
-11
lines changed

1 file changed

+41
-11
lines changed

src/bootupd.rs

Lines changed: 41 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use crate::efi;
1212
use crate::model::{ComponentStatus, ComponentUpdatable, ContentMetadata, SavedState, Status};
1313
use crate::util;
1414
use anyhow::{anyhow, Context, Result};
15+
use camino::{Utf8Path, Utf8PathBuf};
1516
use clap::crate_version;
1617
use fn_error_context::context;
1718
use libc::mode_t;
@@ -215,16 +216,16 @@ fn ensure_writable_boot() -> Result<()> {
215216
}
216217

217218
/// daemon implementation of component update
218-
pub(crate) fn update(name: &str) -> Result<ComponentUpdateResult> {
219-
let mut state = SavedState::load_from_disk("/")?.unwrap_or_default();
219+
pub(crate) fn update(name: &str, rootcxt: &RootContext) -> Result<ComponentUpdateResult> {
220+
let mut state = SavedState::load_from_disk(&rootcxt.path)?.unwrap_or_default();
220221
let component = component::new_from_name(name)?;
221222
let inst = if let Some(inst) = state.installed.get(name) {
222223
inst.clone()
223224
} else {
224225
anyhow::bail!("Component {} is not installed", name);
225226
};
226-
let sysroot = openat::Dir::open("/")?;
227-
let update = component.query_update(&sysroot)?;
227+
let sysroot = &rootcxt.sysroot;
228+
let update = component.query_update(sysroot)?;
228229
let update = match update.as_ref() {
229230
Some(p) if inst.meta.can_upgrade_to(p) => p,
230231
_ => return Ok(ComponentUpdateResult::AtLatestVersion),
@@ -235,6 +236,7 @@ pub(crate) fn update(name: &str) -> Result<ComponentUpdateResult> {
235236
let mut pending_container = state.pending.take().unwrap_or_default();
236237
let interrupted = pending_container.get(component.name()).cloned();
237238
pending_container.insert(component.name().into(), update.clone());
239+
let sysroot = sysroot.try_clone()?;
238240
let mut state_guard =
239241
SavedState::acquire_write_lock(sysroot).context("Failed to acquire write lock")?;
240242
state_guard
@@ -256,19 +258,20 @@ pub(crate) fn update(name: &str) -> Result<ComponentUpdateResult> {
256258
}
257259

258260
/// daemon implementation of component adoption
259-
pub(crate) fn adopt_and_update(name: &str) -> Result<ContentMetadata> {
260-
let sysroot = openat::Dir::open("/")?;
261-
let mut state = SavedState::load_from_disk("/")?.unwrap_or_default();
261+
pub(crate) fn adopt_and_update(name: &str, rootcxt: &RootContext) -> Result<ContentMetadata> {
262+
let sysroot = &rootcxt.sysroot;
263+
let mut state = SavedState::load_from_disk(&rootcxt.path)?.unwrap_or_default();
262264
let component = component::new_from_name(name)?;
263265
if state.installed.contains_key(name) {
264266
anyhow::bail!("Component {} is already installed", name);
265267
};
266268

267269
ensure_writable_boot()?;
268270

269-
let Some(update) = component.query_update(&sysroot)? else {
271+
let Some(update) = component.query_update(sysroot)? else {
270272
anyhow::bail!("Component {} has no available update", name);
271273
};
274+
let sysroot = sysroot.try_clone()?;
272275
let mut state_guard =
273276
SavedState::acquire_write_lock(sysroot).context("Failed to acquire write lock")?;
274277

@@ -408,8 +411,34 @@ pub(crate) fn print_status(status: &Status) -> Result<()> {
408411
Ok(())
409412
}
410413

414+
pub struct RootContext {
415+
pub sysroot: openat::Dir,
416+
pub path: Utf8PathBuf,
417+
#[allow(dead_code)]
418+
pub devices: Vec<String>,
419+
}
420+
421+
impl RootContext {
422+
fn new(sysroot: openat::Dir, path: &str, devices: Vec<String>) -> Self {
423+
Self {
424+
sysroot,
425+
path: Utf8Path::new(path).into(),
426+
devices,
427+
}
428+
}
429+
}
430+
431+
/// Initialize parent devices to prepare the update
432+
fn prep_before_update() -> Result<RootContext> {
433+
let path = "/";
434+
let sysroot = openat::Dir::open(path).context("Opening root dir")?;
435+
let devices = crate::blockdev::get_devices(path).context("get parent devices")?;
436+
Ok(RootContext::new(sysroot, path, devices))
437+
}
438+
411439
pub(crate) fn client_run_update() -> Result<()> {
412440
crate::try_fail_point!("update");
441+
let rootcxt = prep_before_update()?;
413442
let status: Status = status()?;
414443
if status.components.is_empty() && status.adoptable.is_empty() {
415444
println!("No components installed.");
@@ -421,7 +450,7 @@ pub(crate) fn client_run_update() -> Result<()> {
421450
ComponentUpdatable::Upgradable => {}
422451
_ => continue,
423452
};
424-
match update(name)? {
453+
match update(name, &rootcxt)? {
425454
ComponentUpdateResult::AtLatestVersion => {
426455
// Shouldn't happen unless we raced with another client
427456
eprintln!(
@@ -449,7 +478,7 @@ pub(crate) fn client_run_update() -> Result<()> {
449478
}
450479
for (name, adoptable) in status.adoptable.iter() {
451480
if adoptable.confident {
452-
let r: ContentMetadata = adopt_and_update(name)?;
481+
let r: ContentMetadata = adopt_and_update(name, &rootcxt)?;
453482
println!("Adopted and updated: {}: {}", name, r.version);
454483
updated = true;
455484
} else {
@@ -463,12 +492,13 @@ pub(crate) fn client_run_update() -> Result<()> {
463492
}
464493

465494
pub(crate) fn client_run_adopt_and_update() -> Result<()> {
495+
let rootcxt = prep_before_update()?;
466496
let status: Status = status()?;
467497
if status.adoptable.is_empty() {
468498
println!("No components are adoptable.");
469499
} else {
470500
for (name, _) in status.adoptable.iter() {
471-
let r: ContentMetadata = adopt_and_update(name)?;
501+
let r: ContentMetadata = adopt_and_update(name, &rootcxt)?;
472502
println!("Adopted and updated: {}: {}", name, r.version);
473503
}
474504
}

0 commit comments

Comments
 (0)