Skip to content

Commit e46daf7

Browse files
Allow mounting fds in TempMount
Allow mounting of any fds acquired using open_tree like syscalls Signed-off-by: Pragyan Poudyal <[email protected]>
1 parent 4a985e8 commit e46daf7

File tree

5 files changed

+53
-24
lines changed

5 files changed

+53
-24
lines changed

crates/etc-merge/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use composefs::fsverity::{FsVerityHashValue, Sha256HashValue, Sha512HashValue};
2121
use composefs::generic_tree::{Directory, Inode, Leaf, LeafContent, Stat};
2222
use composefs::tree::ImageError;
2323
use rustix::fs::{
24-
lgetxattr, llistxattr, lsetxattr, readlinkat, symlinkat, AtFlags, Gid, Uid, XattrFlags,
24+
AtFlags, Gid, Uid, XattrFlags, lgetxattr, llistxattr, lsetxattr, readlinkat, symlinkat,
2525
};
2626

2727
/// Metadata associated with a file, directory, or symlink entry.

crates/lib/src/bootc_composefs/finalize.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
#![allow(dead_code)]
2-
31
use std::path::Path;
42

53
use crate::bootc_composefs::boot::{get_esp_partition, get_sysroot_parent_dev, BootType};
@@ -9,13 +7,12 @@ use crate::{
97
bootc_composefs::status::composefs_deployment_status, composefs_consts::STATE_DIR_ABS,
108
};
119
use anyhow::{Context, Result};
12-
use bootc_initramfs_setup::{mount_at_wrapper, mount_composefs_image, open_dir};
10+
use bootc_initramfs_setup::{mount_composefs_image, open_dir};
1311
use bootc_mount::tempmount::TempMount;
1412
use cap_std_ext::cap_std::{ambient_authority, fs::Dir};
1513
use cap_std_ext::dirext::CapStdExtDirExt;
1614
use etc_merge::{compute_diff, merge, traverse_etc};
1715
use rustix::fs::{fsync, renameat, CWD};
18-
use rustix::mount::{unmount, UnmountFlags};
1916
use rustix::path::Arg;
2017

2118
use fn_error_context::context;
@@ -38,11 +35,11 @@ pub(crate) async fn composefs_native_finalize() -> Result<()> {
3835
let sysroot = open_dir(CWD, "/sysroot")?;
3936
let composefs_fd = mount_composefs_image(&sysroot, &booted_composefs.verity, false)?;
4037

41-
let tempdir = tempfile::tempdir().context("Creating tempdir")?;
42-
mount_at_wrapper(composefs_fd, CWD, tempdir.path())?;
38+
let erofs_tmp_mnt = TempMount::mount_fd(&composefs_fd)?;
4339

4440
// Perform the /etc merge
45-
let pristine_etc = Dir::open_ambient_dir(tempdir.path(), ambient_authority())?;
41+
let pristine_etc =
42+
Dir::open_ambient_dir(erofs_tmp_mnt.dir.path().join("etc"), ambient_authority())?;
4643
let current_etc = Dir::open_ambient_dir("/etc", ambient_authority())?;
4744

4845
let new_etc_path = Path::new(STATE_DIR_ABS)
@@ -57,7 +54,8 @@ pub(crate) async fn composefs_native_finalize() -> Result<()> {
5754
let diff = compute_diff(&pristine_files, &current_files)?;
5855
merge(&current_etc, &current_files, &new_etc, &new_files, diff)?;
5956

60-
unmount(tempdir.path(), UnmountFlags::DETACH).context("Unmounting tempdir")?;
57+
// Unmount EROFS
58+
drop(erofs_tmp_mnt);
6159

6260
let sysroot_parent = get_sysroot_parent_dev()?;
6361
// NOTE: Assumption here that ESP will always be present
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
pub(crate) mod boot;
2+
pub(crate) mod finalize;
23
pub(crate) mod repo;
34
pub(crate) mod rollback;
45
pub(crate) mod state;
56
pub(crate) mod status;
67
pub(crate) mod switch;
78
pub(crate) mod update;
8-
pub(crate) mod finalize;

crates/lib/src/bootc_composefs/state.rs

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use std::{fs::create_dir_all, process::Command};
33

44
use anyhow::{Context, Result};
55
use bootc_kernel_cmdline::Cmdline;
6+
use bootc_mount::tempmount::TempMount;
67
use bootc_utils::CommandRunExt;
78
use camino::Utf8PathBuf;
89
use cap_std_ext::{cap_std, dirext::CapStdExtDirExt};
@@ -11,8 +12,7 @@ use fn_error_context::context;
1112

1213
use ostree_ext::container::deploy::ORIGIN_CONTAINER;
1314
use rustix::{
14-
fs::{open, Mode, OFlags, CWD},
15-
mount::{unmount, UnmountFlags},
15+
fs::{open, Mode, OFlags},
1616
path::Arg,
1717
};
1818

@@ -71,22 +71,17 @@ pub(crate) fn copy_etc_to_state(
7171

7272
let composefs_fd = bootc_initramfs_setup::mount_composefs_image(&sysroot_fd, &erofs_id, false)?;
7373

74-
let tempdir = tempfile::tempdir().context("Creating tempdir")?;
75-
76-
bootc_initramfs_setup::mount_at_wrapper(composefs_fd, CWD, tempdir.path())?;
74+
let tempdir = TempMount::mount_fd(composefs_fd)?;
7775

7876
// TODO: Replace this with a function to cap_std_ext
7977
let cp_ret = Command::new("cp")
8078
.args([
8179
"-a",
82-
&format!("{}/etc/.", tempdir.path().as_str()?),
80+
&format!("{}/etc/.", tempdir.dir.path().as_str()?),
8381
&format!("{state_path}/etc/."),
8482
])
8583
.run_capture_stderr();
8684

87-
// Unmount regardless of copy succeeding
88-
unmount(tempdir.path(), UnmountFlags::DETACH).context("Unmounting composefs")?;
89-
9085
cp_ret
9186
}
9287

crates/mount/src/tempmount.rs

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1+
use std::os::fd::AsFd;
2+
13
use anyhow::{Context, Result};
24

35
use camino::Utf8Path;
46
use cap_std_ext::cap_std::{ambient_authority, fs::Dir};
57
use fn_error_context::context;
6-
use rustix::mount::{unmount, UnmountFlags};
8+
use rustix::mount::{move_mount, unmount, MoveMountFlags, UnmountFlags};
79

810
pub struct TempMount {
911
pub dir: tempfile::TempDir,
@@ -21,12 +23,46 @@ impl TempMount {
2123

2224
crate::mount(dev, utf8path)?;
2325

24-
// There's a case here where if the following open fails, we won't unmount which should be
25-
// unlikely
2626
let fd = Dir::open_ambient_dir(tempdir.path(), ambient_authority())
27-
.with_context(|| format!("Opening {:?}", tempdir.path()))?;
27+
.with_context(|| format!("Opening {:?}", tempdir.path()));
28+
29+
let fd = match fd {
30+
Ok(fd) => fd,
31+
Err(e) => {
32+
unmount(tempdir.path(), UnmountFlags::DETACH)?;
33+
Err(e)?
34+
}
35+
};
36+
37+
Ok(Self { dir: tempdir, fd })
38+
}
39+
40+
/// Mount and fd acquired with `open_tree` like syscall
41+
#[context("Mounting fd")]
42+
pub fn mount_fd(mnt_fd: impl AsFd) -> Result<Self> {
43+
let tempdir = tempfile::TempDir::new()?;
44+
45+
move_mount(
46+
mnt_fd.as_fd(),
47+
"",
48+
rustix::fs::CWD,
49+
tempdir.path(),
50+
MoveMountFlags::MOVE_MOUNT_F_EMPTY_PATH,
51+
)
52+
.context("move_mount")?;
53+
54+
let fd = Dir::open_ambient_dir(tempdir.path(), ambient_authority())
55+
.with_context(|| format!("Opening {:?}", tempdir.path()));
56+
57+
let fd = match fd {
58+
Ok(fd) => fd,
59+
Err(e) => {
60+
unmount(tempdir.path(), UnmountFlags::DETACH)?;
61+
Err(e)?
62+
}
63+
};
2864

29-
Ok(TempMount { dir: tempdir, fd })
65+
Ok(Self { dir: tempdir, fd })
3066
}
3167
}
3268

0 commit comments

Comments
 (0)