From a8c9d04b0c138942ee1da6a5f543f0cc388d28cf Mon Sep 17 00:00:00 2001 From: Terr Date: Tue, 2 Jan 2024 15:14:43 +0100 Subject: [PATCH] Add some more mounts that the OCI describes as required See https://github.com/opencontainers/runtime-spec/blob/main/config-linux.md#default-filesystems --- crates/libcarton/src/container.rs | 43 ++++++++++++++++++----- crates/libcarton/src/container_builder.rs | 5 ++- crates/libcarton/src/error.rs | 8 +++++ 3 files changed, 46 insertions(+), 10 deletions(-) diff --git a/crates/libcarton/src/container.rs b/crates/libcarton/src/container.rs index 146925a..1040d30 100644 --- a/crates/libcarton/src/container.rs +++ b/crates/libcarton/src/container.rs @@ -150,6 +150,16 @@ pub struct Mount { } impl Mount { + pub(crate) fn rootfs(source: PathBuf) -> Self { + Mount { + source: Some(source), + relative_target: "".into(), + fstype: None, + flags: mount::MsFlags::MS_BIND | mount::MsFlags::MS_PRIVATE, + data: None, + } + } + /// Defines a "bind" mount which can be used to share a directory from outside the container /// with the container. pub(crate) fn bind( @@ -169,22 +179,22 @@ impl Mount { /// When the container runs in a separate PID namespace it also needs a separate /proc mount that /// will contain only this PID namespace's processes. - pub(crate) fn procfs(relative_target: PathBuf) -> Self { + pub(crate) fn procfs() -> Self { Mount { source: None::, - relative_target, + relative_target: "proc".into(), fstype: Some("proc".into()), flags: mount::MsFlags::empty(), data: None, } } - pub(crate) fn rootfs(source: PathBuf) -> Self { + pub(crate) fn sysfs() -> Self { Mount { - source: Some(source), - relative_target: "".into(), - fstype: None, - flags: mount::MsFlags::MS_BIND | mount::MsFlags::MS_PRIVATE, + source: None::, + relative_target: "sys".into(), + fstype: Some("sysfs".into()), + flags: mount::MsFlags::empty(), data: None, } } @@ -199,18 +209,33 @@ impl Mount { } } + pub(crate) fn devpts() -> Self { + Mount { + source: None::, + relative_target: "dev/pts".into(), + fstype: Some("devpts".into()), + flags: mount::MsFlags::empty(), + data: None, + } + } + /// Returns the absolute path where the mount has been mounted pub(crate) fn mount(&self, rootfs_path: &Path) -> Result { let mount_path = rootfs_path.join(&self.relative_target); + if !mount_path.exists() { + info!("creating {}", mount_path.display()); + std::fs::create_dir_all(&mount_path)?; + } + info!( - "mount {} ({}) at {}", + "mounting {} ({}) at {}", &self .source .as_ref() .map_or("(no source)", |p| p.to_str().unwrap()), self.fstype.as_ref().map_or("bind mount", |f| f.as_str()), - &mount_path.display() + mount_path.display() ); mount::mount( diff --git a/crates/libcarton/src/container_builder.rs b/crates/libcarton/src/container_builder.rs index c7bb2ce..de06319 100644 --- a/crates/libcarton/src/container_builder.rs +++ b/crates/libcarton/src/container_builder.rs @@ -40,9 +40,12 @@ impl ContainerBuilder { /// Adds mounting configuration for some important mounts, in the correct order. pub fn add_default_mounts(mut self) -> Self { self.config.mounts.extend(vec![ - Mount::procfs("proc".into()), + Mount::procfs(), + Mount::sysfs(), Mount::tmpfs("tmp".into()), Mount::tmpfs("dev".into()), + Mount::devpts(), + Mount::tmpfs("dev/shm".into()), ]); self diff --git a/crates/libcarton/src/error.rs b/crates/libcarton/src/error.rs index e4fa64b..1547d06 100644 --- a/crates/libcarton/src/error.rs +++ b/crates/libcarton/src/error.rs @@ -16,6 +16,14 @@ pub enum CartonError { SysCallFailed(String), #[error("namespace error: {0}")] NamespaceError(String), + #[error("I/O error: {0}")] + IOError(String), +} + +impl From for CartonError { + fn from(error: std::io::Error) -> Self { + CartonError::IOError(format!("{}", error)) + } } impl From for CartonError {