diff --git a/crates/initramfs/src/lib.rs b/crates/initramfs/src/lib.rs index 802ac6409..2f7ae275e 100644 --- a/crates/initramfs/src/lib.rs +++ b/crates/initramfs/src/lib.rs @@ -179,7 +179,9 @@ fn overlay_state(base: impl AsFd, state: impl AsFd, source: &str) -> Result<()> mount_at_wrapper(fs, base, ".").context("Moving mount") } -fn overlay_transient(base: impl AsFd) -> Result<()> { +/// Mounts a transient overlayfs with passed in fd as the lowerdir +#[context("Mounting transient overlayfs")] +pub fn overlay_transient(base: impl AsFd) -> Result<()> { overlay_state(base, prepare_mount(mount_tmpfs()?)?, "transient") } diff --git a/crates/lib/src/bootc_composefs/state.rs b/crates/lib/src/bootc_composefs/state.rs index ac12ed541..7ff10c048 100644 --- a/crates/lib/src/bootc_composefs/state.rs +++ b/crates/lib/src/bootc_composefs/state.rs @@ -2,10 +2,13 @@ use std::os::unix::fs::symlink; use std::{fs::create_dir_all, process::Command}; use anyhow::{Context, Result}; +use bootc_initramfs_setup::overlay_transient; use bootc_kernel_cmdline::utf8::Cmdline; use bootc_mount::tempmount::TempMount; use bootc_utils::CommandRunExt; use camino::Utf8PathBuf; +use cap_std_ext::cap_std::ambient_authority; +use cap_std_ext::cap_std::fs::Dir; use cap_std_ext::{cap_std, dirext::CapStdExtDirExt}; use composefs::fsverity::{FsVerityHashValue, Sha256HashValue}; use fn_error_context::context; @@ -163,3 +166,25 @@ pub(crate) fn write_composefs_state( Ok(()) } + +pub(crate) fn composefs_usr_overlay() -> Result<()> { + let usr = Dir::open_ambient_dir("/usr", ambient_authority()).context("Opening /usr")?; + let is_usr_mounted = usr + .is_mountpoint(".") + .context("Failed to get mount details for /usr")?; + + let is_usr_mounted = + is_usr_mounted.ok_or_else(|| anyhow::anyhow!("Falied to get mountinfo"))?; + + if is_usr_mounted { + println!("A writeable overlayfs is already mounted on /usr"); + return Ok(()); + } + + overlay_transient(usr)?; + + println!("A writeable overlayfs is now mounted on /usr"); + println!("All changes there will be discarded on reboot."); + + Ok(()) +} diff --git a/crates/lib/src/cli.rs b/crates/lib/src/cli.rs index b6706d36a..3412a6b03 100644 --- a/crates/lib/src/cli.rs +++ b/crates/lib/src/cli.rs @@ -33,6 +33,7 @@ use serde::{Deserialize, Serialize}; use crate::bootc_composefs::{ finalize::{composefs_native_finalize, get_etc_diff}, rollback::composefs_rollback, + state::composefs_usr_overlay, status::composefs_booted, switch::switch_composefs, update::upgrade_composefs, @@ -1289,7 +1290,17 @@ async fn run_from_opt(opt: Opt) -> Result<()> { Ok(()) } Opt::Edit(opts) => edit(opts).await, - Opt::UsrOverlay => usroverlay().await, + Opt::UsrOverlay => { + #[cfg(feature = "composefs-backend")] + if composefs_booted()?.is_some() { + composefs_usr_overlay() + } else { + usroverlay().await + } + + #[cfg(not(feature = "composefs-backend"))] + usroverlay().await + } Opt::Container(opts) => match opts { ContainerOpts::Lint { rootfs,