pub struct Sandbox { /* private fields */ }Expand description
The main user-facing sandbox API.
Orchestrates fork, confinement (Landlock + seccomp), and async notification-based supervision of the sandboxed child process.
Implementations§
Source§impl Sandbox
impl Sandbox
Sourcepub fn new(policy: &Policy) -> Result<Self, SandlockError>
pub fn new(policy: &Policy) -> Result<Self, SandlockError>
Create a new sandbox in the Created state.
Sourcepub fn new_with_fns(
policy: &Policy,
init_fn: impl FnOnce() + Send + 'static,
work_fn: impl Fn(u32) + Send + Sync + 'static,
) -> Result<Self, SandlockError>
pub fn new_with_fns( policy: &Policy, init_fn: impl FnOnce() + Send + 'static, work_fn: impl Fn(u32) + Send + Sync + 'static, ) -> Result<Self, SandlockError>
Create a sandbox with init and work functions for COW forking.
init_fn runs once in the child to load expensive state.
work_fn runs in each COW clone created by fork(N).
let mut sb = Sandbox::new_with_fns(&policy,
|| { load_model(); },
|clone_id| { rollout(clone_id); },
)?;
let clones = sb.fork(1000).await?;Sourcepub async fn run(
policy: &Policy,
cmd: &[&str],
) -> Result<RunResult, SandlockError>
pub async fn run( policy: &Policy, cmd: &[&str], ) -> Result<RunResult, SandlockError>
One-shot: spawn a sandboxed process, wait for it to exit, and return the result. Stdout and stderr are captured.
Sourcepub async fn run_interactive(
policy: &Policy,
cmd: &[&str],
) -> Result<RunResult, SandlockError>
pub async fn run_interactive( policy: &Policy, cmd: &[&str], ) -> Result<RunResult, SandlockError>
Run a sandboxed process with inherited stdio (interactive mode).
Sourcepub async fn fork(&mut self, n: u32) -> Result<Vec<Sandbox>, SandlockError>
pub async fn fork(&mut self, n: u32) -> Result<Vec<Sandbox>, SandlockError>
Create N COW clones of this sandbox.
Requires new_with_fns(). Forks a confined child, runs init_fn,
then forks N times using raw fork() (bypasses seccomp). Each
clone gets CLONE_ID=0..N-1 and runs work_fn(clone_id).
Memory pages from init_fn are shared copy-on-write across all
clones — 1000 clones of a 50MB process use ~50MB total.
Returns PIDs of all clones. Use waitpid to collect them.
Create N COW clones, each runs work_fn(clone_id).
Returns a Vec of Sandbox handles — one per clone. Each clone is a live process that can be waited on, killed, or paused.
let clones = sb.fork(4).await?;
for mut c in clones { c.wait().await?; }Sourcepub async fn reduce(
&self,
cmd: &[&str],
clones: &mut [Sandbox],
) -> Result<RunResult, SandlockError>
pub async fn reduce( &self, cmd: &[&str], clones: &mut [Sandbox], ) -> Result<RunResult, SandlockError>
Reduce: wait for all clones, then run a reducer command.
Waits for every clone to finish, then runs cmd in this sandbox.
The reducer can read clone results from shared files, tmpdir, etc.
let clones = mapper.fork(4).await?;
let result = reducer.reduce(&["python3", "sum.py"], &mut clones).await?;Sourcepub async fn wait(&mut self) -> Result<RunResult, SandlockError>
pub async fn wait(&mut self) -> Result<RunResult, SandlockError>
Wait for the child process to exit.
Sourcepub fn pause(&mut self) -> Result<(), SandlockError>
pub fn pause(&mut self) -> Result<(), SandlockError>
Send SIGSTOP to the child’s process group.
Sourcepub fn resume(&mut self) -> Result<(), SandlockError>
pub fn resume(&mut self) -> Result<(), SandlockError>
Send SIGCONT to the child’s process group.
Sourcepub fn kill(&mut self) -> Result<(), SandlockError>
pub fn kill(&mut self) -> Result<(), SandlockError>
Send SIGKILL to the child’s process group.
Sourcepub async fn checkpoint(&self) -> Result<Checkpoint, SandlockError>
pub async fn checkpoint(&self) -> Result<Checkpoint, SandlockError>
Capture a checkpoint of the running sandbox.