Repository navigation
nvx-rs: prove cross-image platform restore with pre-ready activation RPC #542
Description
Parent: #535. Phase 5 (functional snapshot before the region). Depends on the runnable cold profile #541, #548's reviewed opened-media guarantee, and an independent, reviewed single-image-slot OpenVMM change pinned to the current aggregate/file-child/network baseline, with matched nvx::host bind/query and nvx::guest media-discovery support. Exactly one image0 slot is declared for this profile; it is bind-once and never hotplugged. Open nanvix/openvmm#116 and NVX #406 are multi-slot prior art, not merge or source-pin prerequisites. Current public OpenVMM has no image slot; the separate VMM/guest capture work here also enables tiered blockless RAM and scratch-only fresh-ext4 templates without adopting the older #406 gitlink. Time/restore helpers from the #358 guest-port series must also be source-matched.
Goal
Demonstrate a working image-independent platform snapshot restored with a different image through an authenticated pre-ready activation RPC, before building a replaceable VMM configuration region or requiring changing filesystem/network policy. This first milestone deliberately uses zero host mappings and no network; it is not acceptance of a policy-independent template.
Operations
- Single-slot VMM/guest contract: a template declares one permanently identifiable, initially empty read-only virtio-blk
image0with versioned MMIO/IRQ/status and immutable sector geometry, matched to the guest kernel shared-status table (image0may reuse0xd0008000/ status offset0x20; another placement requires a kernel change in the same pin), but zero media capacity at capture. Binding sets capacity from the verified image; image size is not a template-key invariant. There are noimage1-image3placeholders or prefix negotiation. An authenticated host-control endpoint binds one approved media file once, checks the actual opened handle through OpenVMM prerequisite: verify and receipt opened host attachments #548, returns/query-verifies its identity and capacity across host reconnect, accepts only an identical safe retry and rejects a different image or slot index. The VMM raises a device-originated virtio config change on bind. The guest waits for the bound capacity/config change, validates the selected role and rereads GPT partitions before root assembly/Ready. No device is hotplugged. Version the VMM manifest, guest discovery and template key together; an old four-declared-slot template is incompatible and requires recapture. Direct-image cold boots do not acquire an empty slot. - Capture once per immutable compatibility key (runtime/guest/VMM version, hypervisor, CPU and memory geometry, one declared
image0identity and single-slot ABI, upper mode and scratch role/capacity/geometry, activation schema). These are strictly pre-image, pre-overlay, pre-exec platform-tier templates, not snapshots of running workloads. Extend the VMM tier/manifest/CLI guards and the guest capture helper for a blockless RAM-upper template with no dummy scratch; the distinct ext4-scratch template cold-plugs only an unmounted scratch role (no bound lower image) and uses the tier's fresh-scratch policy. The current VMM also rejects this scratch-only block layout; extend its capture preflight and tier manifest contract without weakening old/workload snapshot checks. Capture before binding image media, mounting an image/overlay, starting an exec or recording tenant policy. Do not capture an active application-control session or tenant bytes. Publish each template once under a per-key lock to protected immutable storage, verify its sealed receipt/opened identity without a full memory-file rehash on each restore, and quarantine invalid cache entries. - Restore OpenVMM with fresh authenticated endpoints and the sole pre-existing empty
image0slot; bind one approved read-only image via authenticated host control after VMM launch, without hotplug, a second image slot or rebind. Query the bound identity after host reconnect. For the ext4 template attach fresh empty scratch in its captured slot on every restore; no capture-time or prior-restore scratch bytes may survive. For the RAM template attach no scratch. Verify the actual VMM-opened media/attachment receipt, VMM PID/identity, selected image and the class-specific snapshot key. On guest resume, recheck generation, time and entropy, discover image-slot media/capacity and re-read its partition table if necessary before root assembly. Before mounting a fresh restored scratch device, discard its capture-time cached blocks (e.g.,BLKFLSBUF) and validate the newly selected filesystem superblock; do not mix cached data from the capture disk with the replacement. Share these guest setup helpers rather than duplicating them in each application adapter. - Bring up restricted authenticated guest control before root and guest-network setup. Accept one bounded/versioned
Activate(generation, config-id, image, mapping_count=0, no-network); allow matching retry only when safe, reject divergent retry/replayed generation, and fail closed on partial side effects, timeout or reset. Exec is forbidden before Ready; Ready echoes the accepted identity after the image and fresh root are usable. - Both cold and restore use the same semantic activation/Ready contract, even if this phase initially transports it by RPC. A requested restore never silently cold-boots on a failed import/activation. This profile does not weaken the old public NVXC v1 mapping/boot grammar.
Acceptance
- A real hypervisor runs each tenant-free template (blockless RAM upper and fresh ext4 scratch upper) with two different read-only images of different capacities, proves new image content and no overlay/scratch state leak, and reports the same immutable template identity within each upper class, not across classes. No dummy scratch or extra image slot is added to the RAM template; its dormant filesystem slot is a separate captured invariant, not evidence of a no-device cold launch. No dummy lower image is bound for the scratch-only template, and neither template declares unused image slots.
- VMM and matched-guest tests prove no-slot cold boot, one empty
image0at capture, bind-once/read-only enforcement, idempotent same-identity bind/query after reconnect, rejection of a different identity or second slot, replacement of an authorized file before the VMM opens it, device-originated capacity notification/GPT rescan before Ready (including bind after the guest has begun waiting), matched guest-kernel shared-status/MMIO placement, and explicit rejection/recapture of old four-slot templates. No test relies on merging guest: add Ubuntu userland support #116 or Adopt bind-once microVM image slots #406. - Tests cover the VMM RAM-overlay, blockless-RAM and scratch-only capture/restore guards with the new pre-image contract, old snapshot-tier rejection, fresh-scratch reset with different first-block contents at capture and restore and no stale cached superblock, zero mappings, pre-Ready exec rejection, identical/divergent activation retry, interrupted image bind, reset/timeouts, teardown and explicit failure (not hidden fallback). A separate reviewed single-slot OpenVMM PR and matched NVX adapter are source-pinned on the current VMM baseline; tests bind and query only
image0and reject a second image slot. Version guest discovery for one declared slot; old four-slot development templates (including extra stable IDs and prior-art manifest fields 34/35) fail positively before vCPU resume and must be recaptured rather than reinterpreted; unrelated slot-free snapshots retain their existing manifest contract. guest: add Ubuntu userland support #116/Adopt bind-once microVM image slots #406 may guide the implementation but need not merge, and Adopt bind-once microVM image slots #406's older gitlink is never adopted. - Report capture and per-restore costs separately for each upper class. For the same source-bound image, runtime, VMM, CPU/memory geometry and workload, interleave cold and restore measurements while reporting expected device-topology differences (direct cold has no image/virtio-fs slot; the template has
image0and a dormant filesystem slot) and report p50/p95 with VMM start/state restore, image-slot bind, fresh-scratch attachment when applicable, time/entropy repair, root assembly, control attachment/activation and Ready broken out. Set a regression budget before acceptance; no success is inferred from a cold fallback or omitted activation step. - Results call this image-only RPC restore; filesystem/network policy changes await the separate OpenVMM prerequisites microvm: at a platform restore, attach an aggregate export to the dormant filesystem slot #540 and OpenVMM prerequisite: fixed NIC with pre-vCPU mutable policy on platform restore #536 and a later integration phase.
Activity
esaurez commentedon Oct 16, 2026
From the #550 review. A platform-tier restore currently runs repair through
nvx-snapshot, a shell script, around helper processes:nvx-time capture(steps 2 and 3);nvx-reseed,sha256sum,hostnameandnsenter(step 5);nvx-time restore-finish(step 6).On nested WHP that path measured 44 ms from packet selection until the caller resumed (#358).
nvx::guestlibrary calls that nvx-rs: factor minimal guest rootfs and descriptor-rooted host mapping #539 tracks (comment), instead ofnvx-snapshot. Validate the packet and step the clock, activate processors and memory when requested, reseed, and refresh the machine ID and hostname. Then acknowledge before thawing anything. The time daemon stays a separatenvx-timeprocess for step 7, and every failure stays fatal.nvx-reseed5.9 ms, identity 9.2 ms,restore-finish3.4 ms and shell exit 4.3 ms.esaurez commentedon Oct 24, 2026
Superseded by #833. The image-only restore with activation over RPC is #844, with #842 and #843, in stage 1 (#834). Image slots, receipts and an activation record in the restore packet are no longer part of the design.