Skip to content

Restore snapshots with another scratch size - #162

Merged
danbugs merged 3 commits into
mainfrom
scratch-resize
Oct 30, 2026
Merged

danbugs merged 3 commits into
mainfrom
scratch-resize

Conversation

@danbugs

@danbugs danbugs commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Adds AppSandbox::snapshot_with_scratch_mb, which takes a snapshot that restores with less or more scratch than the guest booted with. hyperlight has not released scratch resize (#1947) yet, so this pins hyperlight-host and hyperlight-common to hyperlight main by rev, which keeps hyperlight-unikraft off crates.io until a hyperlight release replaces the pin.

  • Kernel: bumped to plat-hyperlight-v2 9f414729. It stops allocating at the host's reserved pages and the transport arena, and aborts cleanly when scratch runs out in a copy-on-write fault or an early x86 page fault. It runs from a resized restored scratch, and works on hyperlight 0.18.0 too.
  • snapshot_with_scratch_mb goes through hyperlight's SnapshotOptions::scratch_size and records the target size in the snapshot's metadata. SNAPSHOT_CONTRACT is 8, so snapshots saved by v0.20.1 and earlier are refused. tests/resize.rs covers shrinking, growth and the record, and also runs in the arm64 job.
  • Restore plus guest function call at 8 MiB, measured on the v0.18 base: python on MSHV 32.6 → 1.07 ms, node 66.2 → 1.62 ms; on WHP 11.6 → 3.80 ms.

Copilot AI balanced review requested due to automatic review settings October 16, 2026 23:32
@danbugs danbugs added the ci/arm64 Run the arm64 guest tests (self-hosted KVM and HVF runners) label Oct 16, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔵 Needs a closer look

Snapshot memory-layout changes depend on unmerged host and kernel work and require final human validation.

No open issues 🎉

What changed in this PR

Adds smaller-scratch snapshots so guests can boot with ample memory and restore with less, reducing restore costs.

Changes:

  • Adds snapshot_with_scratch_mb and documents sizing and recovery behavior.
  • Tests resized snapshots, persistence, and failure recovery.
  • Updates snapshot compatibility and temporarily pins unmerged host and kernel dependencies.
File Description
tests/​resize.rs Tests resizing, persistence, limits, and recovery.
src/​lib.rs Adds the resized-snapshot API and saturating size conversion.
docs/​execution.md Documents smaller-scratch restores.
CHANGELOG.md Records the API and compatibility changes.
Cargo.toml Pins experimental Hyperlight dependencies.
Cargo.lock Locks the pinned Hyperlight revision.
build.rs Bumps the snapshot contract to 6.
.gitmodules Selects the scratch-resize kernel fork.
.github/​workflows/​arm64.yml Includes resize tests in arm64 CI.

Review effort: Balanced

@danbugs danbugs changed the title [do not merge] Restore snapshots with less scratch [do not merge] Restore snapshots with another scratch size Oct 29, 2026
Pin hyperlight-host and hyperlight-common to hyperlight main at
a4563dbd, which has scratch resize (#1947), here and in the crates that
build hyperlight-unikraft from this tree (integrations/clickhouse,
demos/pptx-gen). crates.io takes no git dependency, so
hyperlight-unikraft is not published until a hyperlight release
replaces the pin.

hyperlight main builds bindgen 0.73, which needs syn 3.0.9 or later
and prettyplease 0.3.

Signed-off-by: danbugs <danilochiarlone@gmail.com>
Bump the kernel (plat-hyperlight-v2 0d9edd33 -> 9f414729), and
rebuild the kernels and the native-kernel fixture:

- The allocator stopped two pages below the top of scratch, but
  Hyperlight reserves twelve there, and the early fault handlers had no
  limit.  Allocation stops at the reserved pages, or at the transport
  arena when the host places it below them.
- A guest that ran out of scratch inside a copy-on-write fault crashed
  again reporting it and triple-faulted the VM.  It aborts.
- On x86, an unhandled early page fault halted the guest, which the
  host takes as a normal end.  It aborts.
- The scratch base follows the scratch size, so the kernel runs from a
  snapshot restored with another scratch size.

The kernel runs on hyperlight 0.18.0 as well as on hyperlight main.

Signed-off-by: danbugs <danilochiarlone@gmail.com>
Booting needs room to unpack the rootfs; guest function calls need far
less, or sometimes more.  snapshot_with_scratch_mb takes a snapshot that
a sandbox restores with `mb` MiB of scratch, through hyperlight's
SnapshotOptions::scratch_size, so every restore of a warm image costs
less, or guest function calls get more room than the boot had.  The
snapshot records `mb` as its guest's size, so snapshot_scratch_mb and a
restore go by the size it restores with.  It errors on a size above the
maximum memory size or too small for the transport and page tables; a
size too small for the kernel fails the restore, and a restore of a
snapshot that fits recovers the sandbox.

The host's scratch layout changed (the transport arena sits at a fixed
address below the top of scratch), so SNAPSHOT_CONTRACT goes to 8 and
older snapshots are refused.  tests/resize.rs covers shrinking and
growing, the record, the error paths and guest function calls that
outgrow a snapshot; the arm64 job runs it too.

Signed-off-by: danbugs <danilochiarlone@gmail.com>
@danbugs danbugs changed the title [do not merge] Restore snapshots with another scratch size Restore snapshots with another scratch size Oct 30, 2026
@danbugs
danbugs merged commit e65f866 into main Oct 30, 2026
81 checks passed
@danbugs
danbugs deleted the scratch-resize branch October 30, 2026 00:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci/arm64 Run the arm64 guest tests (self-hosted KVM and HVF runners)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants