Skip to content
This repository has been archived by the owner on Nov 7, 2024. It is now read-only.

commit: Skip bind mounts too #540

Merged
merged 1 commit into from
Sep 18, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 28 additions & 1 deletion lib/src/commit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use camino::Utf8Path;
use cap_std::fs::Dir;
use cap_std_ext::cap_std;
use cap_std_ext::dirext::CapStdExtDirExt;
use io_lifetimes::AsFd;
use rustix::fs::MetadataExt;
use std::borrow::Cow;
use std::convert::TryInto;
Expand Down Expand Up @@ -101,16 +102,42 @@ fn remove_all_on_mount_recurse(root: &Dir, rootdev: u64, path: &Path) -> Result<
Ok(skipped)
}

/// Try to (heuristically) determine if the provided path is a mount root.
fn is_mountpoint(root: &Dir, path: &Path) -> bool {
// https://github.com/systemd/systemd/blob/8fbf0a214e2fe474655b17a4b663122943b55db0/src/basic/mountpoint-util.c#L176
use rustix::fs::{AtFlags, StatxFlags};

let attr_mount_root: u32 = libc::STATX_ATTR_MOUNT_ROOT.try_into().unwrap();
let flags: StatxFlags = StatxFlags::from_bits(attr_mount_root).unwrap();
if let Ok(meta) = rustix::fs::statx(
root.as_fd(),
path,
AtFlags::NO_AUTOMOUNT | AtFlags::SYMLINK_NOFOLLOW,
flags,
) {
(meta.stx_attributes & attr_mount_root as u64) > 0
} else {
return false;
}
}

fn clean_subdir(root: &Dir, rootdev: u64) -> Result<()> {
for entry in root.entries()? {
let entry = entry?;
let metadata = entry.metadata()?;
let dev = metadata.dev();
let path = PathBuf::from(entry.file_name());
// Ignore other filesystem mounts, e.g. podman injects /run/.containerenv
if dev != rootdev {
tracing::trace!("Skipping entry in foreign dev {path:?}");
continue;
}
// Also ignore bind mounts, if we have a new enough kernel with statx()
// that will tell us.
if is_mountpoint(root, &path) {
tracing::trace!("Skipping mount point {path:?}");
continue;
}
let path = PathBuf::from(entry.file_name());
if metadata.is_dir() {
remove_all_on_mount_recurse(root, rootdev, &path)?;
} else {
Expand Down
Loading