Skip to main content

Sandbox

Struct Sandbox 

Source
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

Source

pub fn new(policy: &Policy) -> Result<Self, SandlockError>

Create a new sandbox in the Created state.

Source

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?;
Source

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.

Source

pub async fn run_interactive( policy: &Policy, cmd: &[&str], ) -> Result<RunResult, SandlockError>

Run a sandboxed process with inherited stdio (interactive mode).

Source

pub async fn dry_run( policy: &Policy, cmd: &[&str], ) -> Result<DryRunResult, SandlockError>

Dry-run: spawn, wait, collect filesystem changes, then abort. Returns the run result plus a list of changes that would have been committed. The workdir is left unchanged.

Source

pub async fn dry_run_interactive( policy: &Policy, cmd: &[&str], ) -> Result<DryRunResult, SandlockError>

Dry-run with inherited stdio (interactive mode).

Source

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?; }
Source

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?;
Source

pub async fn wait(&mut self) -> Result<RunResult, SandlockError>

Wait for the child process to exit.

Source

pub fn pause(&mut self) -> Result<(), SandlockError>

Send SIGSTOP to the child’s process group.

Source

pub fn resume(&mut self) -> Result<(), SandlockError>

Send SIGCONT to the child’s process group.

Source

pub fn kill(&mut self) -> Result<(), SandlockError>

Send SIGKILL to the child’s process group.

Source

pub fn pid(&self) -> Option<i32>

Return the child PID, if spawned.

Source

pub fn set_on_bind( &mut self, cb: impl Fn(&HashMap<u16, u16>) + Send + Sync + 'static, )

Set a callback invoked whenever a port bind is recorded.

Source

pub async fn port_mappings(&self) -> HashMap<u16, u16>

Return the current virtual-to-real port mappings.

Returns a snapshot of all ports where the real (host) port differs from the virtual port the sandbox requested. Empty if port_remap is disabled or no ports have been remapped.

Source

pub fn policy(&self) -> &Policy

Return a reference to the policy.

Source

pub async fn checkpoint(&self) -> Result<Checkpoint, SandlockError>

Capture a checkpoint of the running sandbox.

Trait Implementations§

Source§

impl Drop for Sandbox

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<'a, T, E> AsTaggedExplicit<'a, E> for T
where T: 'a,

Source§

fn explicit(self, class: Class, tag: u32) -> TaggedParser<'a, Explicit, Self, E>

Source§

impl<'a, T, E> AsTaggedImplicit<'a, E> for T
where T: 'a,

Source§

fn implicit( self, class: Class, constructed: bool, tag: u32, ) -> TaggedParser<'a, Implicit, Self, E>

Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<A, B, T> HttpServerConnExec<A, B> for T
where B: Body,