a3s_box_runtime/rootfs/
mod.rs1mod builder;
11mod layout;
12pub(crate) mod overlay;
13mod provider;
14
15pub use builder::RootfsBuilder;
16pub use layout::{GuestLayout, GUEST_WORKDIR};
17pub use provider::{default_provider, CopyProvider, OverlayProvider, RootfsProvider};
18
19use std::path::Path;
20
21pub fn unmount_box_overlay(merged: &Path) {
29 for _ in 0..8 {
30 if !is_mountpoint(merged) {
31 break;
32 }
33 if overlay::overlay_unmount(merged).is_err() {
34 break;
35 }
36 }
37}
38
39#[cfg(target_os = "linux")]
41pub(crate) fn is_mountpoint(path: &Path) -> bool {
42 use std::os::unix::fs::MetadataExt;
43 match (std::fs::metadata(path), std::fs::metadata(path.join(".."))) {
44 (Ok(here), Ok(parent)) => here.dev() != parent.dev(),
45 _ => false,
46 }
47}
48
49#[cfg(not(target_os = "linux"))]
50pub(crate) fn is_mountpoint(_path: &Path) -> bool {
51 false
52}
53
54#[cfg(test)]
55mod tests {
56 use super::*;
57
58 #[test]
59 fn missing_path_is_not_mountpoint() {
60 let temp = tempfile::tempdir().unwrap();
61 let missing = temp.path().join("missing");
62
63 assert!(!is_mountpoint(&missing));
64 }
65
66 #[test]
67 fn unmount_overlay_noops_for_non_mountpoint() {
68 let temp = tempfile::tempdir().unwrap();
69 let merged = temp.path().join("merged");
70 std::fs::create_dir(&merged).unwrap();
71
72 unmount_box_overlay(&merged);
73
74 assert!(merged.exists());
75 }
76}