Skip to content

Commit 218ff2f

Browse files
mount: Add TempMount mount struct
Add a TempMount struct which mounts a device/partition on a tempdir and automatically unmount on drop Signed-off-by: Pragyan Poudyal <[email protected]>
1 parent 00ca840 commit 218ff2f

File tree

4 files changed

+46
-0
lines changed

4 files changed

+46
-0
lines changed

Cargo.lock

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/mount/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ libc = { workspace = true }
2020
rustix = { workspace = true }
2121
serde = { workspace = true, features = ["derive"] }
2222
tracing = { workspace = true }
23+
tempfile = { workspace = true }
24+
cap-std-ext = { workspace = true }
2325

2426
[dev-dependencies]
2527
indoc = { workspace = true }

crates/mount/src/mount.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ use rustix::{
2222
};
2323
use serde::Deserialize;
2424

25+
pub mod tempmount;
26+
2527
/// Well known identifier for pid 1
2628
pub const PID1: Pid = const {
2729
match Pid::from_raw(1) {

crates/mount/src/tempmount.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
use anyhow::{Context, Result};
2+
3+
use camino::Utf8Path;
4+
use cap_std_ext::cap_std::{ambient_authority, fs::Dir};
5+
use fn_error_context::context;
6+
use rustix::mount::{unmount, UnmountFlags};
7+
8+
pub struct TempMount {
9+
pub dir: tempfile::TempDir,
10+
pub fd: Dir,
11+
}
12+
13+
impl TempMount {
14+
/// Mount device/partition on a tempdir which will be automatically unmounted on drop
15+
#[context("Mounting {dev}")]
16+
pub fn mount_dev(dev: &str) -> Result<Self> {
17+
let tempdir = tempfile::TempDir::new()?;
18+
19+
let utf8path = Utf8Path::from_path(tempdir.path())
20+
.ok_or(anyhow::anyhow!("Failed to convert path to UTF-8 Path"))?;
21+
22+
crate::mount(dev, utf8path)?;
23+
24+
// There's a case here where if the following open fails, we won't unmount which should be
25+
// unlikely
26+
let fd = Dir::open_ambient_dir(tempdir.path(), ambient_authority())
27+
.with_context(|| format!("Opening {:?}", tempdir.path()))?;
28+
29+
Ok(TempMount { dir: tempdir, fd })
30+
}
31+
}
32+
33+
impl Drop for TempMount {
34+
fn drop(&mut self) {
35+
match unmount(self.dir.path(), UnmountFlags::DETACH) {
36+
Ok(_) => {}
37+
Err(e) => tracing::warn!("Failed to unmount tempdir: {e:?}"),
38+
}
39+
}
40+
}

0 commit comments

Comments
 (0)