Repository navigation
nvx-rs: the template compatibility key, the template store and leases #839
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::hosthas no template store.nvx::host::storekeeps runtime records and the launch journal:LaunchJournalrecords 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), underFile::lock(store/mod.rs:520-550). LaunchId::generatedraws 16 random bytes (record.rs:30-57).
RuntimeIdentityholds 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) andSnapshotTimeContract(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 distrocapacity and block sizes; the scratch length and geometryDevices 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. -
CaptureClassholds 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::launchaccepts 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.
Activity
nvx-rs: carry the store generation as a nonzero publication ID
Integrate #887 with #840 PR 2 for #841 PR 3
nvx-rs: carry the store generation as a nonzero publication ID
nvx-rs: carry the store generation as a nonzero publication ID