Skip to content

nvx-rs: prove cross-image platform restore with pre-ready activation RPC #542

Closed as not planned

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 image0 with versioned MMIO/IRQ/status and immutable sector geometry, matched to the guest kernel shared-status table (image0 may reuse 0xd0008000 / status offset 0x20; 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 no image1-image3 placeholders 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 image0 identity 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 image0 slot; 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 image0 at 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 image0 and 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 image0 and 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

  1. esaurez commented on Oct 16, 2026

    @esaurez
    ContributorAuthor

    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);
    • sysfs writes (step 4);
    • nvx-reseed, sha256sum, hostname and nsenter (step 5);
    • nvx-time restore-finish (step 6).

    On nested WHP that path measured 44 ms from packet selection until the caller resumed (#358).

    • Run repair steps 2 to 6 in the image-backed PID 1 through the nvx::guest library calls that nvx-rs: factor minimal guest rootfs and descriptor-rooted host mapping #539 tracks (comment), instead of nvx-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 separate nvx-time process for step 7, and every failure stays fatal.
    • Report these stages in this issue's restore breakdown, next to the shell path's: packet and clock 17.6 ms, processor prefix 3.7 ms, nvx-reseed 5.9 ms, identity 9.2 ms, restore-finish 3.4 ms and shell exit 4.3 ms.
  2. esaurez commented on Oct 24, 2026

    @esaurez
    ContributorAuthor

    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.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions