diff --git a/src/spawner.rs b/src/spawner.rs index ad93a14..9359536 100644 --- a/src/spawner.rs +++ b/src/spawner.rs @@ -10,6 +10,7 @@ use std::ffi::CString; use std::fs::File; use std::io::Read; use std::os::unix::io::AsRawFd; +use std::path::PathBuf; use nix::unistd; @@ -29,10 +30,15 @@ impl<'a> Spawner<'a> { match &entrypoint.trigger { Trigger::Startup => { + let binary = PathBuf::from(self.binary).canonicalize()?; + + let mut builder = VoidBuilder::new(); + builder.mount(binary, "/entrypoint"); + let closure = || { let args = self.prepare_args(name, &entrypoint.args, None); - if let Err(e) = unistd::execv(&CString::new(self.binary).unwrap(), &args) + if let Err(e) = unistd::execv(&CString::new("/entrypoint").unwrap(), &args) .map_err(|e| Error::Nix { msg: "execv", src: e, @@ -45,14 +51,15 @@ impl<'a> Spawner<'a> { } }; - let mut builder = VoidBuilder::new(); builder.spawn(closure)?; } Trigger::Pipe(s) => { let pipe = self.pipes.get_mut(s).unwrap().take_read(); + let binary = PathBuf::from(self.binary).canonicalize()?; let mut builder = VoidBuilder::new(); + builder.mount(binary, "/entrypoint"); builder.keep_fd(&pipe); let closure = || match self.pipe_trigger(pipe, entrypoint, name) { @@ -87,7 +94,7 @@ impl<'a> Spawner<'a> { let pipe_trigger = std::str::from_utf8(&buf[0..read_bytes]).unwrap(); let args = self.prepare_args_ref(name, &spec.args, Some(pipe_trigger)); - if let Err(e) = unistd::execv(&CString::new(self.binary).unwrap(), &args) + if let Err(e) = unistd::execv(&CString::new("/entrypoint").unwrap(), &args) .map_err(|e| Error::Nix { msg: "execv", src: e, diff --git a/src/void.rs b/src/void.rs index f414b59..7e133f6 100644 --- a/src/void.rs +++ b/src/void.rs @@ -6,7 +6,7 @@ use crate::{Error, Result}; use std::collections::{HashMap, HashSet}; use std::fs; use std::os::unix::io::{AsRawFd, RawFd}; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use nix::mount::{mount, umount2, MntFlags, MsFlags}; use nix::sched::unshare; @@ -31,8 +31,8 @@ impl VoidBuilder { } #[allow(dead_code)] - pub fn mount(&mut self, src: PathBuf, dst: PathBuf) -> &mut Self { - self.mounts.insert(src, dst); + pub fn mount, T2: AsRef>(&mut self, src: T1, dst: T2) -> &mut Self { + self.mounts.insert(src.as_ref().into(), dst.as_ref().into()); self } @@ -144,10 +144,37 @@ impl VoidBuilder { // chdir after std::env::set_current_dir("/")?; - // TODO: mount requested mounts + // mount paths before unmounting old_root + for (src, dst) in &self.mounts { + let src = PathBuf::from("/old_root/").join(src.strip_prefix("/").unwrap_or(src)); + let dst = PathBuf::from("/").join(dst); + + debug!("mounting `{:?}` as `{:?}`", src, dst); + + // create the target + let src_data = fs::metadata(&src)?; + if src_data.is_dir() { + fs::create_dir_all(&dst)?; + } else { + fs::write(&dst, b"")?; + } + + // bind mount + mount( + Some(&src), + &dst, + Option::<&str>::None, + MsFlags::MS_BIND, + Option::<&str>::None, + ) + .map_err(|e| Error::Nix { + msg: "mount", + src: e, + })?; + } // unmount the old root - umount2("old_root/", MntFlags::MNT_DETACH).map_err(|e| Error::Nix { + umount2("/old_root/", MntFlags::MNT_DETACH).map_err(|e| Error::Nix { msg: "umount2", src: e, })?;