Repository navigation
nvx-rs: share the VMM supervisor and the sandbox store #620
Description
Parent: #535. Phase: A1, in parallel with A1-guest.
Goal. One store, one supervisor and the host role of a shared NVXS session beneath the CLI, host::instance and external orchestrators. Callers keep the configuration, launch planning, authorization, application framing and orchestration.
Today:
host::process,host::platformandhost::instanceare public. The layered CLI has a separate, private store and lifecycle (host::cli::sandbox).- Waits on a persisted process identity poll. Windows already waits on a launched child's handle.
- The CLI and
host::instanceuse different record formats and locks. - If the caller crashes between spawning the VMM and recording its PID, the VMM keeps running unrecorded.
- The public host session speaks only NVXC; it has no session that other application protocols can use.
Scope:
-
Store:
- a private directory per sandbox and one lock;
- a runtime record: the VMM's PID and start time, the host boot, the control endpoint, and the runtime identity: OpenVMM, kernel and initramfs identities plus the boot and control contract versions, taken from install or staging metadata, never by hashing at launch;
- the capability, endpoint, log, console and outcome paths, and the launch journal.
It uses one new versioned format. NVX is pre-release, so there are no readers for older formats. Configuration records belong to the caller.
-
Launch journal:
- a marker written before spawn;
- the VMM's identity, recorded right after spawn;
- an inherited claim on the VMM log, which proves that a launch with no endpoint yet has exited.
Recovery kills an interrupted launch only when its identity is verified.
-
Supervisor:
- Spawn and detach, with an explicit allowlist of descriptors (Linux) or handles (Windows) to pass. Everything else stays close-on-exec, and only the child clears the flag on the allowed ones.
- Event-driven exit waits: a pidfd on Linux and the process handle on Windows. Polling is only a fallback.
- Stop: one graceful callback with a bounded deadline. The caller may request a bounded forced step against a verified process identity, and the result marks a forced stop as forced.
- Reattach after an orchestrator restart within the same host boot, reporting live, exited, mismatched or indeterminate. A different runtime identity counts as mismatched. Records from an earlier boot count as exited.
- The supervisor takes transport callbacks; it doesn't own an NVXC session.
- An unverified process is never signaled.
-
NVXS session, host role: validated records, incremental parsing and the host's session state, with no NVXC dependency.
host::sessionbecomes the NVXC adapter over it. -
The CLI and
host::instancedelegate to the store, supervisor and session. The CLI'sstopkeeps today's behavior: it reports the timeout and doesn't escalate. -
Lifecycle lock and removal: the store owns the rules that keep its directory consistent across lifecycle transitions, so no orchestrator copies the CLI's.
- A typed declaration of the caller's files: the configuration record whose presence means "provisioned", and any other names of the caller's own. Each is a single file name that isn't one of the store's.
- A lock for provision, which re-creates a directory that a concurrent removal deleted, and a lock for an existing sandbox, which fails as not found once the sandbox has been removed. A release removes its own lock file from a directory left without a configuration record.
- Removal, valid only when no VMM of the sandbox can run. It removes the store's files and the caller's, refuses foreign entries, removes the lock file before the directory, and handles lingering lock files and a provision that races it.
- The VMM's outcome-report staging file, which a VMM killed while it publishes its report leaves behind, belongs to the store. The store removes it with the launch's runtime files once the VMM has verifiably exited.
Not in scope: orchestration, image management, application transports and product configuration. Reattach doesn't replay Start or MAPS, restore lost streams, or resolve images.
Acceptance:
- The CLI's golden scenarios and lifecycle tests pass. Switching from today's formats to the new store needs one stop of all sandboxes; earlier state directories are not migrated.
nvx-rs/tests/supervisor.rscovers:- the launch crash windows: before spawn, between spawn and identity, and before the endpoint;
- PID reuse and reattach to a process that isn't a child;
- unknown identity and forced termination;
- Windows handles and jobs.
- The host half of the test adapter starts a VM, reattaches after a simulated orchestrator restart, and stops it, using public APIs only and its own framing over the NVXS session.
- Store fixtures cover two orchestrator builds using the new store format: a matching runtime identity reattaches, and a different one reports mismatched (the host parts of C6 and C7).
- The NVXS session passes the existing record vectors, including partial reads and record boundaries, on Linux and Windows.
- The store's lock, release and removal pass the CLI's lifecycle-lock tests, and concurrent tests across threads and processes on Linux and Windows: transitions that wait through a removal, a provision that races it, lingering lock files, and foreign entries. A failed start publishes its outcome report, and a leaked staging file never blocks removal.
PR stack:
- H1, verified process references and event waits, in parallel with H2, the store, layout, lock, journal and runtime identity.
- H3, the supervisor with the spawn allowlist, needs both.
- H4: the NVXS session's host role, then CLI and instance delegation.
- H5: restart and test-adapter acceptance.
- H6: the store's lifecycle lock and removal, moved from the CLI, after H4.
Carries over: #538's event-driven waits, verified reattach and supervisor extraction.
Meta A: #535. Phases: A1-guest #619, A1-host #620, A3 #621, A4 #622, A5 #623. NVX's binaries and tools, and the final acceptance: #816.
Activity
nvx-rs: report process identities that cannot be checked as errors
nvx-rs: never take a hidden process for an exited one
nvx-rs: let ending a process that exited succeed on Linux
nvx-rs: keep the supervision fixtures readable in one test thread
nvx-rs: add verified process references with event-driven exit waits
nvx-rs: report process identities that cannot be checked as errors
nvx-rs: never take a hidden process for an exited one
nvx-rs: let ending a process that exited succeed on Linux
nvx-rs: keep the supervision fixtures readable in one test thread
nvx-rs: add verified process references with event-driven exit waits
nvx-rs: report process identities that cannot be checked as errors
nvx-rs: never take a hidden process for an exited one
nvx-rs: let ending a process that exited succeed on Linux
nvx-rs: keep the supervision fixtures readable in one test thread
esaurez commentedon Oct 23, 2026
H1–H6 merged.