cellos-supervisor 0.5.1

CellOS execution-cell runner — boots cells in Firecracker microVMs or gVisor, enforces narrow typed authority, emits signed CloudEvents.
Documentation
//! Linux-only: private mount namespace setup for isolated cell runs (L2-03).
//!
//! Called in `pre_exec` after `unshare(CLONE_NEWNS)`. Sequence:
//! 1. Remount the entire tree `MS_PRIVATE | MS_REC` so no mounts leak to the host.
//! 2. Create `workspace_path` as a directory if absent (best-effort).
//! 3. Mount a fresh `tmpfs` over `workspace_path`.
//!
//! The child process gets a clean, empty writable workspace. On exit the entire
//! mount namespace is destroyed — no tmpfs residue on the host.
//!
//! This is called from the `pre_exec` hook (forked child, single-threaded) so
//! only async-signal-safe and re-entrant primitives are allowed.

use std::ffi::CString;
use std::io;

/// Make the host mount tree private and mount a fresh tmpfs over `workspace_path`.
///
/// # Errors
/// Returns the first `io::Error` encountered. Callers should treat this as fatal
/// for the cell run (return `Err` from `pre_exec`).
pub fn make_private_workspace(workspace_path: &str) -> io::Result<()> {
    // Step 1: prevent any mount/unmount operations inside this namespace from
    // propagating back to the parent namespace.
    let root = CString::new("/").expect("static");
    let none = CString::new("none").expect("static");
    // SAFETY: libc::mount with MS_PRIVATE | MS_REC on "/" — standard unshare pattern.
    let rc = unsafe {
        libc::mount(
            none.as_ptr(),
            root.as_ptr(),
            std::ptr::null(),
            libc::MS_PRIVATE | libc::MS_REC,
            std::ptr::null(),
        )
    };
    if rc != 0 {
        return Err(io::Error::last_os_error());
    }

    // Step 2: ensure the workspace directory exists.
    let ws =
        CString::new(workspace_path).map_err(|e| io::Error::new(io::ErrorKind::InvalidInput, e))?;
    // SAFETY: mkdir(2) is async-signal-safe; 0o755 is the conventional directory mode.
    let _ = unsafe { libc::mkdir(ws.as_ptr(), 0o755) }; // ignore EEXIST

    // Step 3: mount a fresh tmpfs.
    let tmpfs = CString::new("tmpfs").expect("static");
    let rc = unsafe {
        libc::mount(
            tmpfs.as_ptr(),
            ws.as_ptr(),
            tmpfs.as_ptr(),
            libc::MS_NODEV | libc::MS_NOSUID,
            std::ptr::null(),
        )
    };
    if rc != 0 {
        return Err(io::Error::last_os_error());
    }

    Ok(())
}