Skip to content

tests: check the runtime adapter's staged images and hand OpenVMM the checked files - #867

Merged
Pedro Henrique Penna (ppenna) merged 1 commit into
devfrom
esaurez/822-pr02-checked-handoff-20261023
Oct 25, 2026
Merged

Pedro Henrique Penna (ppenna) merged 1 commit into
devfrom
esaurez/822-pr02-checked-handoff-20261023

Conversation

@esaurez

@esaurez Enrique Saurez (esaurez) commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

Rebased onto dev after #863 merged. This PR now contains only the checked-handoff commit and preserves the separate staged module and launch record format 1.

Part of #822: PR 2 of 11, the checked handoff.

What changed

  • A layered runtime-adapter-host launch checks the bindings that the sandbox's store stages for its image and scratch image before it spawns anything. LayeredLaunch::prepare runs DistroBinding::check, under DISTRO_POLICY_REVISION, and ScratchBinding::check, which claims the scratch image for the sandbox and waits CLAIM_RELEASE_WAIT for a claim that should be free. Neither reads the images.
  • A binding that the store does not stage, or that no longer holds, fails the launch before it begins. No launch journal, VMM log, runtime record, or launch record is left. The host program adds "stage the images first" to those Unavailable errors. A claimed scratch image (TimedOut, ScratchClaimed) and host failures keep NVX's message.
  • prepare returns NVX's PreparedLaunch of the checked files. LayeredLaunch::openvmm_arguments takes it, and renders its arguments and kernel command line, which name the checked files: /proc/self/fd/N on Linux, and their final paths on Windows. The VmmCommand inherits PreparedLaunch::inherited() and nothing else. As in NVX's own sandbox start, the checks run before supervisor::launch.
  • The launch holds the checked files until the guest reports RootReady, or until a failed launch is torn down: the prepared launch is declared before the Starting, which drops first.
  • The launch record (format 1) holds the bindings that the launch checked: the image's, and the scratch image's, which is null over RAM.
  • Every scenario of vm_layered.rs and vm_restart.rs now stages, then launches. The restart scenarios boot NVX's Ubuntu EROFS image over a copy of the scratch template, and the fixtures move to tests/common.
  • Three new rows of vm_layered.rs check that unstaged images, a GPT disk changed in place after staging, and a replaced scratch image are each refused before spawn, with nothing of a launch left in the store. They also check that the same sandbox launches once its images are staged again.
  • layered_launch.rs checks:
    • the handoff's arguments and inherited handles, over a scratch image and over RAM;
    • refusals of unstaged images, another format or identity, a changed image, a replaced scratch image, and a missing image;
    • the scratch image's claim, which a second launch waits for, then fails to take, until the first one releases its checked files.
  • The README has a new section, "The checked handoff", and the module docs describe the checks and the hold.

API changes for stacked work

  • LayeredLaunch::prepare(&self) -> nvx::Result<PreparedLaunch> is new.
  • LayeredLaunch::openvmm_arguments(&self, prepared: &PreparedLaunch, hypervisor, kernel, initramfs, endpoint, report) -> Vec<OsString> now takes the prepared launch, and no longer fails.
  • tests/common gains Fixtures (moved from vm_layered.rs), SCRATCH_TEMPLATE, Sandbox::stderr and Sandbox::assert_unlaunched.

Validation

Rebased head: eb02d28ec4a792c22f0b28109077109fbffd440c, a single checked-handoff commit on origin/dev at 56c530e491438becc35124b346f2a070ed580868 (the latest dev verified immediately before the force-push). The already-merged #863 parent is no longer in this PR, and all conflict fixes are folded into the checked-handoff commit. The upstream staged module split and launch record format 1 are preserved.

  • Exact-head CI succeeded: 31 PR checks passed, 13 were intentionally skipped, and none failed or remain pending.
  • The runtime adapter's VM tests passed on Linux/KVM, Linux/MSHV, and Windows/WHP: vm_layered 25/25 and vm_restart 2/2 on each backend. These include the pre-spawn binding refusals and successful restaging, layered launch teardown, and orchestrator restart scenarios.
  • CI passed the runtime adapter's protocol-only and host-only configurations on Linux and Windows, plus its Linux musl guest-only configuration, including Clippy, builds, tests, and the minimum supported Rust version.
  • Local Windows checks passed with Rust 1.95.0: formatting, Clippy with -D warnings, builds and tests of protocol-only and host-only configurations; Rust 1.89 all-target checks of both; Markdown links; and whitespace checks. The focused launch/staging test run passed 11/11 tests.
  • nvx-rs coverage and Copilot Setup Steps succeeded.
  • The exact-head Copilot review reports no open issues, and there are no unresolved review threads. The repository's required team approval is still needed before merging.

An additional, non-CI strict rustdoc check (cargo doc --features host with RUSTDOCFLAGS=-D warnings) finds three pre-existing links to the guest-only Runner in the untouched src/exec.rs. No unrelated documentation changes were folded into this PR; the authoritative CI gates above are green.

Copilot AI left a comment

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.

🔵 Needs a closer look

Cross-platform file inheritance and teardown lifetimes warrant human review while KVM and full NVX CI validation remain pending.

No open issues 🎉

What changed in this PR

Implements the checked image handoff for the runtime adapter, building on staging in #863 toward the end-to-end sandbox work in #822.

Changes:

  • Checks staged image and scratch bindings before launch, rejecting missing or stale bindings before spawning OpenVMM.
  • Passes checked files through PreparedLaunch, retaining them until root readiness or failed-launch teardown.
  • Updates host-only and VM tests for staging, checked arguments, scratch claims, and pre-spawn refusals.
File Description
tests/​runtime-adapter/​tests/​vm_restart.rs Stages layered image fixtures before restart scenarios.
tests/​runtime-adapter/​tests/​vm_layered.rs Stages each scenario and tests pre-spawn refusals and recovery.
tests/​runtime-adapter/​tests/​layered_launch.rs Tests checked arguments, inherited handles, binding refusals, and scratch claims.
tests/​runtime-adapter/​tests/​common/​mod.rs Shares fixtures and adds diagnostic and unlaunched-state helpers.
tests/​runtime-adapter/​src/​lib.rs Updates module documentation for checked image handoff.
tests/​runtime-adapter/​src/​layered.rs Adds binding checks and renders arguments from PreparedLaunch.
tests/​runtime-adapter/​src/​bin/​runtime-adapter-host.rs Integrates preparation, handle inheritance, resource lifetimes, and staging diagnostics.
tests/​runtime-adapter/​README.md Documents the handoff contract and expanded test scenarios.

Review effort: Balanced

… checked files

A layered launch of runtime-adapter-host now checks the bindings that the
sandbox's store stages for its image and scratch image before it spawns
anything, with DistroBinding::check and ScratchBinding::check, which read
no content and claim the scratch image for the sandbox. A binding that the
store does not stage, or that no longer holds, fails the launch before it
begins.

LayeredLaunch::prepare returns NVX's PreparedLaunch of the checked files.
OpenVMM's arguments name those files rather than their paths, and the
VmmCommand inherits what PreparedLaunch::inherited names. The launch holds
the checked files until the guest has assembled the root, or until it has
torn down a launch that failed.

Every scenario of vm_layered.rs and vm_restart.rs now stages its images,
then launches them, and three scenarios check that unstaged images, an
image changed in place, and a replaced scratch image are refused before
spawn. The restart scenarios boot NVX's Ubuntu EROFS image over a copy of
the scratch template, whose fixtures move to tests/common.

Part of #822.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 95934b67-b8c3-419d-ab53-05fe1b79af13
@ppenna
Pedro Henrique Penna (ppenna) force-pushed the esaurez/822-pr02-checked-handoff-20261023 branch from 5476878 to eb02d28 Compare October 25, 2026 12:52
Copilot AI balanced review requested due to automatic review settings October 25, 2026 12:52

Copilot AI left a comment

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.

🔵 Needs a closer look

Cross-platform handle inheritance and teardown lifetimes warrant human review, with KVM and full CI validation still pending in the PR description.

No open issues 🎉

Review effort: Balanced

@ppenna

Copy link
Copy Markdown
Contributor

Rebased and force-pushed as eb02d28e, with all conflict fixes folded into the existing checked-handoff commit. The merged #863 parent is removed, and dev's separate staging module and record format 1 are retained.

Validation for the review's cross-platform handoff/teardown concern is now complete: exact-head CI is green, with 25 layered and 2 restart VM tests passing on each of KVM, MSHV, and WHP. Host tests also pass for the exact inherited-file allowlist, binding refusals, and scratch claim lifetime. PreparedLaunch remains declared before Starting, so failed-launch teardown ends the VM before dropping the checked files; the successful path releases them only after root readiness.

There are no unresolved review threads. The remaining merge requirement is the repository's team approval, not a failing or pending CI check. The PR description now records the current validation instead of the old stacked-PR pending status.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants