Skip to content

Commit 44eb304

Browse files
authored
Merge pull request #1288 from cgwalters/mount-crate
Split mount code into separate helper crate
2 parents 76b9e5e + 0b8fad6 commit 44eb304

File tree

9 files changed

+79
-45
lines changed

9 files changed

+79
-45
lines changed

Cargo.lock

+16
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ members = [
33
"cli",
44
"system-reinstall-bootc",
55
"lib",
6+
"mount",
67
"ostree-ext",
78
"utils",
89
"blockdev",

lib/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ anstyle = "1.0.6"
1818
anyhow = { workspace = true }
1919
bootc-utils = { path = "../utils" }
2020
bootc-blockdev = { path = "../blockdev" }
21+
bootc-mount = { path = "../mount" }
2122
bootc-tmpfiles = { path = "../tmpfiles" }
2223
bootc-sysusers = { path = "../sysusers" }
2324
camino = { workspace = true, features = ["serde1"] }

lib/src/bootloader.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use fn_error_context::context;
44

55
use crate::task::Task;
66
use bootc_blockdev::PartitionTable;
7+
use bootc_mount as mount;
78

89
/// The name of the mountpoint for efi (as a subdirectory of /boot, or at the toplevel)
910
pub(crate) const EFI_DIR: &str = "efi";
@@ -33,7 +34,7 @@ pub(crate) fn install_via_bootupd(
3334
#[context("Installing bootloader using zipl")]
3435
pub(crate) fn install_via_zipl(device: &PartitionTable, boot_uuid: &str) -> Result<()> {
3536
// Identify the target boot partition from UUID
36-
let fs = crate::mount::inspect_filesystem_by_uuid(boot_uuid)?;
37+
let fs = mount::inspect_filesystem_by_uuid(boot_uuid)?;
3738
let boot_dir = Utf8Path::new(&fs.target);
3839
let maj_min = fs.maj_min;
3940

lib/src/install.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,12 @@ use crate::boundimage::{BoundImage, ResolvedBoundImage};
5555
use crate::containerenv::ContainerExecutionInfo;
5656
use crate::deploy::{prepare_for_pull, pull_from_prepared, PreparedImportMeta, PreparedPullResult};
5757
use crate::lsm;
58-
use crate::mount::Filesystem;
5958
use crate::progress_jsonl::ProgressWriter;
6059
use crate::spec::ImageReference;
6160
use crate::store::Storage;
6261
use crate::task::Task;
6362
use crate::utils::sigpolicy_from_opt;
63+
use bootc_mount::Filesystem;
6464

6565
/// The toplevel boot directory
6666
const BOOT: &str = "boot";
@@ -1287,8 +1287,8 @@ async fn prepare_install(
12871287
tracing::debug!("Target image reference: {target_imgref}");
12881288

12891289
// A bit of basic global state setup
1290-
crate::mount::ensure_mirrored_host_mount("/dev")?;
1291-
crate::mount::ensure_mirrored_host_mount("/var/lib/containers")?;
1290+
bootc_mount::ensure_mirrored_host_mount("/dev")?;
1291+
bootc_mount::ensure_mirrored_host_mount("/var/lib/containers")?;
12921292
ensure_var()?;
12931293
setup_tmp_mounts()?;
12941294
// Allocate a temporary directory we can use in various places to avoid
@@ -1763,8 +1763,8 @@ pub(crate) async fn install_to_filesystem(
17631763
{
17641764
tracing::debug!("Mounting host / to {ALONGSIDE_ROOT_MOUNT}");
17651765
std::fs::create_dir(ALONGSIDE_ROOT_MOUNT)?;
1766-
crate::mount::bind_mount_from_pidns(
1767-
crate::mount::PID1,
1766+
bootc_mount::bind_mount_from_pidns(
1767+
bootc_mount::PID1,
17681768
"/".into(),
17691769
ALONGSIDE_ROOT_MOUNT.into(),
17701770
true,
@@ -1829,7 +1829,7 @@ pub(crate) async fn install_to_filesystem(
18291829
}
18301830

18311831
// Gather data about the root filesystem
1832-
let inspect = crate::mount::inspect_filesystem(&fsopts.root_path)?;
1832+
let inspect = bootc_mount::inspect_filesystem(&fsopts.root_path)?;
18331833

18341834
// We support overriding the mount specification for root (i.e. LABEL vs UUID versus
18351835
// raw paths).
@@ -1881,7 +1881,7 @@ pub(crate) async fn install_to_filesystem(
18811881
// Find the UUID of /boot because we need it for GRUB.
18821882
let boot_uuid = if boot_is_mount {
18831883
let boot_path = fsopts.root_path.join(BOOT);
1884-
let u = crate::mount::inspect_filesystem(&boot_path)
1884+
let u = bootc_mount::inspect_filesystem(&boot_path)
18851885
.context("Inspecting /{BOOT}")?
18861886
.uuid
18871887
.ok_or_else(|| anyhow!("No UUID found for /{BOOT}"))?;

lib/src/install/baseline.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,9 @@ use super::RootSetup;
2727
use super::State;
2828
use super::RUN_BOOTC;
2929
use super::RW_KARG;
30-
use crate::mount;
31-
#[cfg(feature = "install-to-disk")]
32-
use crate::mount::is_mounted_in_pid1_mountns;
3330
use crate::task::Task;
31+
#[cfg(feature = "install-to-disk")]
32+
use bootc_mount::is_mounted_in_pid1_mountns;
3433

3534
// This ensures we end up under 512 to be small-sized.
3635
pub(crate) const BOOTPN_SIZE_MB: u32 = 510;
@@ -421,15 +420,15 @@ pub(crate) fn install_create_rootfs(
421420
.chain(bootarg)
422421
.collect::<Vec<_>>();
423422

424-
mount::mount(&rootdev, &physical_root_path)?;
423+
bootc_mount::mount(&rootdev, &physical_root_path)?;
425424
let target_rootfs = Dir::open_ambient_dir(&physical_root_path, cap_std::ambient_authority())?;
426425
crate::lsm::ensure_dir_labeled(&target_rootfs, "", Some("/".into()), 0o755.into(), sepolicy)?;
427426
let physical_root = Dir::open_ambient_dir(&physical_root_path, cap_std::ambient_authority())?;
428427
let bootfs = physical_root_path.join("boot");
429428
// Create the underlying mount point directory, which should be labeled
430429
crate::lsm::ensure_dir_labeled(&target_rootfs, "boot", None, 0o755.into(), sepolicy)?;
431430
if let Some(bootdev) = bootdev {
432-
mount::mount(bootdev.node.as_str(), &bootfs)?;
431+
bootc_mount::mount(bootdev.node.as_str(), &bootfs)?;
433432
}
434433
// And we want to label the root mount of /boot
435434
crate::lsm::ensure_dir_labeled(&target_rootfs, "boot", None, 0o755.into(), sepolicy)?;

lib/src/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ mod bootloader;
3535
mod containerenv;
3636
mod install;
3737
mod kernel;
38-
pub(crate) mod mount;
3938

4039
#[cfg(feature = "rhsm")]
4140
mod rhsm;

mount/Cargo.toml

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
[package]
2+
description = "Internal mount code"
3+
# Should never be published to crates.io
4+
publish = false
5+
edition = "2021"
6+
license = "MIT OR Apache-2.0"
7+
name = "bootc-mount"
8+
repository = "https://github.com/containers/bootc"
9+
version = "0.0.0"
10+
11+
[dependencies]
12+
anyhow = { workspace = true }
13+
bootc-utils = { path = "../utils" }
14+
camino = { workspace = true, features = ["serde1"] }
15+
fn-error-context = { workspace = true }
16+
rustix = { workspace = true }
17+
libc = {workspace = true}
18+
serde = { workspace = true, features = ["derive"] }
19+
tracing = { workspace = true }
20+
21+
[dev-dependencies]
22+
indoc = "2.0.5"
23+
24+
[lib]
25+
path = "src/mount.rs"

lib/src/mount.rs renamed to mount/src/mount.rs

+23-31
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,8 @@ use rustix::{
2222
};
2323
use serde::Deserialize;
2424

25-
#[cfg(feature = "install-to-disk")]
26-
use crate::task::Task;
27-
2825
/// Well known identifier for pid 1
29-
pub(crate) const PID1: Pid = const {
26+
pub const PID1: Pid = const {
3027
match Pid::from_raw(1) {
3128
Some(v) => v,
3229
None => panic!("Expected to parse pid1"),
@@ -36,21 +33,21 @@ pub(crate) const PID1: Pid = const {
3633
#[derive(Deserialize, Debug)]
3734
#[serde(rename_all = "kebab-case")]
3835
#[allow(dead_code)]
39-
pub(crate) struct Filesystem {
36+
pub struct Filesystem {
4037
// Note if you add an entry to this list, you need to change the --output invocation below too
41-
pub(crate) source: String,
42-
pub(crate) target: String,
38+
pub source: String,
39+
pub target: String,
4340
#[serde(rename = "maj:min")]
44-
pub(crate) maj_min: String,
45-
pub(crate) fstype: String,
46-
pub(crate) options: String,
47-
pub(crate) uuid: Option<String>,
48-
pub(crate) children: Option<Vec<Filesystem>>,
41+
pub maj_min: String,
42+
pub fstype: String,
43+
pub options: String,
44+
pub uuid: Option<String>,
45+
pub children: Option<Vec<Filesystem>>,
4946
}
5047

5148
#[derive(Deserialize, Debug)]
52-
pub(crate) struct Findmnt {
53-
pub(crate) filesystems: Vec<Filesystem>,
49+
pub struct Findmnt {
50+
pub filesystems: Vec<Filesystem>,
5451
}
5552

5653
fn run_findmnt(args: &[&str], path: &str) -> Result<Findmnt> {
@@ -80,20 +77,19 @@ fn findmnt_filesystem(args: &[&str], path: &str) -> Result<Filesystem> {
8077
#[context("Inspecting filesystem {path}")]
8178
/// Inspect a target which must be a mountpoint root - it is an error
8279
/// if the target is not the mount root.
83-
pub(crate) fn inspect_filesystem(path: &Utf8Path) -> Result<Filesystem> {
80+
pub fn inspect_filesystem(path: &Utf8Path) -> Result<Filesystem> {
8481
findmnt_filesystem(&["--mountpoint"], path.as_str())
8582
}
8683

8784
#[context("Inspecting filesystem by UUID {uuid}")]
8885
/// Inspect a filesystem by partition UUID
89-
pub(crate) fn inspect_filesystem_by_uuid(uuid: &str) -> Result<Filesystem> {
86+
pub fn inspect_filesystem_by_uuid(uuid: &str) -> Result<Filesystem> {
9087
findmnt_filesystem(&["--source"], &(format!("UUID={uuid}")))
9188
}
9289

9390
// Check if a specified device contains an already mounted filesystem
9491
// in the root mount namespace
95-
#[cfg(feature = "install-to-disk")]
96-
pub(crate) fn is_mounted_in_pid1_mountns(path: &str) -> Result<bool> {
92+
pub fn is_mounted_in_pid1_mountns(path: &str) -> Result<bool> {
9793
let o = run_findmnt(&["-N"], "1")?;
9894

9995
let mounted = o.filesystems.iter().any(|fs| is_source_mounted(path, fs));
@@ -102,8 +98,7 @@ pub(crate) fn is_mounted_in_pid1_mountns(path: &str) -> Result<bool> {
10298
}
10399

104100
// Recursively check a given filesystem to see if it contains an already mounted source
105-
#[cfg(feature = "install-to-disk")]
106-
pub(crate) fn is_source_mounted(path: &str, mounted_fs: &Filesystem) -> bool {
101+
pub fn is_source_mounted(path: &str, mounted_fs: &Filesystem) -> bool {
107102
if mounted_fs.source.contains(path) {
108103
return true;
109104
}
@@ -120,21 +115,18 @@ pub(crate) fn is_source_mounted(path: &str, mounted_fs: &Filesystem) -> bool {
120115
}
121116

122117
/// Mount a device to the target path.
123-
#[cfg(feature = "install-to-disk")]
124-
pub(crate) fn mount(dev: &str, target: &Utf8Path) -> Result<()> {
125-
Task::new_and_run(
126-
format!("Mounting {target}"),
127-
"mount",
128-
[dev, target.as_str()],
129-
)
118+
pub fn mount(dev: &str, target: &Utf8Path) -> Result<()> {
119+
Command::new("mount")
120+
.args([dev, target.as_str()])
121+
.run_with_cmd_context()
130122
}
131123

132124
/// If the fsid of the passed path matches the fsid of the same path rooted
133125
/// at /proc/1/root, it is assumed that these are indeed the same mounted
134126
/// filesystem between container and host.
135127
/// Path should be absolute.
136128
#[context("Comparing filesystems at {path} and /proc/1/root/{path}")]
137-
pub(crate) fn is_same_as_host(path: &Utf8Path) -> Result<bool> {
129+
pub fn is_same_as_host(path: &Utf8Path) -> Result<bool> {
138130
// Add a leading '/' in case a relative path is passed
139131
let path = Utf8Path::new("/").join(path);
140132

@@ -155,7 +147,7 @@ pub(crate) fn is_same_as_host(path: &Utf8Path) -> Result<bool> {
155147
/// for a mount from that namespace.
156148
#[allow(unsafe_code)]
157149
#[context("Opening mount tree from pid")]
158-
pub(crate) fn open_tree_from_pidns(
150+
pub fn open_tree_from_pidns(
159151
pid: rustix::process::Pid,
160152
path: &Utf8Path,
161153
recursive: bool,
@@ -259,7 +251,7 @@ pub(crate) fn open_tree_from_pidns(
259251

260252
/// Create a bind mount from the mount namespace of the target pid
261253
/// into our mount namespace.
262-
pub(crate) fn bind_mount_from_pidns(
254+
pub fn bind_mount_from_pidns(
263255
pid: Pid,
264256
src: &Utf8Path,
265257
target: &Utf8Path,
@@ -279,7 +271,7 @@ pub(crate) fn bind_mount_from_pidns(
279271

280272
// If the target path is not already mirrored from the host (e.g. via -v /dev:/dev)
281273
// then recursively mount it.
282-
pub(crate) fn ensure_mirrored_host_mount(path: impl AsRef<Utf8Path>) -> Result<()> {
274+
pub fn ensure_mirrored_host_mount(path: impl AsRef<Utf8Path>) -> Result<()> {
283275
let path = path.as_ref();
284276
// If we didn't have this in our filesystem already (e.g. for /var/lib/containers)
285277
// then create it now.

0 commit comments

Comments
 (0)