use nix::mount::{self, MsFlags}; use common::error::*; use crate::{paths, util::fs}; fn prepare_dev(path: &str) -> Result<()> { fs::mkdir(path)?; mount::mount::<_, _, str, str>(Some(path), path, None, MsFlags::MS_BIND, None) .context("Failed to bind mount container /dev")?; for dir in ["pts", "shm"] { fs::mkdir(paths::join(&[path, dir]))?; } for (link, target) in [ ("fd", "/proc/self/fd"), ("stdin", "/proc/self/fd/0"), ("stdout", "/proc/self/fd/1"), ("stderr", "/proc/self/fd/2"), ("ptmx", "pts/ptmx"), ] { let path = paths::join(&[path, link]); std::os::unix::fs::symlink(target, &path) .with_context(|| format!("Failed to create link {}", path))?; } for dev in ["null", "zero", "full", "random", "urandom", "tty"] { let source = paths::join(&["/dev", dev]); let target = paths::join(&[path, dev]); fs::create(&target)?; mount::mount::(Some(&source), &target, None, MsFlags::MS_BIND, None) .with_context(|| format!("Failed to bind mount {}", source))?; } mount::mount::( None, path, None, MsFlags::MS_REMOUNT | MsFlags::MS_BIND | MsFlags::MS_RDONLY, None, ) .context("Failed to mount container /dev read-only")?; Ok(()) } pub fn init_runner() -> Result<()> { fs::mkdir(paths::LAYER_STATE_DIR)?; fs::mkdir(paths::OUTPUT_STATE_DIR)?; fs::ensure_removed(paths::TMP_DIR)?; fs::mkdir(paths::TMP_DIR)?; mount::mount::<_, _, str, str>( Some(paths::TMP_DIR), paths::TMP_DIR, None, MsFlags::MS_BIND, None, ) .context("Failed to bind mount build tmpdir")?; mount::mount::(None, paths::TMP_DIR, None, MsFlags::MS_PRIVATE, None) .context("Failed to set MS_PRIVATE for build tmpdir")?; prepare_dev(paths::DEV_DIR)?; Ok(()) }