Skip to content

Create sandboxes directly from snapshots#1459

Open
ludfjig wants to merge 7 commits into
hyperlight-dev:mainfrom
ludfjig:from_snapshot
Open

Create sandboxes directly from snapshots#1459
ludfjig wants to merge 7 commits into
hyperlight-dev:mainfrom
ludfjig:from_snapshot

Conversation

@ludfjig
Copy link
Copy Markdown
Contributor

@ludfjig ludfjig commented May 15, 2026

Builds a ready-to-use MultiUseSandbox directly from an Arc<Snapshot> without going through UninitializedSandbox + evolve(). Building block for OCI-backed snapshot loading on a follow-up branch.

Adds:

  • HostFunctions newtype around the internal FunctionRegistry. default() pre-registers HostPrint, empty() starts empty.
  • MultiUseSandbox::from_snapshot(snap, host_funcs, cfg). Snapshot is the source of truth for layout. cfg is honored for non-layout fields (timeouts, debug info, interrupt retry delay).
  • Snapshot records host function metadata. from_snapshot rejects registries missing functions or with mismatched signatures. Pre-init snapshots record nothing and accept any registry, matching the UninitializedSandbox contract.
  • gdb support extended to sandboxes built via from_snapshot.

Recommend to review commit-by-commit

@ludfjig ludfjig added the kind/enhancement For PRs adding features, improving functionality, docs, tests, etc. label May 15, 2026
@ludfjig ludfjig marked this pull request as ready for review May 15, 2026 07:10
@danbugs danbugs requested a review from Copilot May 15, 2026 16:26
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds the ability to construct a MultiUseSandbox directly from an Arc<Snapshot>, bypassing UninitializedSandbox + evolve(). Snapshots now record the host functions registered at capture time, and the new constructor validates that the provided host-function set is a superset of those required. The gdb entry-point breakpoint mechanism is reworked into a one-shot tracked on the VM so it works for both Initialise and Call snapshots.

Changes:

  • New HostFunctions newtype (with default() pre-registering HostPrint and new() empty) and MultiUseSandbox::from_snapshot(snap, host_funcs, cfg).
  • Snapshot now carries HostFunctionDetails and exposes validate_host_functions to reject missing/mismatched signatures; pre-init snapshots accept any registry.
  • Gdb support: replaces VcpuStopReason::EntryPointBp with a one_shot_entry_bp field cleared by the run loop; entry breakpoint installed for both Initialise and Call entries; new gdb e2e test for snapshot path.

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
src/hyperlight_host/src/sandbox/initialized_multi_use.rs Implements from_snapshot, layout-override warning, snapshot host-function plumbing, and tests.
src/hyperlight_host/src/sandbox/snapshot/mod.rs Adds host_functions field and validate_host_functions; updates constructors and tests.
src/hyperlight_host/src/sandbox/host_funcs.rs Adds HostFunctions newtype and with_default_host_print; changes register_host_function to infallible; tweaks From impl.
src/hyperlight_host/src/sandbox/uninitialized.rs Uses with_default_host_print and removes redundant register_print call in new.
src/hyperlight_host/src/func/host_functions.rs Adapts Registerable impls to infallible registry call; adds HostFunctions impl.
src/hyperlight_host/src/mem/mgr.rs Plumbs HostFunctionDetails into snapshot(); inherits snapshot_count in from_snapshot.
src/hyperlight_host/src/mem/layout.rs Widens visibility of several layout fields and MAX_MEMORY_SIZE.
src/hyperlight_host/src/lib.rs Re-exports HostFunctions.
src/hyperlight_host/src/hypervisor/hyperlight_vm/x86_64.rs Sets up one-shot entry breakpoint covering Initialise and Call.
src/hyperlight_host/src/hypervisor/hyperlight_vm/mod.rs Adds one_shot_entry_bp field and run-loop logic to clear it on first hit.
src/hyperlight_host/src/hypervisor/gdb/mod.rs Removes VcpuStopReason::EntryPointBp variant.
src/hyperlight_host/src/hypervisor/gdb/event_loop.rs Drops handling for the removed variant.
src/hyperlight_host/src/hypervisor/gdb/arch.rs vcpu_stop_reason no longer takes/uses the entrypoint, becomes side-effect-free classifier.
src/hyperlight_host/examples/guest-debugging/main.rs Extracts gdb test helpers and adds test_gdb_from_snapshot.

Comment thread src/hyperlight_host/src/sandbox/initialized_multi_use.rs
Comment thread src/hyperlight_host/src/sandbox/initialized_multi_use.rs
Comment thread src/hyperlight_host/src/mem/layout.rs
Comment thread src/hyperlight_host/src/sandbox/host_funcs.rs
Comment thread src/hyperlight_host/src/sandbox/snapshot/mod.rs
Comment thread src/hyperlight_host/examples/guest-debugging/main.rs
Comment thread src/hyperlight_host/src/sandbox/initialized_multi_use.rs
ludfjig added 7 commits May 19, 2026 09:56
Signed-off-by: Ludvig Liljenberg <4257730+ludfjig@users.noreply.github.com>
Signed-off-by: Ludvig Liljenberg <4257730+ludfjig@users.noreply.github.com>
Signed-off-by: Ludvig Liljenberg <4257730+ludfjig@users.noreply.github.com>
Signed-off-by: Ludvig Liljenberg <4257730+ludfjig@users.noreply.github.com>
Signed-off-by: Ludvig Liljenberg <4257730+ludfjig@users.noreply.github.com>
Signed-off-by: Ludvig Liljenberg <4257730+ludfjig@users.noreply.github.com>
Signed-off-by: Ludvig Liljenberg <4257730+ludfjig@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

@jsturtevant jsturtevant left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, I've left a few comments and one missing testing that needs a fix


// Validate that the provided host functions are a superset of
// those required by the snapshot.
snapshot.validate_host_functions(&host_funcs)?;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume the snapshot manager does other validation? Should this validation live with that validation? if not are we missing validation? Can a maliciously crafted snapshot bypass any assumptions we have about the memory layout?

.expect_err("signature mismatch on `Add` must be rejected");
let msg = format!("{}", err);
assert!(msg.contains("Add"), "got: {}", msg);
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we are missing a test that catches the case: snapshot, register a new host function, snapshot again

A test that demonstrates this is missing and fails:

 let mut sbox = make_sandbox();
let _ = sbox.snapshot().unwrap();

sbox.register_host_function("Echo42", || Ok(42i64)).unwrap();

let snap = sbox.snapshot().unwrap();
let err = MultiUseSandbox::from_snapshot(snap, HostFunctions::default(), None)
    .expect_err("late-registered `Echo42` must be required by the new snapshot");
let msg = format!("{}", err);
assert!(msg.contains("Echo42"), "got: {}", msg);

/// disagrees with `snapshot`. Used by [`MultiUseSandbox::from_snapshot`]
/// to surface ignored caller-supplied layout values, since those
/// fields are always taken from the snapshot.
fn warn_on_layout_override(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what's the consequences of lay override?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kind/enhancement For PRs adding features, improving functionality, docs, tests, etc.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants