diff --git a/backend/src/bin/embassy-init.rs b/backend/src/bin/embassy-init.rs index c7dfac7cc..840de505a 100644 --- a/backend/src/bin/embassy-init.rs +++ b/backend/src/bin/embassy-init.rs @@ -76,10 +76,11 @@ async fn setup_or_init(cfg_path: Option<&str>) -> Result<(), Error> { .with_kind(embassy::ErrorKind::Network)?; } else { let cfg = RpcContextConfig::load(cfg_path).await?; - embassy::disk::main::import( - tokio::fs::read_to_string("/embassy-os/disk.guid") // unique identifier for volume group - keeps track of the disk that goes with your embassy - .await? - .trim(), + let guid_string = tokio::fs::read_to_string("/embassy-os/disk.guid") // unique identifier for volume group - keeps track of the disk that goes with your embassy + .await?; + let guid = guid_string.trim(); + let reboot = embassy::disk::main::import( + guid, cfg.datadir(), if tokio::fs::metadata(REPAIR_DISK_PATH).await.is_ok() { RepairStrategy::Aggressive @@ -94,6 +95,12 @@ async fn setup_or_init(cfg_path: Option<&str>) -> Result<(), Error> { .await .with_ctx(|_| (embassy::ErrorKind::Filesystem, REPAIR_DISK_PATH))?; } + if reboot.0 { + embassy::disk::main::export(guid, cfg.datadir()).await?; + Command::new("reboot") + .invoke(embassy::ErrorKind::Unknown) + .await?; + } tracing::info!("Loaded Disk"); embassy::init::init(&cfg, &get_product_key().await?).await?; } diff --git a/backend/src/disk/fsck.rs b/backend/src/disk/fsck.rs index 024adcb3a..0e2f8e0a5 100644 --- a/backend/src/disk/fsck.rs +++ b/backend/src/disk/fsck.rs @@ -2,12 +2,15 @@ use std::ffi::OsStr; use std::path::Path; use color_eyre::eyre::eyre; +use futures::future::BoxFuture; +use futures::FutureExt; use tokio::process::Command; use tracing::instrument; use crate::{Error, ResultExt}; #[derive(Debug, Clone, Copy)] +#[must_use] pub struct RequiresReboot(pub bool); impl std::ops::BitOrAssign for RequiresReboot { fn bitor_assign(&mut self, rhs: Self) { @@ -39,21 +42,38 @@ pub async fn e2fsck_preen( e2fsck_runner(Command::new("e2fsck").arg("-p"), logicalname).await } +fn backup_existing_undo_file<'a>(path: &'a Path) -> BoxFuture<'a, Result<(), Error>> { + async move { + if tokio::fs::metadata(path).await.is_ok() { + let bak = path.with_extension(format!( + "{}.bak", + path.extension() + .and_then(|s| s.to_str()) + .unwrap_or_default() + )); + backup_existing_undo_file(&bak).await?; + tokio::fs::rename(path, &bak).await?; + } + Ok(()) + } + .boxed() +} + #[instrument] pub async fn e2fsck_aggressive( logicalname: impl AsRef + std::fmt::Debug, ) -> Result { + let undo_path = Path::new("/embassy-os") + .join( + logicalname + .as_ref() + .file_name() + .unwrap_or(OsStr::new("unknown")), + ) + .with_extension("e2undo"); + backup_existing_undo_file(&undo_path).await?; e2fsck_runner( - Command::new("e2fsck").arg("-y").arg("-z").arg( - Path::new("/embassy-os") - .join( - logicalname - .as_ref() - .file_name() - .unwrap_or(OsStr::new("unknown")), - ) - .with_extension("e2undo"), - ), + Command::new("e2fsck").arg("-y").arg("-z").arg(undo_path), logicalname, ) .await diff --git a/backend/src/disk/main.rs b/backend/src/disk/main.rs index 65fe18e02..694e12305 100644 --- a/backend/src/disk/main.rs +++ b/backend/src/disk/main.rs @@ -202,7 +202,7 @@ pub async fn import>( datadir: P, repair: RepairStrategy, password: &str, -) -> Result<(), Error> { +) -> Result { let scan = pvscan().await?; if scan .values() @@ -250,8 +250,7 @@ pub async fn import>( .arg(guid) .invoke(crate::ErrorKind::DiskManagement) .await?; - mount_all_fs(guid, datadir, repair, password).await?; - Ok(()) + mount_all_fs(guid, datadir, repair, password).await } #[instrument(skip(datadir, password))]