diff --git a/Cargo.toml b/Cargo.toml index 1a7d2bf..57a3179 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,3 +30,6 @@ walkdir = "2" [workspace] exclude = ["cgroup_device_filter"] + +[profile.release] +debug = "line-tables-only" diff --git a/shell.nix b/shell.nix index da722b3..b372412 100644 --- a/shell.nix +++ b/shell.nix @@ -8,5 +8,8 @@ pkgs.mkShell { # For llvm-objdump llvmPackages.bintools + + # To aid testing + runc ]; } diff --git a/src/runc/container.rs b/src/runc/container.rs index 697a8b6..32b5838 100644 --- a/src/runc/container.rs +++ b/src/runc/container.rs @@ -113,7 +113,7 @@ impl Container { } pub async fn mknod(&self, node: &Path, (major, minor): (u32, u32)) -> Result<()> { - crate::util::namespace::MntNamespace::of_pid(self.pid)?.enter(|| { + crate::util::namespace::Namespace::of_pid(self.pid)?.enter(|| { if let Some(parent) = node.parent() { let _ = std::fs::create_dir_all(parent); } @@ -129,11 +129,11 @@ impl Container { rustix::fs::chown(node, Some(self.uid), Some(self.gid))?; } Ok(()) - })? + }) } pub async fn symlink(&self, source: &Path, link: &Path) -> Result<()> { - crate::util::namespace::MntNamespace::of_pid(self.pid)?.enter(|| { + crate::util::namespace::Namespace::of_pid(self.pid)?.enter(|| { if let Some(parent) = link.parent() { let _ = std::fs::create_dir_all(parent); } @@ -141,12 +141,13 @@ impl Container { std::os::unix::fs::symlink(source, link)?; // No need to chown symlink. Permission is determined by the target. Ok(()) - })? + }) } pub async fn rm(&self, node: &Path) -> Result<()> { - crate::util::namespace::MntNamespace::of_pid(self.pid)?.enter(|| { + crate::util::namespace::Namespace::of_pid(self.pid)?.enter(|| { let _ = std::fs::remove_file(node); + Ok(()) }) } diff --git a/src/util/namespace.rs b/src/util/namespace.rs index ab26164..de75d66 100644 --- a/src/util/namespace.rs +++ b/src/util/namespace.rs @@ -5,35 +5,34 @@ use anyhow::Result; use rustix::process::Pid; use rustix::thread::{LinkNameSpaceType, UnshareFlags}; -pub struct MntNamespace { - fd: File, +pub struct Namespace { + mnt_fd: File, } -impl MntNamespace { +impl Namespace { /// Open the mount namespace of a process. - pub fn of_pid(pid: Pid) -> Result { - let path = format!("/proc/{}/ns/mnt", pid.as_raw_nonzero()); - let fd = File::open(path)?; - Ok(MntNamespace { fd }) + pub fn of_pid(pid: Pid) -> Result { + let mnt_fd = File::open(format!("/proc/{}/ns/mnt", pid.as_raw_nonzero()))?; + Ok(Namespace { mnt_fd }) } /// Enter the mount namespace. - pub fn enter T + Send>(&self, f: F) -> Result { + pub fn enter Result<()> + Send>(&self, f: F) -> Result<()> { // To avoid messing with rest of the process, we do everything in a new thread. // Use scoped thread to avoid 'static bound (we need to access fd). std::thread::scope(|scope| { scope - .spawn(|| -> Result { + .spawn(|| -> Result<()> { // Unshare FS for this specific thread so we can switch to another namespace. // Not doing this will cause EINVAL when switching to namespaces. rustix::thread::unshare(UnshareFlags::FS)?; // Switch this particular thread to the container's mount namespace. rustix::thread::move_into_link_name_space( - self.fd.as_fd(), + self.mnt_fd.as_fd(), Some(LinkNameSpaceType::Mount), )?; - Ok(f()) + Ok(f()?) }) .join() .map_err(|_| anyhow::anyhow!("work thread panicked"))?