Skip to content

nvx-rs: the template compatibility key, the template store and leases #839

Closed

Description

Parent: #834 (#833), step 1. Needs: nothing. Unblocks: #841, #844.

Goal. The host library's metadata and durability for templates, with no VM: a canonical compatibility key, a separate store of template generations with a versioned index, and durable leases that tie each clone to its generation.

Today (dev d04d9fb):

  • nvx::host has no template store. nvx::host::store keeps runtime records and the launch journal:
    • LaunchJournal records the launch identity, the endpoint, the runtime identity and the log claim before spawn, then the process reference (nvx-rs/src/host/store/record.rs:198-225).
    • Records are written to a temporary file, synced, then renamed (store/files.rs:130-152), under File::lock (store/mod.rs:520-550).
    • LaunchId::generate draws 16 random bytes (record.rs:30-57).
  • RuntimeIdentity holds the OpenVMM, kernel and initramfs identities, and the boot and control contract versions, with no guest build (store/identity.rs:168-239). The test adapter adds its guest build to its own runtime identity (tests/runtime-adapter/src/runtime.rs:31-58).
  • OpenVMM's SnapshotManifest (openvmm/openvmm_helpers/src/snapshot.rs:25-72) and SnapshotTimeContract (openvmm/openvmm_defs/src/time_abi.rs:22-63) describe a capture. No host code reads them.

Stacked PRs. Each PR builds on the one before it, and lands with its own tests.

PR 1 of 4: the compatibility key.

  • nvx::host::template::TemplateKey, a canonical, versioned projection of small metadata. It never comes from hashes of binaries, images, memory or saved state. The table is exhaustive:

    Part Contents
    Bundle and contracts The VMM, kernel and initramfs identities, and the guest's build identity, which the adapter supplies. The versions of the key encoding and of the boot, snapshot, device-state, time, restore-packet, control and activation contracts.
    CPU and time The backend; the CPU vendor, generation, profile revision and effective CPUID; the topology; the time ABI version, the declared TSC and LAPIC rates, and the rate policy
    Resources CPU capacity and boot-online count; boot memory, memory capacity, block size and ranges
    Boot The exact effective command line, and its digest
    Disks The distro capacity and block sizes; the scratch length and geometry
    Devices and isolation Device IDs, MMIO, IRQs, features and queues; the filesystem slot and tag; NIC presence, and the fixed NIC's profile, MAC, addresses, prefixes and gateways; the network policy's identity, until nvx-rs: per-clone network policies on deny-all templates #850; invariant isolation and resource settings
  • A generation's own metadata stays out of the key, so the generations of one key differ in it: the capture time (created_at), the time contract's capture anchors, host and boot IDs and lineage counter, and the artifact sizes. The host keeps them for eligibility and restore checks.

  • CaptureClass holds the invariant inputs known before a capture. The full key is derived after publication.

  • The key's identity is a domain- and version-separated SHA-256 of its canonical bytes. A bundle change makes a new key; old templates aren't recertified.

  • TemplateManifest::read, a bounded reader of the capture's manifest and time contract.

  • Tests: canonical key vectors; each keyed change changes the key, and per-clone changes don't; unknown, truncated and oversized manifests, refused.

PR 2 of 4: the store.

  • nvx::host::template::Store, a separate logical store with its own identity and a versioned index, at a location that the adapter chooses.
  • Immutable generation payloads are kept apart from the mutable index, lease and tombstone records. Records use the existing temporary-file, sync and rename writes.
  • Its directories must be writable only by the orchestrator's account; links and reparse points are refused.
  • Four namespaces stay apart: the store generation (the host's publication ID), the bound-block storage generation, the time lineage counter, and the VM generation ID.
  • Tests, on Linux and Windows: creating, opening and reopening a store; index versions; unsafe ownership, links and reparse points, refused; the four namespaces kept apart.

PR 3 of 4: eligibility, leases, tombstones and retirement.

  • Eligibility, apart from compatibility: the time contract's restore window, with same-boot and reboot rules from the host's boot ID and clock. Generations outside it are excluded from selection and from create, and restoring one fails, with no capture or fallback.
  • One cross-process transaction checks eligibility and writes the lease, a durable clone-binding record beside the launch journal, before spawn. A lease lasts until the clone's verified exit (ProcessRef), through reattach, and never expires by timeout.
  • A tombstone quarantines a generation: it stops new acquisitions, and granted leases keep working. Retirement deletes a generation only after its leases drain.
  • Tests, with several processes, on Linux and Windows: acquisition, tombstones and retirement under concurrency; eligibility with clock fixtures, within one boot and across a reboot.

PR 4 of 4: the supervisor seam and the lock order.

  • supervisor::launch accepts a launch identity that the caller reserved (or an equivalent journaled preparation), so that the reservation and the clone binding are durable before a child exists.
  • One lock order: the template index, then the clone binding, the sandbox journal and the scratch claim, with one crash-consistent reservation and release protocol across them. No lock is held for a VM's lifetime.
  • Tests, on Linux and Windows: crashes at each reservation and release step, and around spawn; PID reuse, an earlier boot, an inaccessible process and a failed forced teardown, each with its own outcome.

Not in scope: capture and publication (#841); restore (#844); eviction policy, which the adapter owns.

Guide (#591's numbering): 1.5.2 (template compatibility), 1.5.3 (persisted state), 5.4.5 (the four identities), 5.5.6 (generations).

Done when: the four PRs are merged with their tests, on Linux and Windows.

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions