diff --git a/lib/src/install.rs b/lib/src/install.rs index 5929e4cd..d591672b 100644 --- a/lib/src/install.rs +++ b/lib/src/install.rs @@ -1711,7 +1711,7 @@ pub(crate) async fn install_to_filesystem( tracing::debug!("Root filesystem: {root_path}"); - if let Some(false) = ostree_ext::mountutil::is_mountpoint(&rootfs_fd, ".")? { + if let Some(false) = rootfs_fd.is_mountpoint(".")? { anyhow::bail!("Not a mountpoint: {root_path}"); } rootfs_fd diff --git a/ostree-ext/src/commit.rs b/ostree-ext/src/commit.rs index babe9017..31571d1e 100644 --- a/ostree-ext/src/commit.rs +++ b/ostree-ext/src/commit.rs @@ -3,7 +3,6 @@ //! use crate::container_utils::require_ostree_container; -use crate::mountutil::is_mountpoint; use anyhow::Context; use anyhow::Result; use cap_std::fs::Dir; @@ -60,7 +59,7 @@ fn clean_subdir(root: &Dir, rootdev: u64) -> Result<()> { } // Also ignore bind mounts, if we have a new enough kernel with statx() // that will tell us. - if is_mountpoint(root, &path)?.unwrap_or_default() { + if root.is_mountpoint(&path)?.unwrap_or_default() { tracing::trace!("Skipping mount point {path:?}"); continue; } diff --git a/ostree-ext/src/lib.rs b/ostree-ext/src/lib.rs index b962c8d6..97ec80de 100644 --- a/ostree-ext/src/lib.rs +++ b/ostree-ext/src/lib.rs @@ -39,7 +39,6 @@ pub mod diff; pub mod ima; pub mod keyfileext; pub(crate) mod logging; -pub mod mountutil; pub mod ostree_prepareroot; pub mod refescape; #[doc(hidden)] diff --git a/ostree-ext/src/mountutil.rs b/ostree-ext/src/mountutil.rs deleted file mode 100644 index f73cbba2..00000000 --- a/ostree-ext/src/mountutil.rs +++ /dev/null @@ -1,60 +0,0 @@ -//! Helpers for interacting with mounts. - -use std::os::fd::AsFd; -use std::path::Path; - -use anyhow::Result; -use cap_std::fs::Dir; -use cap_std_ext::cap_std; - -// Fix musl support -#[cfg(target_env = "gnu")] -use libc::STATX_ATTR_MOUNT_ROOT; -#[cfg(target_env = "musl")] -const STATX_ATTR_MOUNT_ROOT: libc::c_int = 0x2000; - -fn is_mountpoint_impl_statx(root: &Dir, path: &Path) -> Result> { - // https://github.com/systemd/systemd/blob/8fbf0a214e2fe474655b17a4b663122943b55db0/src/basic/mountpoint-util.c#L176 - use rustix::fs::{AtFlags, StatxFlags}; - - // SAFETY(unwrap): We can infallibly convert an i32 into a u64. - let mountroot_flag: u64 = STATX_ATTR_MOUNT_ROOT.try_into().unwrap(); - match rustix::fs::statx( - root.as_fd(), - path, - AtFlags::NO_AUTOMOUNT | AtFlags::SYMLINK_NOFOLLOW, - StatxFlags::empty(), - ) { - Ok(r) => { - let present = (r.stx_attributes_mask & mountroot_flag) > 0; - Ok(present.then_some(r.stx_attributes & mountroot_flag > 0)) - } - Err(e) if e == rustix::io::Errno::NOSYS => Ok(None), - Err(e) => Err(e.into()), - } -} - -/// Try to (heuristically) determine if the provided path is a mount root. -pub fn is_mountpoint(root: &Dir, path: impl AsRef) -> Result> { - is_mountpoint_impl_statx(root, path.as_ref()) -} - -#[cfg(test)] -mod tests { - use super::*; - use cap_std_ext::cap_tempfile; - - #[test] - fn test_is_mountpoint() -> Result<()> { - let root = cap_std::fs::Dir::open_ambient_dir("/", cap_std::ambient_authority())?; - let supported = is_mountpoint(&root, Path::new("/")).unwrap(); - match supported { - Some(r) => assert!(r), - // If the host doesn't support statx, ignore this for now - None => return Ok(()), - } - let tmpdir = cap_tempfile::TempDir::new(cap_std::ambient_authority())?; - assert!(!is_mountpoint(&tmpdir, Path::new(".")).unwrap().unwrap()); - Ok(()) - } -}