Skip to content

Commit

Permalink
Stop if /dev is not a bind mount with loopback
Browse files Browse the repository at this point in the history
At container start, /dev is snapshotted, so any new device files
don't get added unless /dev is bindmounted in. For now, check that
/dev is the same as the host's /dev via fsid. If they differ, it
means that /dev is not bindmounted.

Fixes #352

Signed-off-by: Brad P. Crochet <brad@redhat.com>
  • Loading branch information
bcrochet committed Apr 2, 2024
1 parent cc98447 commit 93c30e6
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 0 deletions.
3 changes: 3 additions & 0 deletions lib/src/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1177,6 +1177,9 @@ pub(crate) async fn install_to_disk(mut opts: InstallToDiskOpts) -> Result<()> {
block_opts.device
);
}
if !crate::mount::is_same_as_host(Utf8Path::new("/dev"))? {
anyhow::bail!("Add `-v /dev:/dev` to `podman` when using --via-loopback");
}
} else if !target_blockdev_meta.file_type().is_block_device() {
anyhow::bail!("Not a block device: {}", block_opts.device);
}
Expand Down
21 changes: 21 additions & 0 deletions lib/src/mount.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,24 @@ pub(crate) fn mount(dev: &str, target: &Utf8Path) -> Result<()> {
[dev, target.as_str()],
)
}

/// If the fsid of the passed path matches the fsid of the same path rooted
/// at /proc/1/root, it is assumed that these are indeed the same mounted
/// filesystem between container and host.
/// Path *should not* include a leading '/'. It will be stripped.
#[context("Comparing filesystems at {path} and /proc/1/root/{path}")]
pub(crate) fn is_same_as_host(path: &Utf8Path) -> Result<bool> {
let path = Utf8Path::new("/").join(path);

// Using statvfs instead of fs, since rustix will translate the fsid field
// for us.
let devstat = rustix::fs::statvfs(path.as_std_path())?;
let hostpath = Utf8Path::new("/proc/1/root").join(path.strip_prefix("/")?);
let hostdevstat = rustix::fs::statvfs(hostpath.as_std_path())?;
tracing::trace!(
"base mount id {:?}, host mount id {:?}",
devstat.f_fsid,
hostdevstat.f_fsid
);
Ok(devstat.f_fsid == hostdevstat.f_fsid)
}

0 comments on commit 93c30e6

Please sign in to comment.