From 75065edeb2f6f449b81f1b23d0bf4a4dbc35ea57 Mon Sep 17 00:00:00 2001 From: Enrique Saurez Date: Sat, 7 Nov 2026 01:10:06 -0800 Subject: [PATCH 1/3] host: move snapshot metadata to its own names Own the key, manifest, codecs and time eligibility in host::snapshot while retaining the template re-exports for current users. Remove guest_build from the key and change its version 1 encoding and hash domain in place. Keep the existing opaque snapshot shell and capture and restore behavior. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 7f9c3ba3-e38b-427c-8ed6-da7a970c21a9 Copilot-Session: 0325d032-38a9-4c7f-9899-687a4ec93a51 --- nvx-rs/README.md | 23 +- nvx-rs/public-api/linux.txt | 114 +++++++- nvx-rs/public-api/windows.txt | 114 +++++++- nvx-rs/src/host/mod.rs | 1 + nvx-rs/src/host/snapshot.rs | 38 +++ .../host/{template => snapshot}/canonical.rs | 0 .../{template => snapshot}/canonical/tests.rs | 0 .../{template => snapshot}/eligibility.rs | 2 +- .../eligibility/tests.rs | 0 nvx-rs/src/host/{template => snapshot}/key.rs | 54 ++-- .../host/{template => snapshot}/key/tests.rs | 106 ++++--- .../host/{template => snapshot}/manifest.rs | 28 +- .../{template => snapshot}/manifest/tests.rs | 22 +- .../src/host/{template => snapshot}/tests.rs | 260 +++++++++--------- .../src/host/{template => snapshot}/wire.rs | 0 .../host/{template => snapshot}/wire/tests.rs | 0 nvx-rs/src/host/template/clone/tests.rs | 2 +- .../src/host/template/clone/tests/launch.rs | 2 +- nvx-rs/src/host/template/mod.rs | 39 +-- .../src/host/template/store/capture/tests.rs | 2 +- .../src/host/template/store/leases/tests.rs | 2 +- nvx-rs/src/host/template/store/tests.rs | 6 +- nvx-rs/tests/vectors/README.md | 16 +- nvx-rs/tests/vectors/snapshot-key-v1.txt | 100 +++++++ nvx-rs/tests/vectors/template-key-v1.txt | 99 ------- tests/runtime-adapter/tests/vm_template.rs | 7 +- 26 files changed, 664 insertions(+), 373 deletions(-) create mode 100644 nvx-rs/src/host/snapshot.rs rename nvx-rs/src/host/{template => snapshot}/canonical.rs (100%) rename nvx-rs/src/host/{template => snapshot}/canonical/tests.rs (100%) rename nvx-rs/src/host/{template => snapshot}/eligibility.rs (99%) rename nvx-rs/src/host/{template => snapshot}/eligibility/tests.rs (100%) rename nvx-rs/src/host/{template => snapshot}/key.rs (96%) rename nvx-rs/src/host/{template => snapshot}/key/tests.rs (92%) rename nvx-rs/src/host/{template => snapshot}/manifest.rs (98%) rename nvx-rs/src/host/{template => snapshot}/manifest/tests.rs (98%) rename nvx-rs/src/host/{template => snapshot}/tests.rs (81%) rename nvx-rs/src/host/{template => snapshot}/wire.rs (100%) rename nvx-rs/src/host/{template => snapshot}/wire/tests.rs (100%) create mode 100644 nvx-rs/tests/vectors/snapshot-key-v1.txt delete mode 100644 nvx-rs/tests/vectors/template-key-v1.txt diff --git a/nvx-rs/README.md b/nvx-rs/README.md index 0bbf4be63..0504efb95 100644 --- a/nvx-rs/README.md +++ b/nvx-rs/README.md @@ -124,6 +124,7 @@ changes only when the module's purpose does. | [`nvx::exec`](#nvxexec) | The execution engine: the streams, credit, and outcome of an execution's two sides, without I/O, for any framing | | [`nvx::host::runtime`](#nvxhostruntime) | `Runtime`: what every launch shares, the runtime's files and their identity, the hypervisor and its probe, and the launch options | | [`nvx::host::vm`](#nvxhostvm) | The directory of a VM, private to the current user, with the fixed names of the files and endpoints of its launches | +| [`nvx::host::snapshot`](#nvxhostsnapshot) | Snapshot compatibility keys, strict manifests, and restore-time eligibility | | [`nvx::host::config`](#nvxhostconfig) | `VmConfig`, a VM's configuration as one value, and `CaptureConfig`, what a capture adds and the identity of its snapshots, checked without reading the host | | [`nvx::host::restore`](#nvxhostrestore) | The restore-ready listener, with native ownership transfer for a caller's own I/O | | [`nvx::host::artifacts`](#nvxhostartifacts) | Locating the OpenVMM executable and the guest artifacts that a VM runs, and their runtime identity | @@ -136,7 +137,7 @@ changes only when the module's purpose does. | [`nvx::host::nvxs`](#nvxhostnvxs) | `HostConnection`: the host's role of the NVXS session over a platform transport | | [`nvx::host::process`](#nvxhostprocess) | Verified references to OpenVMM processes, through which callers wait for them and end them | | [`nvx::host::supervisor`](#nvxhostsupervisor) | The supervisor of a sandbox's VMM, beneath the CLI, `Instance`, and external orchestrators | -| [`nvx::host::template`](#nvxhosttemplate) | Templates, captures of a microVM from which clones are restored: their plans, manifests, keys, and store | +| [`nvx::host::template`](#nvxhosttemplate) | Legacy template capture and clone plans and store, with aliases of the snapshot metadata | | [`nvx::host::seal`](#nvxhostseal) | `FileSeal`: what the host reports about an open file from its metadata alone, without reading it | | [`nvx::host::session`, `platform`, `report`](#nvxhostsession-platform-report) | The authenticated control session, Linux and Windows primitives, and OpenVMM's outcome report | | [`nvx::host::sandbox`](#nvxhostsandbox) | The launch profile of `nvx-rs sandbox`: its plans, live shares, option checks, bindings, and prepared launches | @@ -466,6 +467,19 @@ credential that the host presents at a VM's control endpoint: `as_bytes` returns it, and its `Debug` form hides it. The library never writes it to a file; a caller that reconnects after a restart keeps it. +### `nvx::host::snapshot` + +`SnapshotKey` and `SnapshotManifest` own the compatibility key and strict +OpenVMM manifest reader. `SnapshotManifest::time` exposes the capture's +`TimeContract`, whose `eligibility` checks its restore window at a `HostTime`; +`HostTime::now` samples the host's clock and identities. The existing +`host::template` names remain aliases of these same types. + +The key's canonical encoding and identity use the snapshot names and omit +`guest_build`. Version 1 changes in place: no snapshot outlives a deployment, +and no reader or migration of the prior encoding is supported. `CaptureClass` +still records the legacy capture inputs, including its guest build. + ### `nvx::host::config` `VmConfig`: the configuration of a VM as one value, its processors, its memory @@ -849,8 +863,9 @@ top-level message. Neither silently changes the requested directory. ### `nvx::host::template` -The metadata of templates, captures of a microVM from which independent clones -are restored. +The legacy plans and store of templates, captures of a microVM from which +independent clones are restored. Their metadata names remain aliases of +[`host::snapshot`](#nvxhostsnapshot)'s types. `TemplatePlan::new` lowers an adapter's `SandboxPlan` into the plan of a template's capture, without I/O: the placeholder `distro`, which its @@ -902,7 +917,7 @@ domain-separated SHA-256 digest is its identity, a `KeyIdentity`, which converts to and from the `nvx::activation::Identity` by which a clone's lease and durable records name its template's key, or a `ClassIdentity`; the [conformance vectors](tests/vectors/README.md) of version 1, -`tests/vectors/template-key-v1.txt`, pin both encodings and identities. The +`tests/vectors/snapshot-key-v1.txt`, pin both encodings and identities. The key's encoding, version 1, leaves the network policy out, since templates capture their NIC under the complete deny-all policy, and has not been released, so a template store that an earlier build created is not supported: delete it diff --git a/nvx-rs/public-api/linux.txt b/nvx-rs/public-api/linux.txt index a8830709f..d3feb845b 100644 --- a/nvx-rs/public-api/linux.txt +++ b/nvx-rs/public-api/linux.txt @@ -2583,6 +2583,119 @@ field nvx::host::session::SessionError::Refused::0 variant nvx::host::session::SessionError::Reset variant nvx::host::session::SessionError::TimedOut fn nvx::host::session::connect +mod nvx::host::snapshot +struct nvx::host::snapshot::BlockGeometry +field nvx::host::snapshot::BlockGeometry::length +field nvx::host::snapshot::BlockGeometry::logical_block_size +field nvx::host::snapshot::BlockGeometry::physical_block_size +struct nvx::host::snapshot::CaptureClass +const nvx::host::snapshot::CaptureClass::VERSION +field nvx::host::snapshot::CaptureClass::boot_processors +method nvx::host::snapshot::CaptureClass::check +field nvx::host::snapshot::CaptureClass::cpu_profile +field nvx::host::snapshot::CaptureClass::distro +field nvx::host::snapshot::CaptureClass::guest_build +field nvx::host::snapshot::CaptureClass::hypervisor +method nvx::host::snapshot::CaptureClass::identity +field nvx::host::snapshot::CaptureClass::invariants +field nvx::host::snapshot::CaptureClass::memory +field nvx::host::snapshot::CaptureClass::memory_capacity +field nvx::host::snapshot::CaptureClass::network +field nvx::host::snapshot::CaptureClass::processors +field nvx::host::snapshot::CaptureClass::runtime +field nvx::host::snapshot::CaptureClass::scratch +method nvx::host::snapshot::CaptureClass::to_bytes +struct nvx::host::snapshot::ClassIdentity +method nvx::host::snapshot::ClassIdentity::as_bytes +method nvx::host::snapshot::ClassIdentity::from_bytes +struct nvx::host::snapshot::Downtime +field nvx::host::snapshot::Downtime::nanos +field nvx::host::snapshot::Downtime::source +field nvx::host::snapshot::Downtime::vm_time_nanos +enum nvx::host::snapshot::DowntimeSource +variant nvx::host::snapshot::DowntimeSource::HostMonotonic +variant nvx::host::snapshot::DowntimeSource::Utc +enum nvx::host::snapshot::Eligibility +variant nvx::host::snapshot::Eligibility::Early +field nvx::host::snapshot::Eligibility::Early::before_ns +field nvx::host::snapshot::Eligibility::Early::source +variant nvx::host::snapshot::Eligibility::Eligible +field nvx::host::snapshot::Eligibility::Eligible::0 +variant nvx::host::snapshot::Eligibility::Expired +field nvx::host::snapshot::Eligibility::Expired::0 +method nvx::host::snapshot::Eligibility::is_eligible +enum nvx::host::snapshot::HostClock +variant nvx::host::snapshot::HostClock::LinuxBoottime +variant nvx::host::snapshot::HostClock::WindowsInterruptTime +method nvx::host::snapshot::HostClock::as_str +struct nvx::host::snapshot::HostTime +field nvx::host::snapshot::HostTime::boot_id +field nvx::host::snapshot::HostTime::clock +field nvx::host::snapshot::HostTime::host_id +field nvx::host::snapshot::HostTime::monotonic_ns +method nvx::host::snapshot::HostTime::now +field nvx::host::snapshot::HostTime::utc_ns +struct nvx::host::snapshot::Invariants +const nvx::host::snapshot::Invariants::MAX_NAME_LEN +const nvx::host::snapshot::Invariants::MAX_SETTINGS +const nvx::host::snapshot::Invariants::MAX_VALUE_LEN +method nvx::host::snapshot::Invariants::get +method nvx::host::snapshot::Invariants::is_empty +method nvx::host::snapshot::Invariants::iter +method nvx::host::snapshot::Invariants::len +method nvx::host::snapshot::Invariants::new +method nvx::host::snapshot::Invariants::with +struct nvx::host::snapshot::KeyIdentity +method nvx::host::snapshot::KeyIdentity::as_bytes +method nvx::host::snapshot::KeyIdentity::from_bytes +const nvx::host::snapshot::MANIFEST_NAME +const nvx::host::snapshot::MAX_DOWNTIME_NS +const nvx::host::snapshot::MAX_MANIFEST_LEN +struct nvx::host::snapshot::SnapshotKey +const nvx::host::snapshot::SnapshotKey::MAX_LEN +const nvx::host::snapshot::SnapshotKey::VERSION +method nvx::host::snapshot::SnapshotKey::boot_processors +method nvx::host::snapshot::SnapshotKey::command_line +method nvx::host::snapshot::SnapshotKey::cpu_profile +method nvx::host::snapshot::SnapshotKey::distro +method nvx::host::snapshot::SnapshotKey::filesystem_tag +method nvx::host::snapshot::SnapshotKey::from_bytes +method nvx::host::snapshot::SnapshotKey::guest_network +method nvx::host::snapshot::SnapshotKey::has_network +method nvx::host::snapshot::SnapshotKey::hypervisor +method nvx::host::snapshot::SnapshotKey::identity +method nvx::host::snapshot::SnapshotKey::invariants +method nvx::host::snapshot::SnapshotKey::memory +method nvx::host::snapshot::SnapshotKey::memory_block_size +method nvx::host::snapshot::SnapshotKey::memory_capacity +method nvx::host::snapshot::SnapshotKey::new +method nvx::host::snapshot::SnapshotKey::processors +method nvx::host::snapshot::SnapshotKey::runtime +method nvx::host::snapshot::SnapshotKey::scratch +method nvx::host::snapshot::SnapshotKey::speaks_current_contracts +method nvx::host::snapshot::SnapshotKey::to_bytes +struct nvx::host::snapshot::SnapshotManifest +method nvx::host::snapshot::SnapshotManifest::created_at +method nvx::host::snapshot::SnapshotManifest::hypervisor +method nvx::host::snapshot::SnapshotManifest::memory_len +method nvx::host::snapshot::SnapshotManifest::openvmm_version +method nvx::host::snapshot::SnapshotManifest::parse +method nvx::host::snapshot::SnapshotManifest::read +method nvx::host::snapshot::SnapshotManifest::state_len +method nvx::host::snapshot::SnapshotManifest::time +struct nvx::host::snapshot::TimeContract +field nvx::host::snapshot::TimeContract::apic_frequency_hz +field nvx::host::snapshot::TimeContract::boot_id +field nvx::host::snapshot::TimeContract::capture_monotonic_ns +field nvx::host::snapshot::TimeContract::capture_tsc +field nvx::host::snapshot::TimeContract::capture_utc_ns +field nvx::host::snapshot::TimeContract::cut_to_anchor_ns +method nvx::host::snapshot::TimeContract::eligibility +field nvx::host::snapshot::TimeContract::host_clock +field nvx::host::snapshot::TimeContract::host_id +field nvx::host::snapshot::TimeContract::lineage +field nvx::host::snapshot::TimeContract::tsc_frequency_hz +field nvx::host::snapshot::TimeContract::tsc_tolerance_ppm mod nvx::host::store struct nvx::host::store::ArtifactIdentity method nvx::host::store::ArtifactIdentity::as_str @@ -3124,7 +3237,6 @@ method nvx::host::template::TemplateKey::cpu_profile method nvx::host::template::TemplateKey::distro method nvx::host::template::TemplateKey::filesystem_tag method nvx::host::template::TemplateKey::from_bytes -method nvx::host::template::TemplateKey::guest_build method nvx::host::template::TemplateKey::guest_network method nvx::host::template::TemplateKey::has_network method nvx::host::template::TemplateKey::hypervisor diff --git a/nvx-rs/public-api/windows.txt b/nvx-rs/public-api/windows.txt index ab8e7d184..42ba404b2 100644 --- a/nvx-rs/public-api/windows.txt +++ b/nvx-rs/public-api/windows.txt @@ -1506,6 +1506,119 @@ field nvx::host::session::SessionError::Refused::0 variant nvx::host::session::SessionError::Reset variant nvx::host::session::SessionError::TimedOut fn nvx::host::session::connect +mod nvx::host::snapshot +struct nvx::host::snapshot::BlockGeometry +field nvx::host::snapshot::BlockGeometry::length +field nvx::host::snapshot::BlockGeometry::logical_block_size +field nvx::host::snapshot::BlockGeometry::physical_block_size +struct nvx::host::snapshot::CaptureClass +const nvx::host::snapshot::CaptureClass::VERSION +field nvx::host::snapshot::CaptureClass::boot_processors +method nvx::host::snapshot::CaptureClass::check +field nvx::host::snapshot::CaptureClass::cpu_profile +field nvx::host::snapshot::CaptureClass::distro +field nvx::host::snapshot::CaptureClass::guest_build +field nvx::host::snapshot::CaptureClass::hypervisor +method nvx::host::snapshot::CaptureClass::identity +field nvx::host::snapshot::CaptureClass::invariants +field nvx::host::snapshot::CaptureClass::memory +field nvx::host::snapshot::CaptureClass::memory_capacity +field nvx::host::snapshot::CaptureClass::network +field nvx::host::snapshot::CaptureClass::processors +field nvx::host::snapshot::CaptureClass::runtime +field nvx::host::snapshot::CaptureClass::scratch +method nvx::host::snapshot::CaptureClass::to_bytes +struct nvx::host::snapshot::ClassIdentity +method nvx::host::snapshot::ClassIdentity::as_bytes +method nvx::host::snapshot::ClassIdentity::from_bytes +struct nvx::host::snapshot::Downtime +field nvx::host::snapshot::Downtime::nanos +field nvx::host::snapshot::Downtime::source +field nvx::host::snapshot::Downtime::vm_time_nanos +enum nvx::host::snapshot::DowntimeSource +variant nvx::host::snapshot::DowntimeSource::HostMonotonic +variant nvx::host::snapshot::DowntimeSource::Utc +enum nvx::host::snapshot::Eligibility +variant nvx::host::snapshot::Eligibility::Early +field nvx::host::snapshot::Eligibility::Early::before_ns +field nvx::host::snapshot::Eligibility::Early::source +variant nvx::host::snapshot::Eligibility::Eligible +field nvx::host::snapshot::Eligibility::Eligible::0 +variant nvx::host::snapshot::Eligibility::Expired +field nvx::host::snapshot::Eligibility::Expired::0 +method nvx::host::snapshot::Eligibility::is_eligible +enum nvx::host::snapshot::HostClock +variant nvx::host::snapshot::HostClock::LinuxBoottime +variant nvx::host::snapshot::HostClock::WindowsInterruptTime +method nvx::host::snapshot::HostClock::as_str +struct nvx::host::snapshot::HostTime +field nvx::host::snapshot::HostTime::boot_id +field nvx::host::snapshot::HostTime::clock +field nvx::host::snapshot::HostTime::host_id +field nvx::host::snapshot::HostTime::monotonic_ns +method nvx::host::snapshot::HostTime::now +field nvx::host::snapshot::HostTime::utc_ns +struct nvx::host::snapshot::Invariants +const nvx::host::snapshot::Invariants::MAX_NAME_LEN +const nvx::host::snapshot::Invariants::MAX_SETTINGS +const nvx::host::snapshot::Invariants::MAX_VALUE_LEN +method nvx::host::snapshot::Invariants::get +method nvx::host::snapshot::Invariants::is_empty +method nvx::host::snapshot::Invariants::iter +method nvx::host::snapshot::Invariants::len +method nvx::host::snapshot::Invariants::new +method nvx::host::snapshot::Invariants::with +struct nvx::host::snapshot::KeyIdentity +method nvx::host::snapshot::KeyIdentity::as_bytes +method nvx::host::snapshot::KeyIdentity::from_bytes +const nvx::host::snapshot::MANIFEST_NAME +const nvx::host::snapshot::MAX_DOWNTIME_NS +const nvx::host::snapshot::MAX_MANIFEST_LEN +struct nvx::host::snapshot::SnapshotKey +const nvx::host::snapshot::SnapshotKey::MAX_LEN +const nvx::host::snapshot::SnapshotKey::VERSION +method nvx::host::snapshot::SnapshotKey::boot_processors +method nvx::host::snapshot::SnapshotKey::command_line +method nvx::host::snapshot::SnapshotKey::cpu_profile +method nvx::host::snapshot::SnapshotKey::distro +method nvx::host::snapshot::SnapshotKey::filesystem_tag +method nvx::host::snapshot::SnapshotKey::from_bytes +method nvx::host::snapshot::SnapshotKey::guest_network +method nvx::host::snapshot::SnapshotKey::has_network +method nvx::host::snapshot::SnapshotKey::hypervisor +method nvx::host::snapshot::SnapshotKey::identity +method nvx::host::snapshot::SnapshotKey::invariants +method nvx::host::snapshot::SnapshotKey::memory +method nvx::host::snapshot::SnapshotKey::memory_block_size +method nvx::host::snapshot::SnapshotKey::memory_capacity +method nvx::host::snapshot::SnapshotKey::new +method nvx::host::snapshot::SnapshotKey::processors +method nvx::host::snapshot::SnapshotKey::runtime +method nvx::host::snapshot::SnapshotKey::scratch +method nvx::host::snapshot::SnapshotKey::speaks_current_contracts +method nvx::host::snapshot::SnapshotKey::to_bytes +struct nvx::host::snapshot::SnapshotManifest +method nvx::host::snapshot::SnapshotManifest::created_at +method nvx::host::snapshot::SnapshotManifest::hypervisor +method nvx::host::snapshot::SnapshotManifest::memory_len +method nvx::host::snapshot::SnapshotManifest::openvmm_version +method nvx::host::snapshot::SnapshotManifest::parse +method nvx::host::snapshot::SnapshotManifest::read +method nvx::host::snapshot::SnapshotManifest::state_len +method nvx::host::snapshot::SnapshotManifest::time +struct nvx::host::snapshot::TimeContract +field nvx::host::snapshot::TimeContract::apic_frequency_hz +field nvx::host::snapshot::TimeContract::boot_id +field nvx::host::snapshot::TimeContract::capture_monotonic_ns +field nvx::host::snapshot::TimeContract::capture_tsc +field nvx::host::snapshot::TimeContract::capture_utc_ns +field nvx::host::snapshot::TimeContract::cut_to_anchor_ns +method nvx::host::snapshot::TimeContract::eligibility +field nvx::host::snapshot::TimeContract::host_clock +field nvx::host::snapshot::TimeContract::host_id +field nvx::host::snapshot::TimeContract::lineage +field nvx::host::snapshot::TimeContract::tsc_frequency_hz +field nvx::host::snapshot::TimeContract::tsc_tolerance_ppm mod nvx::host::store struct nvx::host::store::ArtifactIdentity method nvx::host::store::ArtifactIdentity::as_str @@ -2046,7 +2159,6 @@ method nvx::host::template::TemplateKey::cpu_profile method nvx::host::template::TemplateKey::distro method nvx::host::template::TemplateKey::filesystem_tag method nvx::host::template::TemplateKey::from_bytes -method nvx::host::template::TemplateKey::guest_build method nvx::host::template::TemplateKey::guest_network method nvx::host::template::TemplateKey::has_network method nvx::host::template::TemplateKey::hypervisor diff --git a/nvx-rs/src/host/mod.rs b/nvx-rs/src/host/mod.rs index d18162cd4..cdf254640 100644 --- a/nvx-rs/src/host/mod.rs +++ b/nvx-rs/src/host/mod.rs @@ -92,6 +92,7 @@ pub mod runtime; pub mod sandbox; pub mod seal; pub mod session; +pub mod snapshot; mod spawn; pub mod store; pub mod supervisor; diff --git a/nvx-rs/src/host/snapshot.rs b/nvx-rs/src/host/snapshot.rs new file mode 100644 index 000000000..4fde64985 --- /dev/null +++ b/nvx-rs/src/host/snapshot.rs @@ -0,0 +1,38 @@ +//! Snapshot metadata: compatibility keys, strict manifests and restore-time eligibility. +//! +//! [`SnapshotKey`] derives a compatibility key from a capture's class and manifest. +//! [`SnapshotManifest::read`] reads the manifest that OpenVMM wrote, and +//! [`TimeContract::eligibility`] checks its restore window at a [`HostTime`]. +//! +//! # Canonical encoding +//! +//! A key and a class each have one canonical encoding, which [`SnapshotKey::to_bytes`] and +//! [`CaptureClass::to_bytes`] write, and whose SHA-256 digest, after a domain of its own, is its +//! identity, a [`KeyIdentity`] or a [`ClassIdentity`]. The encoding starts with its version, and +//! each value in it has exactly one encoding: +//! +//! - An integer is its fixed number of little-endian bytes: one for a `u8`, two for a `u16`, four +//! for a `u32`, and eight for a `u64`. +//! - A boolean is one byte, 0 or 1. +//! - A byte string of fixed length, such as a digest or an address, is its bytes. +//! - A byte string of variable length is its length, a `u32`, then its bytes. A text is the byte +//! string of its UTF-8 encoding. +//! - An optional value is one byte: 0 without the value, and 1 before it. +//! - A list is its count, a `u32`, then its items in order. +//! +//! [`SnapshotKey::from_bytes`] refuses any other encoding, and bytes left after it. The vectors +//! in `tests/vectors/snapshot-key-v1.txt` fix version 1 of a key's encoding and of a class's. + +mod canonical; +pub(super) mod eligibility; +pub(super) mod key; +pub(super) mod manifest; +#[cfg(test)] +pub(crate) mod tests; +mod wire; + +pub use self::eligibility::{Downtime, DowntimeSource, Eligibility, HostTime, MAX_DOWNTIME_NS}; +pub use self::key::{CaptureClass, ClassIdentity, Invariants, KeyIdentity, SnapshotKey}; +pub use self::manifest::{ + BlockGeometry, HostClock, MANIFEST_NAME, MAX_MANIFEST_LEN, SnapshotManifest, TimeContract, +}; diff --git a/nvx-rs/src/host/template/canonical.rs b/nvx-rs/src/host/snapshot/canonical.rs similarity index 100% rename from nvx-rs/src/host/template/canonical.rs rename to nvx-rs/src/host/snapshot/canonical.rs diff --git a/nvx-rs/src/host/template/canonical/tests.rs b/nvx-rs/src/host/snapshot/canonical/tests.rs similarity index 100% rename from nvx-rs/src/host/template/canonical/tests.rs rename to nvx-rs/src/host/snapshot/canonical/tests.rs diff --git a/nvx-rs/src/host/template/eligibility.rs b/nvx-rs/src/host/snapshot/eligibility.rs similarity index 99% rename from nvx-rs/src/host/template/eligibility.rs rename to nvx-rs/src/host/snapshot/eligibility.rs index f81994d75..65d3b7e6d 100644 --- a/nvx-rs/src/host/template/eligibility.rs +++ b/nvx-rs/src/host/snapshot/eligibility.rs @@ -9,10 +9,10 @@ use std::io; use std::time::SystemTime; use super::manifest::{HostClock, TimeContract}; -use super::store::Generation; use crate::error::{Error, ErrorKind, Result}; use crate::host::platform; use crate::host::process::BootId; +use crate::host::template::Generation; /// The longest interval by which a restore advances a clone's VM time, from the cut of the /// captured VM's time to the restoring host's time, in nanoseconds: 30 days, as version diff --git a/nvx-rs/src/host/template/eligibility/tests.rs b/nvx-rs/src/host/snapshot/eligibility/tests.rs similarity index 100% rename from nvx-rs/src/host/template/eligibility/tests.rs rename to nvx-rs/src/host/snapshot/eligibility/tests.rs diff --git a/nvx-rs/src/host/template/key.rs b/nvx-rs/src/host/snapshot/key.rs similarity index 96% rename from nvx-rs/src/host/template/key.rs rename to nvx-rs/src/host/snapshot/key.rs index 5a6e0af7c..34da58d2d 100644 --- a/nvx-rs/src/host/template/key.rs +++ b/nvx-rs/src/host/snapshot/key.rs @@ -1,4 +1,4 @@ -//! The compatibility key of a template, [`TemplateKey`], and the [`CaptureClass`] of the capture +//! The compatibility key of a snapshot, [`SnapshotKey`], and the [`CaptureClass`] of the capture //! that makes one. use std::fmt; @@ -12,7 +12,7 @@ use super::manifest::{ FILESYSTEM_SLOT_VERSION, Interrupts, Ipv6Identity, MAX_COMMAND_LINE_LEN, MAX_CPUID_ENTRIES, MAX_DEVICE_RANGES, MAX_DEVICE_WORDS, MAX_DEVICES, MAX_MEMORY_RANGES, MAX_PROCESSORS, MAX_TEXT_LEN, Machine, Memory, MemoryRange, Nic, PROCESSOR_COUNTS, PolicyIdentity, Rates, - TemplateManifest, Topology, parse_profile_id, + SnapshotManifest, Topology, parse_profile_id, }; use crate::activation; use crate::contract; @@ -27,7 +27,7 @@ use crate::hypervisor::Hypervisor; pub use crate::host::config::Invariants; /// The domain of a key's identity: the bytes that precede its canonical encoding in the digest. -const KEY_DOMAIN: &[u8] = b"nvx template key\0"; +const KEY_DOMAIN: &[u8] = b"nvx snapshot key\0"; /// The domain of a capture class's identity: the bytes that precede its canonical encoding in the /// digest. @@ -203,15 +203,15 @@ macro_rules! identity { } identity!( - /// The identity of a [`TemplateKey`]: the SHA-256 digest of its canonical encoding, after the - /// domain `nvx template key` and a NUL, so that it names a key of one encoding version alone. + /// The identity of a [`SnapshotKey`]: the SHA-256 digest of its canonical encoding, after the + /// domain `nvx snapshot key` and a NUL, so that it names a key of one encoding version alone. /// /// Its text form, which `Display` writes and `FromStr` parses, is 64 lowercase hexadecimal /// digits; parsing also accepts uppercase ones. It converts to and from the /// [`activation::Identity`] by which a clone's lease and durable records name the key of its /// template, in their [`TemplateReference`](activation::TemplateReference), without loss. KeyIdentity, - "a template key's identity" + "a snapshot key's identity" ); impl From for activation::Identity { @@ -290,8 +290,8 @@ fn guest_network_of(nic: &Nic) -> String { /// The invariant inputs of a template's capture, known before it: what a template's adapter /// requests, and the class of the templates that the capture makes. /// -/// A capture whose manifest matches its class makes a template whose [`TemplateKey`] combines -/// them: [`TemplateKey::new`] checks that the machine of the manifest is the class's, and takes +/// A capture whose manifest matches its class makes a template whose [`SnapshotKey`] combines +/// them: [`SnapshotKey::new`] checks that the machine of the manifest is the class's, and takes /// the rest of the key from it. Captures of one class make templates of one key, unless something /// that the class does not fix changed between them, such as the host's CPU, which its effective /// CPUID and its rates follow. @@ -443,7 +443,7 @@ impl CaptureClass { /// A key holds, and nothing else: /// /// - **Bundle and contracts:** the identities of OpenVMM, the guest kernel, and the guest -/// initramfs, and the build of the guest's agent, which the adapter supplies; and the versions +/// initramfs; and the versions /// of the key's encoding and of the boot, snapshot, device-state, time, restore-packet, /// control, and activation contracts. /// - **CPU and time:** the backend; the CPU profile's vendor, generation, revision, and the digest @@ -465,7 +465,7 @@ impl CaptureClass { /// /// A capture's own metadata is not part of it, so the generations of one key differ in it: when /// the capture was taken, its time contract's anchor, host, boot, and lineage counter, and the -/// lengths of its artifacts. [`TemplateManifest`] keeps them. Nothing of a clone is part of it +/// lengths of its artifacts. [`SnapshotManifest`] keeps them. Nothing of a clone is part of it /// either: its image, upper, export, network policy and settings, identity, and activation /// targets. So a template with a NIC serves the clones of every network policy at its guest's /// address. @@ -478,11 +478,9 @@ impl CaptureClass { /// Its [`identity`](Self::identity) is the SHA-256 digest of its /// [canonical encoding](Self::to_bytes), after a domain that no other digest of this crate shares. #[derive(Debug, Clone, PartialEq, Eq)] -pub struct TemplateKey { +pub struct SnapshotKey { /// The runtime: OpenVMM, the guest kernel and initramfs, and the boot and control contracts. runtime: RuntimeIdentity, - /// The build of the guest's agent. - guest_build: ArtifactIdentity, /// The versions of the other contracts. contracts: Contracts, /// The machine, as the manifest describes it. @@ -493,10 +491,13 @@ pub struct TemplateKey { invariants: Invariants, } -impl TemplateKey { +pub(in crate::host) use SnapshotKey as TemplateKey; + +impl SnapshotKey { /// Version of the canonical encoding of a key, its first two bytes. /// - /// Version 1 holds the template's NIC, if it has one, with the identity of the complete + /// Version 1 omits the guest build and holds the snapshot's NIC, if it has one, with the + /// identity of the complete /// deny-all policy under which the capture attached it, but no network policy of its clones. /// It has not been released, so a template store that an earlier build created is not /// supported: delete it and create a new one. There is no migration. @@ -514,7 +515,7 @@ impl TemplateKey { /// NIC, and the NIC's address and prefix, and a CPU profile that the class's request selects. /// A manifest whose machine has no processors online at boot activates all of them at boot, /// which a class whose processors are all online at boot requests. The key takes the class's - /// runtime, guest build, and invariant settings, and this crate's versions of the other + /// runtime and invariant settings, and this crate's versions of the other /// contracts. /// /// The key also takes the identity of the network policy that OpenVMM enforced on the NIC, @@ -529,7 +530,7 @@ impl TemplateKey { /// [`CaptureClass::check`] does, and with [`ErrorKind::Io`](crate::ErrorKind::Io) for a /// manifest whose machine is not the class's, as a capture that did not do what its class /// requested. - pub fn new(class: &CaptureClass, manifest: &TemplateManifest) -> Result { + pub fn new(class: &CaptureClass, manifest: &SnapshotManifest) -> Result { class.check()?; let machine = &manifest.machine; let mismatch = |found: String, requested: String| { @@ -609,7 +610,6 @@ impl TemplateKey { } Ok(Self { runtime: class.runtime.clone(), - guest_build: class.guest_build.clone(), contracts: Contracts::CURRENT, machine: machine.clone(), filesystem_tag: MOUNT_TAG.to_owned(), @@ -628,11 +628,6 @@ impl TemplateKey { &self.runtime } - /// Returns the build of the guest's agent. - pub fn guest_build(&self) -> &ArtifactIdentity { - &self.guest_build - } - /// Returns whether the versions of the snapshot, device-state, time, restore-packet, and /// activation contracts in the key are those that this crate speaks. pub fn speaks_current_contracts(&self) -> bool { @@ -732,7 +727,7 @@ impl TemplateKey { /// 1. [`VERSION`](Self::VERSION), a `u16`. /// 2. The bundle and contracts: the OpenVMM, kernel, and initramfs identities, texts; the boot /// contract version, a `u64`; the control contract revision, a text; the control session - /// version, a `u64`; the guest build, a text; and the snapshot format, device-state schema, + /// version, a `u64`; and the snapshot format, device-state schema, /// time ABI, restore packet, and activation contract versions, `u64`s. /// 3. CPU and time: the backend, a text, as OpenVMM spells it; the CPU profile's vendor and /// generation, texts, its revision, a `u32`, and its digest, 32 bytes; the effective @@ -763,7 +758,6 @@ impl TemplateKey { let mut writer = Writer::default(); writer.u16(Self::VERSION); write_runtime(&mut writer, &self.runtime); - writer.text(self.guest_build.as_str()); self.contracts.write(&mut writer); write_machine(&mut writer, &self.machine, &self.filesystem_tag); self.invariants.write(&mut writer); @@ -781,20 +775,20 @@ impl TemplateKey { pub fn from_bytes(bytes: &[u8]) -> Result { if bytes.len() > Self::MAX_LEN { return Err(Error::io(format!( - "a template key of {} bytes is longer than the {} bytes that a key may hold", + "a snapshot key of {} bytes is longer than the {} bytes that a key may hold", bytes.len(), Self::MAX_LEN ))); } let mut reader = Reader::new(bytes); let malformed = - |error: CanonicalError| Error::io(format!("the template key is malformed: {error}")); + |error: CanonicalError| Error::io(format!("the snapshot key is malformed: {error}")); let version = reader.u16("the version").map_err(malformed)?; if version != Self::VERSION { return Err(Error::new( crate::ErrorCode::FormatUnsupported, format!( - "the template key has encoding version {version}; this build reads version {} \ + "the snapshot key has encoding version {version}; this build reads version {} \ only", Self::VERSION ), @@ -802,13 +796,11 @@ impl TemplateKey { } let read = |reader: &mut Reader<'_>| -> Result { let runtime = read_runtime(reader)?; - let guest_build = read_artifact(reader, "the guest build")?; let contracts = Contracts::read(reader)?; let (machine, filesystem_tag) = read_machine(reader)?; let invariants = Invariants::read(reader)?; Ok(Self { runtime, - guest_build, contracts, machine, filesystem_tag, @@ -822,7 +814,7 @@ impl TemplateKey { } /// Writes the machine `machine`, whose filesystem slot has the tag `tag`, as -/// [`TemplateKey::to_bytes`] describes it. +/// [`SnapshotKey::to_bytes`] describes it. fn write_machine(writer: &mut Writer, machine: &Machine, tag: &str) { writer.text(machine.hypervisor.as_str()); let cpu = &machine.cpu; diff --git a/nvx-rs/src/host/template/key/tests.rs b/nvx-rs/src/host/snapshot/key/tests.rs similarity index 92% rename from nvx-rs/src/host/template/key/tests.rs rename to nvx-rs/src/host/snapshot/key/tests.rs index 7c119ac8e..1a6ff2f91 100644 --- a/nvx-rs/src/host/template/key/tests.rs +++ b/nvx-rs/src/host/snapshot/key/tests.rs @@ -1,4 +1,4 @@ -//! Tests of [`TemplateKey`] and [`CaptureClass`]: what a key holds, what it leaves out, and its +//! Tests of [`SnapshotKey`] and [`CaptureClass`]: what a key holds, what it leaves out, and its //! canonical encoding. use std::collections::HashSet; @@ -6,21 +6,21 @@ use std::collections::HashSet; use super::*; use crate::ErrorCode; use crate::host::network::{Access, EgressRule, HostLoopback, NetworkPolicy, NetworkProxy}; -use crate::host::template::tests::{self as support, MIB, ManifestSpec, artifact, network_class}; +use crate::host::snapshot::tests::{self as support, MIB, ManifestSpec, artifact, network_class}; /// Returns the manifest that `spec` encodes. -fn manifest(spec: &ManifestSpec) -> TemplateManifest { - TemplateManifest::parse(&spec.encode()).unwrap() +fn manifest(spec: &ManifestSpec) -> SnapshotManifest { + SnapshotManifest::parse(&spec.encode()).unwrap() } /// Returns the key of the template that a capture of `class` made, whose manifest `spec` /// encodes. -fn key(class: &CaptureClass, spec: &ManifestSpec) -> TemplateKey { - TemplateKey::new(class, &manifest(spec)).unwrap() +fn key(class: &CaptureClass, spec: &ManifestSpec) -> SnapshotKey { + SnapshotKey::new(class, &manifest(spec)).unwrap() } /// Returns the key of the template with a NIC of the tests. -fn network_key() -> TemplateKey { +fn network_key() -> SnapshotKey { key(&network_class(), &ManifestSpec::with_network()) } @@ -60,9 +60,6 @@ fn each_part_of_the_key_changes_it() { ("control session", |class, _| { class.runtime.control_session += 1 }), - ("guest build", |class, _| { - class.guest_build = ArtifactIdentity::new("guest-build-2").unwrap(); - }), // CPU and time. ("backend", |class, spec| { class.hypervisor = Hypervisor::Mshv; @@ -280,7 +277,7 @@ fn each_contract_version_changes_the_key() { assert!(!other.speaks_current_contracts()); assert!(identities.insert(other.identity())); // A key of other versions reads back as it is, so that a store can name what it holds. - assert_eq!(TemplateKey::from_bytes(&other.to_bytes()).unwrap(), other); + assert_eq!(SnapshotKey::from_bytes(&other.to_bytes()).unwrap(), other); } } @@ -332,12 +329,31 @@ fn a_generations_own_metadata_leaves_the_key_as_it_is() { } } +#[test] +fn the_guest_build_is_not_part_of_a_snapshot_key() { + let class = network_class(); + let spec = ManifestSpec::with_network(); + let made = key(&class, &spec); + let other = CaptureClass { + guest_build: ArtifactIdentity::new("guest-build-2").unwrap(), + ..class.clone() + }; + assert_ne!(class.identity().unwrap(), other.identity().unwrap()); + let changed = key(&other, &spec); + assert_eq!(changed, made); + assert_eq!(changed.to_bytes(), made.to_bytes()); + assert_eq!(changed.identity(), made.identity()); + assert_eq!( + crate::host::template::TemplateKey::from_bytes(&changed.to_bytes()).unwrap(), + made + ); +} + #[test] fn a_key_holds_what_its_capture_made() { let made = network_key(); let class = network_class(); assert_eq!(made.runtime(), &class.runtime); - assert_eq!(made.guest_build(), &class.guest_build); assert_eq!(made.hypervisor(), Hypervisor::Kvm); assert_eq!(made.cpu_profile(), "intel.icelake-sp.v1"); assert_eq!((made.processors(), made.boot_processors()), (2, 0)); @@ -382,7 +398,7 @@ fn a_key_holds_what_its_capture_made() { /// Asserts that the capture of `class` whose manifest is `spec` does not match its class, with /// a message that holds `expected`. fn assert_mismatched(class: &CaptureClass, spec: &ManifestSpec, expected: &str) { - let error = TemplateKey::new(class, &manifest(spec)).unwrap_err(); + let error = SnapshotKey::new(class, &manifest(spec)).unwrap_err(); assert_eq!(error.code(), ErrorCode::Io, "{error}"); assert!( error @@ -439,7 +455,7 @@ fn a_capture_that_does_not_match_its_class_is_refused() { &spec, "it has 2 processors, 1 online at boot, but the class requests 2 processors, 2 online", ); - assert!(TemplateKey::new(&class, &manifest(&spec)).is_ok()); + assert!(SnapshotKey::new(&class, &manifest(&spec)).is_ok()); class = base.clone(); class.memory = 1024 * MIB; assert_mismatched( @@ -547,7 +563,7 @@ fn invalid_classes_are_refused() { class.check().unwrap_err(), class.to_bytes().unwrap_err(), class.identity().unwrap_err(), - TemplateKey::new(&class, &manifest(&ManifestSpec::with_network())).unwrap_err(), + SnapshotKey::new(&class, &manifest(&ManifestSpec::with_network())).unwrap_err(), ] { assert_eq!(error.code(), ErrorCode::Unsupported, "{error}"); assert!( @@ -649,11 +665,11 @@ fn keys_read_back_from_their_canonical_encoding() { ] { let bytes = made.to_bytes(); assert_eq!(&bytes[..2], &[1, 0]); - let read = TemplateKey::from_bytes(&bytes).unwrap(); + let read = SnapshotKey::from_bytes(&bytes).unwrap(); assert_eq!(read, made); assert_eq!(read.to_bytes(), bytes); let mut digest = Sha256::new(); - digest.update(b"nvx template key\0"); + digest.update(b"nvx snapshot key\0"); digest.update(&bytes); assert_eq!( made.identity().as_bytes(), @@ -662,9 +678,33 @@ fn keys_read_back_from_their_canonical_encoding() { } } +#[test] +fn keys_with_the_removed_guest_build_field_are_refused() { + let class = network_class(); + let made = network_key(); + let mut prefix = Writer::default(); + prefix.u16(SnapshotKey::VERSION); + write_runtime(&mut prefix, made.runtime()); + let offset = prefix.finish().len(); + let mut field = Writer::default(); + field.text(class.guest_build.as_str()); + let mut old = made.to_bytes(); + old.splice(offset..offset, field.finish()); + assert_eq!( + SnapshotKey::from_bytes(&old).unwrap_err().code(), + ErrorCode::Io + ); + assert_eq!( + crate::host::template::TemplateKey::from_bytes(&old) + .unwrap_err() + .code(), + ErrorCode::Io + ); +} + /// Returns the message of the refusal of the key bytes `bytes`, which must have the code `code`. fn key_refusal(bytes: &[u8], code: ErrorCode) -> String { - let error = TemplateKey::from_bytes(bytes).unwrap_err(); + let error = SnapshotKey::from_bytes(bytes).unwrap_err(); assert_eq!(error.code(), code, "{error}"); error.message().to_owned() } @@ -679,7 +719,7 @@ fn other_encodings_of_a_key_are_refused() { assert_eq!( key_refusal(&other, ErrorCode::FormatUnsupported), format!( - "the template key has encoding version {version}; this build reads version 1 \ + "the snapshot key has encoding version {version}; this build reads version 1 \ only" ) ); @@ -688,16 +728,16 @@ fn other_encodings_of_a_key_are_refused() { longer.push(0); assert_eq!( key_refusal(&longer, ErrorCode::Io), - "the template key is malformed: a byte follows the value" + "the snapshot key is malformed: a byte follows the value" ); for len in 0..bytes.len() { key_refusal(&bytes[..len], ErrorCode::Io); } assert_eq!( key_refusal(&[], ErrorCode::Io), - "the template key is malformed: the version is truncated" + "the snapshot key is malformed: the version is truncated" ); - let oversized = vec![0; TemplateKey::MAX_LEN + 1]; + let oversized = vec![0; SnapshotKey::MAX_LEN + 1]; assert!(key_refusal(&oversized, ErrorCode::Io).contains("is longer than the")); } @@ -726,7 +766,7 @@ fn a_key_that_holds_its_network_s_lowering_after_its_invariants_is_refused() { assert_eq!( key_refusal(&bytes, ErrorCode::Io), format!( - "the template key is malformed: {} bytes follow the value", + "the snapshot key is malformed: {} bytes follow the value", part.len() ) ); @@ -735,7 +775,7 @@ fn a_key_that_holds_its_network_s_lowering_after_its_invariants_is_refused() { #[test] fn keys_of_machines_that_no_manifest_describes_are_refused() { - type KeyChange = fn(&mut TemplateKey); + type KeyChange = fn(&mut SnapshotKey); let cases: &[(KeyChange, &str)] = &[ ( |key| key.machine.command_line.push_str(" quiet"), @@ -775,7 +815,7 @@ fn keys_of_machines_that_no_manifest_describes_are_refused() { change(&mut changed); let message = key_refusal(&changed.to_bytes(), ErrorCode::Io); assert!( - message.starts_with(&format!("the template key is malformed: {expected}")), + message.starts_with(&format!("the snapshot key is malformed: {expected}")), "{message:?} lacks {expected:?}" ); } @@ -794,7 +834,7 @@ fn keys_of_machines_that_no_manifest_describes_are_refused() { bytes[len - tail.len()..].copy_from_slice(&tail); assert_eq!( key_refusal(&bytes, ErrorCode::Io), - "the template key is malformed: the invariant settings are not in the strict order of \ + "the snapshot key is malformed: the invariant settings are not in the strict order of \ their names" ); // An artifact identity that a runtime identity refuses. @@ -849,7 +889,7 @@ fn identities_have_a_text_form() { assert_eq!(error.code(), ErrorCode::Unsupported); assert_eq!( error.message(), - format!("{invalid:?} is not a template key's identity, which is 64 hexadecimal digits") + format!("{invalid:?} is not a snapshot key's identity, which is 64 hexadecimal digits") ); } let class = network_class().identity().unwrap(); @@ -863,7 +903,7 @@ fn identities_have_a_text_form() { } /// The conformance vectors of version 1 of the canonical encodings of keys and classes. -const VECTORS: &str = include_str!("../../../../tests/vectors/template-key-v1.txt"); +const VECTORS: &str = include_str!("../../../../tests/vectors/snapshot-key-v1.txt"); /// The versions of the contracts that the vectors hold. const VECTOR_CONTRACTS: Contracts = Contracts { @@ -979,15 +1019,15 @@ fn the_conformance_vectors_decode_and_encode() { let names: Vec<&str> = keys.iter().map(|(name, ..)| *name).collect(); assert_eq!(names, ["TEMPLATE", "NETWORK", "HOST_PROFILE", "MINIMAL"]); for (name, bytes, values) in keys { - let key = TemplateKey::from_bytes(&bytes).unwrap_or_else(|error| panic!("{name}: {error}")); + let key = SnapshotKey::from_bytes(&bytes).unwrap_or_else(|error| panic!("{name}: {error}")); assert_eq!(key.to_bytes(), bytes, "{name}"); assert_eq!(values, [key.identity().to_string()], "{name}"); if name != "MINIMAL" { // The key that this crate derives from the capture is the vector's, but for the // versions of the contracts, which are this crate's. - let derived = TemplateKey::new(&vector_class(name), &manifest(&vector_spec(name))) + let derived = SnapshotKey::new(&vector_class(name), &manifest(&vector_spec(name))) .unwrap_or_else(|error| panic!("{name}: {error}")); - let derived = TemplateKey { + let derived = SnapshotKey { contracts: VECTOR_CONTRACTS, ..derived }; @@ -1009,7 +1049,7 @@ fn the_conformance_vectors_decode_and_encode() { let versions = vectors("INVALID_KEY_VERSION"); assert_eq!(versions.len(), 3); for (name, bytes, _) in versions { - let error = TemplateKey::from_bytes(&bytes).expect_err(name); + let error = SnapshotKey::from_bytes(&bytes).expect_err(name); assert_eq!( error.code(), ErrorCode::FormatUnsupported, @@ -1019,7 +1059,7 @@ fn the_conformance_vectors_decode_and_encode() { let invalid = vectors("INVALID_KEY"); assert_eq!(invalid.len(), 23); for (name, bytes, _) in invalid { - let error = TemplateKey::from_bytes(&bytes).expect_err(name); + let error = SnapshotKey::from_bytes(&bytes).expect_err(name); assert_eq!(error.code(), ErrorCode::Io, "{name}: {error}"); } } diff --git a/nvx-rs/src/host/template/manifest.rs b/nvx-rs/src/host/snapshot/manifest.rs similarity index 98% rename from nvx-rs/src/host/template/manifest.rs rename to nvx-rs/src/host/snapshot/manifest.rs index 76db5f900..6148f89da 100644 --- a/nvx-rs/src/host/template/manifest.rs +++ b/nvx-rs/src/host/snapshot/manifest.rs @@ -1,4 +1,4 @@ -//! The manifest of a snapshot: a template's capture, which [`TemplateManifest::read`] reads, and +//! The manifest of a snapshot: a template's capture, which [`SnapshotManifest::read`] reads, and //! the host attachments of any microVM snapshot, which `read_attachments` reads for the restores //! of `nvx-rs run`. //! @@ -7,7 +7,7 @@ //! most [`MAX_MANIFEST_LEN`] bytes. It describes the machine that the snapshot restores, its time //! contract and CPU profile, its sandbox blocks, the host attachments that a restore reconnects, //! and the lengths of its artifacts. Restore treats it as authoritative, and so does a template's -//! [compatibility key](super::TemplateKey), which projects its machine. [`TemplateManifest`] +//! [compatibility key](super::SnapshotKey), which projects its machine. [`SnapshotManifest`] //! describes what the reader refuses. use std::io; @@ -28,7 +28,7 @@ use crate::hypervisor::Hypervisor; /// Name of the manifest in a snapshot's directory. pub const MANIFEST_NAME: &str = "manifest.bin"; -/// Longest manifest that [`TemplateManifest::read`] reads, in bytes: 1 MiB, the limit of +/// Longest manifest that [`SnapshotManifest::read`] reads, in bytes: 1 MiB, the limit of /// OpenVMM's own reader. pub const MAX_MANIFEST_LEN: u64 = 1024 * 1024; @@ -107,7 +107,7 @@ pub(super) const CPUID_ENTRY_LEN: usize = 44; /// Most entries of a CPU profile's effective CPUID record. pub(super) const MAX_CPUID_ENTRIES: usize = 1024; -pub(super) use crate::host::config::PROCESSOR_COUNTS; +pub(in crate::host) use crate::host::config::PROCESSOR_COUNTS; /// Bytes of a SHA-256 digest. const SHA256_LEN: usize = 32; @@ -633,11 +633,11 @@ impl Machine { /// a read-only `distro` whose identity is unbound, a fresh scratch, and the dormant filesystem /// slot. It never reads another artifact of the snapshot. /// -/// A template's [`TemplateKey`](super::TemplateKey) projects its machine. The rest is the +/// A template's [`SnapshotKey`](super::SnapshotKey) projects its machine. The rest is the /// capture's own: when it was taken, its [`TimeContract`]'s anchor, host, boot, and lineage /// counter, and the lengths of its artifacts, in which the generations of one key differ. #[derive(Debug, Clone, PartialEq, Eq)] -pub struct TemplateManifest { +pub struct SnapshotManifest { /// When OpenVMM created the snapshot. created_at: SystemTime, /// The version of the OpenVMM that captured it. @@ -650,7 +650,9 @@ pub struct TemplateManifest { pub(super) machine: Machine, } -impl TemplateManifest { +pub(in crate::host) use SnapshotManifest as TemplateManifest; + +impl SnapshotManifest { /// Reads the manifest of the snapshot in the directory `snapshot`: its [`MANIFEST_NAME`]. /// /// The file is opened without following a link, or on Windows any other reparse point, and @@ -675,7 +677,7 @@ impl TemplateManifest { /// layout, or time ABI than this build reads, and with /// [`ErrorKind::Io`](crate::ErrorKind::Io) for more than [`MAX_MANIFEST_LEN`] bytes, bytes /// that are not such a manifest, and a manifest that is not a template's, as - /// [`TemplateManifest`] describes. + /// [`SnapshotManifest`] describes. pub fn parse(bytes: &[u8]) -> Result { Self::parse_described(bytes, "the snapshot manifest") } @@ -796,11 +798,11 @@ pub(crate) struct Attachment { /// machine contract of its manifest, [`MANIFEST_NAME`]: those of any microVM snapshot, a /// template's or not, which `nvx-rs run` restores. /// -/// It reads the manifest as [`TemplateManifest::read`] does, and checks its format and the form of -/// its fields as [`TemplateManifest::parse`] does, but nothing that makes it a template's. A +/// It reads the manifest as [`SnapshotManifest::read`] does, and checks its format and the form of +/// its fields as [`SnapshotManifest::parse`] does, but nothing that makes it a template's. A /// manifest without a machine contract holds no attachments. /// -/// Fails as [`TemplateManifest::read`] does, but for a manifest that is not a template's. +/// Fails as [`SnapshotManifest::read`] does, but for a manifest that is not a template's. #[cfg(feature = "cli")] pub(crate) fn read_attachments(snapshot: &Path) -> Result> { let (bytes, description) = read_manifest(snapshot)?; @@ -819,7 +821,7 @@ pub(crate) fn read_attachments(snapshot: &Path) -> Result> { const CAPTURE_TEMPLATE: &str = "the template again with the runtime of this build"; /// Reads the manifest of the snapshot in the directory `snapshot`, its [`MANIFEST_NAME`], as -/// [`TemplateManifest::read`] describes, and returns its bytes, with the description that names +/// [`SnapshotManifest::read`] describes, and returns its bytes, with the description that names /// it in messages. fn read_manifest(snapshot: &Path) -> Result<(Vec, String)> { let path = snapshot.join(MANIFEST_NAME); @@ -837,7 +839,7 @@ fn read_manifest(snapshot: &Path) -> Result<(Vec, String)> { } /// Checks the length and the format of the manifest `bytes`, with messages that call it -/// `description`, and decodes it, as [`TemplateManifest::parse`] describes; a capture of `again` +/// `description`, and decodes it, as [`SnapshotManifest::parse`] describes; a capture of `again` /// mends a format that this build does not read. fn decode_described(bytes: &[u8], description: &str, again: &str) -> Result { if bytes.len() as u64 > MAX_MANIFEST_LEN { diff --git a/nvx-rs/src/host/template/manifest/tests.rs b/nvx-rs/src/host/snapshot/manifest/tests.rs similarity index 98% rename from nvx-rs/src/host/template/manifest/tests.rs rename to nvx-rs/src/host/snapshot/manifest/tests.rs index d15972e06..517b46cb2 100644 --- a/nvx-rs/src/host/template/manifest/tests.rs +++ b/nvx-rs/src/host/snapshot/manifest/tests.rs @@ -1,4 +1,4 @@ -//! Tests of [`TemplateManifest`]: what it reads of a template's manifest, and what it refuses, and +//! Tests of [`SnapshotManifest`]: what it reads of a template's manifest, and what it refuses, and //! of `read_attachments`, which reads the host attachments of any snapshot's manifest for the CLI. use std::fs; @@ -6,16 +6,16 @@ use std::path::Path; use std::time::{Duration, SystemTime}; use super::*; -use crate::host::template::tests::{MIB, ManifestSpec, Proto}; +use crate::host::snapshot::tests::{MIB, ManifestSpec, Proto}; /// Returns the manifest that the encoding of `spec` parses to. -fn parse(spec: &ManifestSpec) -> TemplateManifest { - TemplateManifest::parse(&spec.encode()).unwrap() +fn parse(spec: &ManifestSpec) -> SnapshotManifest { + SnapshotManifest::parse(&spec.encode()).unwrap() } /// Returns the message of the refusal of `bytes`, which must have the code `code`. fn refusal(bytes: &[u8], code: ErrorCode) -> String { - let error = TemplateManifest::parse(bytes).expect_err("the manifest is refused"); + let error = SnapshotManifest::parse(bytes).expect_err("the manifest is refused"); assert_eq!(error.code(), code, "{error}"); error.message().to_owned() } @@ -247,7 +247,7 @@ fn the_fields_of_a_manifest_need_not_be_written_in_their_order() { spec.magic.clear(); let bytes = spec.encode_with(reversed); assert_eq!( - TemplateManifest::parse(&bytes).unwrap(), + SnapshotManifest::parse(&bytes).unwrap(), parse(&ManifestSpec::template()) ); } @@ -429,7 +429,7 @@ fn truncated_manifests_are_refused() { let bytes = ManifestSpec::template().encode(); for len in 0..bytes.len() { let error = - TemplateManifest::parse(&bytes[..len]).expect_err("a truncated manifest is refused"); + SnapshotManifest::parse(&bytes[..len]).expect_err("a truncated manifest is refused"); // A manifest that ends between its fields lacks some, such as its format magic. assert!( matches!(error.code(), ErrorCode::Io | ErrorCode::FormatUnsupported), @@ -865,7 +865,7 @@ fn the_manifests_that_openvmm_writes_are_read() { ("platform-kvm", ManifestSpec::template()), ("platform-mshv-network", ManifestSpec::with_network()), ] { - let manifest = TemplateManifest::read(&fixture(name)).unwrap(); + let manifest = SnapshotManifest::read(&fixture(name)).unwrap(); let machine = &manifest.machine; assert_eq!(machine.cpu.id(), "intel.icelake-sp.v1", "{name}"); assert_eq!(machine.cpu.effective_cpuid.len() % CPUID_ENTRY_LEN, 0); @@ -1018,7 +1018,7 @@ fn the_attachments_of_unreadable_manifests_are_refused() { /// Returns the message of the refusal of the manifest of the snapshot directory `directory`, /// which must have the code `code`, and the error that caused it. fn read_refusal(directory: &Path, code: ErrorCode) -> (String, String) { - let error = TemplateManifest::read(directory).expect_err("the manifest is refused"); + let error = SnapshotManifest::read(directory).expect_err("the manifest is refused"); assert_eq!(error.code(), code, "{error}"); let cause = std::error::Error::source(&error) .map(ToString::to_string) @@ -1031,7 +1031,7 @@ fn read_reads_the_manifest_of_a_snapshot() { let spec = ManifestSpec::with_network(); let directory = snapshot(&spec.encode()); assert_eq!( - TemplateManifest::read(directory.path()).unwrap(), + SnapshotManifest::read(directory.path()).unwrap(), parse(&spec) ); // The messages of a manifest that is read name its path. @@ -1132,7 +1132,7 @@ fn read_refuses_a_fifo_without_waiting_for_a_writer() { let path = directory.path().to_owned(); thread::spawn(move || { sender - .send(TemplateManifest::read(&path).map(drop)) + .send(SnapshotManifest::read(&path).map(drop)) .unwrap() }); let error = receiver diff --git a/nvx-rs/src/host/template/tests.rs b/nvx-rs/src/host/snapshot/tests.rs similarity index 81% rename from nvx-rs/src/host/template/tests.rs rename to nvx-rs/src/host/snapshot/tests.rs index d16127ade..3772e3ac5 100644 --- a/nvx-rs/src/host/template/tests.rs +++ b/nvx-rs/src/host/snapshot/tests.rs @@ -1,4 +1,4 @@ -//! Builders of the manifests and capture classes of templates, for their tests. +//! Builders of the manifests and capture classes of snapshots, for their tests. //! //! [`Proto`] writes the protobuf wire format as OpenVMM's `mesh` does, independently of the reader //! that the tests check, and [`ManifestSpec`] holds each field of a manifest, so that a test @@ -13,18 +13,18 @@ use crate::host::store::{ArtifactIdentity, RuntimeIdentity}; use crate::hypervisor::Hypervisor; /// Bytes in a MiB. -pub(super) const MIB: u64 = 1024 * 1024; +pub(in crate::host) const MIB: u64 = 1024 * 1024; /// A protobuf message under construction, whose fields are written in the order of the calls. /// /// Like `mesh`, the typed methods omit a field whose value is zero or empty, but for /// [`message`](Self::message) and [`some`](Self::some), which write an `Option` that is `Some`. #[derive(Debug, Clone, Default)] -pub(super) struct Proto(Vec); +pub(in crate::host) struct Proto(Vec); impl Proto { /// Appends `value` to `bytes` as a varint. - pub(super) fn put_varint(bytes: &mut Vec, mut value: u64) { + pub(in crate::host) fn put_varint(bytes: &mut Vec, mut value: u64) { loop { let byte = (value & 0x7f) as u8; value >>= 7; @@ -37,20 +37,20 @@ impl Proto { } /// Appends the key of field `number` of wire type `wire_type`. - pub(super) fn key(mut self, number: u32, wire_type: u8) -> Self { + pub(in crate::host) fn key(mut self, number: u32, wire_type: u8) -> Self { Self::put_varint(&mut self.0, u64::from(number) << 3 | u64::from(wire_type)); self } /// Appends field `number` as the varint `value`, even if it is 0. - pub(super) fn some(self, number: u32, value: u64) -> Self { + pub(in crate::host) fn some(self, number: u32, value: u64) -> Self { let mut message = self.key(number, 0); Self::put_varint(&mut message.0, value); message } /// Appends field `number` as the varint `value`, unless it is 0. - pub(super) fn varint(self, number: u32, value: u64) -> Self { + pub(in crate::host) fn varint(self, number: u32, value: u64) -> Self { if value == 0 { self } else { @@ -59,7 +59,7 @@ impl Proto { } /// Appends field `number` as the bytes `bytes`, even if they are empty. - pub(super) fn always_bytes(self, number: u32, bytes: &[u8]) -> Self { + pub(in crate::host) fn always_bytes(self, number: u32, bytes: &[u8]) -> Self { let mut message = self.key(number, 2); Self::put_varint(&mut message.0, bytes.len() as u64); message.0.extend_from_slice(bytes); @@ -67,7 +67,7 @@ impl Proto { } /// Appends field `number` as the bytes `bytes`, unless they are empty. - pub(super) fn bytes(self, number: u32, bytes: &[u8]) -> Self { + pub(in crate::host) fn bytes(self, number: u32, bytes: &[u8]) -> Self { if bytes.is_empty() { self } else { @@ -76,18 +76,18 @@ impl Proto { } /// Appends field `number` as the text `text`, unless it is empty. - pub(super) fn text(self, number: u32, text: &str) -> Self { + pub(in crate::host) fn text(self, number: u32, text: &str) -> Self { self.bytes(number, text.as_bytes()) } /// Appends field `number` as the message `message`, even if it is empty, as `mesh` writes an /// `Option` that is `Some`, or an element of a repeated field. - pub(super) fn message(self, number: u32, message: Proto) -> Self { + pub(in crate::host) fn message(self, number: u32, message: Proto) -> Self { self.always_bytes(number, &message.0) } /// Appends field `number` as the packed varints `values`, unless there are none. - pub(super) fn packed(self, number: u32, values: &[u32]) -> Self { + pub(in crate::host) fn packed(self, number: u32, values: &[u32]) -> Self { let mut packed = Vec::new(); for &value in values { Self::put_varint(&mut packed, u64::from(value)); @@ -96,40 +96,40 @@ impl Proto { } /// Appends `bytes` as they are. - pub(super) fn raw(mut self, bytes: &[u8]) -> Self { + pub(in crate::host) fn raw(mut self, bytes: &[u8]) -> Self { self.0.extend_from_slice(bytes); self } /// Returns the message's bytes. - pub(super) fn finish(self) -> Vec { + pub(in crate::host) fn finish(self) -> Vec { self.0 } } /// `openvmm.snapshot.SnapshotDevice`. #[derive(Debug, Clone)] -pub(super) struct DeviceSpec { +pub(in crate::host) struct DeviceSpec { /// Field 1. - pub(super) stable_id: String, + pub(in crate::host) stable_id: String, /// Field 2. - pub(super) state_unit: String, + pub(in crate::host) state_unit: String, /// Field 3. - pub(super) kind: String, + pub(in crate::host) kind: String, /// Field 4. - pub(super) order: u32, + pub(in crate::host) order: u32, /// Field 5: each range's address space, start, and length. - pub(super) ranges: Vec<(String, u64, u64)>, + pub(in crate::host) ranges: Vec<(String, u64, u64)>, /// Field 6. - pub(super) irq: Option, + pub(in crate::host) irq: Option, /// Field 7. - pub(super) transport: String, + pub(in crate::host) transport: String, /// Field 8. - pub(super) feature_banks: Vec, + pub(in crate::host) feature_banks: Vec, /// Field 9. - pub(super) queue_count: u32, + pub(in crate::host) queue_count: u32, /// Field 10. - pub(super) queue_max_sizes: Vec, + pub(in crate::host) queue_max_sizes: Vec, } impl DeviceSpec { @@ -211,23 +211,23 @@ impl DeviceSpec { /// `openvmm.snapshot.SnapshotAttachment`. #[derive(Debug, Clone)] -pub(super) struct AttachmentSpec { +pub(in crate::host) struct AttachmentSpec { /// Field 1. - pub(super) stable_id: String, + pub(in crate::host) stable_id: String, /// Field 2. - pub(super) kind: String, + pub(in crate::host) kind: String, /// Field 3. - pub(super) required: bool, + pub(in crate::host) required: bool, /// Field 4. - pub(super) reconnect_policy: String, + pub(in crate::host) reconnect_policy: String, /// Field 5. - pub(super) identity_kind: String, + pub(in crate::host) identity_kind: String, /// Field 6. - pub(super) identity: Vec, + pub(in crate::host) identity: Vec, /// Field 7. - pub(super) length: u64, + pub(in crate::host) length: u64, /// Field 8. - pub(super) reconnect_timeout_ms: u64, + pub(in crate::host) reconnect_timeout_ms: u64, } impl AttachmentSpec { @@ -267,33 +267,33 @@ impl AttachmentSpec { /// `openvmm.snapshot.SnapshotMicrovmNetwork`. #[derive(Debug, Clone)] -pub(super) struct NetworkSpec { +pub(in crate::host) struct NetworkSpec { /// Field 1. - pub(super) ipv4: [u8; 4], + pub(in crate::host) ipv4: [u8; 4], /// Field 2. - pub(super) prefix_length: u32, + pub(in crate::host) prefix_length: u32, /// Field 3. - pub(super) gateway: [u8; 4], + pub(in crate::host) gateway: [u8; 4], /// Field 4. - pub(super) guest_mac: Vec, + pub(in crate::host) guest_mac: Vec, /// Field 5. - pub(super) gateway_mac: Vec, + pub(in crate::host) gateway_mac: Vec, /// Field 6. - pub(super) policy_mode: String, + pub(in crate::host) policy_mode: String, /// Field 7. - pub(super) policy_digest: Vec, + pub(in crate::host) policy_digest: Vec, /// Field 8. - pub(super) policy_required: bool, + pub(in crate::host) policy_required: bool, /// Field 9. - pub(super) profile: String, + pub(in crate::host) profile: String, /// Field 10. - pub(super) policy_encoding_version: u32, + pub(in crate::host) policy_encoding_version: u32, /// Field 11. - pub(super) ipv6: Vec, + pub(in crate::host) ipv6: Vec, /// Field 12. - pub(super) ipv6_prefix_length: u32, + pub(in crate::host) ipv6_prefix_length: u32, /// Field 13. - pub(super) ipv6_gateway: Vec, + pub(in crate::host) ipv6_gateway: Vec, } impl NetworkSpec { @@ -318,25 +318,25 @@ impl NetworkSpec { /// `openvmm.snapshot.SnapshotMicrovmSandboxBlock`. #[derive(Debug, Clone)] -pub(super) struct BlockSpec { +pub(in crate::host) struct BlockSpec { /// Field 1. - pub(super) role: String, + pub(in crate::host) role: String, /// Field 2. - pub(super) read_only: bool, + pub(in crate::host) read_only: bool, /// Field 3. - pub(super) length: u64, + pub(in crate::host) length: u64, /// Field 4. - pub(super) identity_kind: String, + pub(in crate::host) identity_kind: String, /// Field 5. - pub(super) identity: Vec, + pub(in crate::host) identity: Vec, /// Field 6. - pub(super) artifact: String, + pub(in crate::host) artifact: String, /// Field 7. - pub(super) logical_block_size: u32, + pub(in crate::host) logical_block_size: u32, /// Field 8. - pub(super) physical_block_size: u32, + pub(in crate::host) physical_block_size: u32, /// Field 9. - pub(super) restore_mode: String, + pub(in crate::host) restore_mode: String, } impl BlockSpec { @@ -357,31 +357,31 @@ impl BlockSpec { /// `openvmm.snapshot.SnapshotTimeContract`. #[derive(Debug, Clone)] -pub(super) struct TimeSpec { +pub(in crate::host) struct TimeSpec { /// Field 1. - pub(super) abi_version: u32, + pub(in crate::host) abi_version: u32, /// Field 2. - pub(super) tsc_hz: u64, + pub(in crate::host) tsc_hz: u64, /// Field 3. - pub(super) tolerance_ppm: u32, + pub(in crate::host) tolerance_ppm: u32, /// Field 4. - pub(super) apic_hz: u64, + pub(in crate::host) apic_hz: u64, /// Field 5. - pub(super) capture_tsc: u64, + pub(in crate::host) capture_tsc: u64, /// Field 6. - pub(super) capture_utc_ns: u64, + pub(in crate::host) capture_utc_ns: u64, /// Field 7. - pub(super) capture_monotonic_ns: u64, + pub(in crate::host) capture_monotonic_ns: u64, /// Field 8. - pub(super) host_clock: String, + pub(in crate::host) host_clock: String, /// Field 9. - pub(super) host_id: Vec, + pub(in crate::host) host_id: Vec, /// Field 10. - pub(super) boot_id: Vec, + pub(in crate::host) boot_id: Vec, /// Field 11. - pub(super) lineage: u32, + pub(in crate::host) lineage: u32, /// Field 12. - pub(super) cut_to_anchor_ns: Option, + pub(in crate::host) cut_to_anchor_ns: Option, } impl TimeSpec { @@ -408,17 +408,17 @@ impl TimeSpec { /// `openvmm.snapshot.SnapshotCpuProfile`. #[derive(Debug, Clone)] -pub(super) struct CpuSpec { +pub(in crate::host) struct CpuSpec { /// Field 1. - pub(super) id: String, + pub(in crate::host) id: String, /// Field 2. - pub(super) digest: Vec, + pub(in crate::host) digest: Vec, /// Field 3. - pub(super) document: Vec, + pub(in crate::host) document: Vec, /// Field 4. - pub(super) effective_cpuid: Vec, + pub(in crate::host) effective_cpuid: Vec, /// Field 6. - pub(super) signature: u32, + pub(in crate::host) signature: u32, } impl CpuSpec { @@ -435,61 +435,61 @@ impl CpuSpec { /// `openvmm.snapshot.SnapshotMachineContract`. #[derive(Debug, Clone)] -pub(super) struct ContractSpec { +pub(in crate::host) struct ContractSpec { /// Field 1. - pub(super) machine_profile: String, + pub(in crate::host) machine_profile: String, /// Field 2. - pub(super) abi_version: u32, + pub(in crate::host) abi_version: u32, /// Field 3. - pub(super) source_hypervisor: String, + pub(in crate::host) source_hypervisor: String, /// Field 4. - pub(super) command_line: String, + pub(in crate::host) command_line: String, /// Field 5, or `None` for the SHA-256 digest of the command line. - pub(super) command_line_digest: Option>, + pub(in crate::host) command_line_digest: Option>, /// Field 6: each range's start, length, and file offset. - pub(super) memory_ranges: Vec<(u64, u64, u64)>, + pub(in crate::host) memory_ranges: Vec<(u64, u64, u64)>, /// Field 7: the sockets, the dies of each socket, the cores of each die, the threads of each /// core, and the APIC IDs. - pub(super) topology: (u32, u32, u32, u32, Vec), + pub(in crate::host) topology: (u32, u32, u32, u32, Vec), /// Field 8. - pub(super) devices: Vec, + pub(in crate::host) devices: Vec, /// Field 9. - pub(super) state_units: Vec, + pub(in crate::host) state_units: Vec, /// Field 10. - pub(super) attachments: Vec, + pub(in crate::host) attachments: Vec, /// Field 16. - pub(super) boot_layout_version: u32, + pub(in crate::host) boot_layout_version: u32, /// Field 18. - pub(super) network: Option, + pub(in crate::host) network: Option, /// Field 19: the encoded policy of an attached filesystem. - pub(super) filesystem: Option>, + pub(in crate::host) filesystem: Option>, /// Field 21. - pub(super) blocks: Vec, + pub(in crate::host) blocks: Vec, /// Field 22. - pub(super) filesystem_slot_version: u32, + pub(in crate::host) filesystem_slot_version: u32, /// Field 23. - pub(super) boot_online_vp_count: u32, + pub(in crate::host) boot_online_vp_count: u32, /// Field 24. - pub(super) interrupt_mode: String, + pub(in crate::host) interrupt_mode: String, /// Fields 25 and 26: the start and the length of the shared interrupt-status page. - pub(super) status_page: (u64, u64), + pub(in crate::host) status_page: (u64, u64), /// Field 27. - pub(super) expansion_version: u32, + pub(in crate::host) expansion_version: u32, /// Field 28. - pub(super) memory_capacity: u64, + pub(in crate::host) memory_capacity: u64, /// Field 29. - pub(super) memory_block_size: u64, + pub(in crate::host) memory_block_size: u64, /// Field 30: each range's start and length. - pub(super) expansion_ranges: Vec<(u64, u64)>, + pub(in crate::host) expansion_ranges: Vec<(u64, u64)>, /// Field 31. - pub(super) time: Option, + pub(in crate::host) time: Option, /// Field 32. - pub(super) cpu: Option, + pub(in crate::host) cpu: Option, } impl ContractSpec { /// Gives each device its index as its order. - pub(super) fn renumber(&mut self) { + pub(in crate::host) fn renumber(&mut self) { for (index, device) in self.devices.iter_mut().enumerate() { device.order = index as u32; } @@ -569,37 +569,37 @@ impl ContractSpec { /// `openvmm.snapshot.SnapshotManifest`. #[derive(Debug, Clone)] -pub(super) struct ManifestSpec { +pub(in crate::host) struct ManifestSpec { /// Field 1. - pub(super) version: u32, + pub(in crate::host) version: u32, /// Field 2: seconds and nanoseconds. - pub(super) created_at: (i64, i32), + pub(in crate::host) created_at: (i64, i32), /// Field 3. - pub(super) openvmm_version: String, + pub(in crate::host) openvmm_version: String, /// Field 4. - pub(super) memory_size: u64, + pub(in crate::host) memory_size: u64, /// Field 5. - pub(super) vp_count: u32, + pub(in crate::host) vp_count: u32, /// Field 6. - pub(super) page_size: u32, + pub(in crate::host) page_size: u32, /// Field 7. - pub(super) architecture: String, + pub(in crate::host) architecture: String, /// Field 8. - pub(super) state_size: u64, + pub(in crate::host) state_size: u64, /// Field 11. - pub(super) contract: Option, + pub(in crate::host) contract: Option, /// Field 12. - pub(super) magic: Vec, + pub(in crate::host) magic: Vec, /// Field 13. - pub(super) schema_version: u32, + pub(in crate::host) schema_version: u32, /// Field 14. - pub(super) root_type: String, + pub(in crate::host) root_type: String, /// Field 15. - pub(super) tier: String, + pub(in crate::host) tier: String, /// Field 16. - pub(super) restore_policy: String, + pub(in crate::host) restore_policy: String, /// Field 17. - pub(super) consumed_sections: u32, + pub(in crate::host) consumed_sections: u32, } /// The kernel command line of the template of [`ManifestSpec::template`]. @@ -615,7 +615,7 @@ impl ManifestSpec { /// Returns the manifest of a template: a KVM microVM of 2 processors, all online at boot, and /// 512 MiB of RAM, of a capacity of 2 GiB, with a `distro` of 1 GiB, a scratch of 64 MiB, the /// dormant filesystem slot, a console, a control console, and no NIC. - pub(super) fn template() -> Self { + pub(in crate::host) fn template() -> Self { let (pmio, mmio) = ("pmio", "mmio"); let platform = DeviceSpec::platform; let mut contract = ContractSpec { @@ -822,7 +822,7 @@ impl ManifestSpec { /// Returns the manifest of [`template`](Self::template) with a fixed NIC at `10.0.0.2/24`, /// with an IPv6 identity, under an allow-list policy. - pub(super) fn with_network() -> Self { + pub(in crate::host) fn with_network() -> Self { let mut spec = Self::template(); let contract = spec.contract(); contract.devices.insert( @@ -882,12 +882,12 @@ impl ManifestSpec { } /// Returns the machine contract. - pub(super) fn contract(&mut self) -> &mut ContractSpec { + pub(in crate::host) fn contract(&mut self) -> &mut ContractSpec { self.contract.as_mut().expect("the spec has a contract") } /// Returns the time contract. - pub(super) fn time(&mut self) -> &mut TimeSpec { + pub(in crate::host) fn time(&mut self) -> &mut TimeSpec { self.contract() .time .as_mut() @@ -895,7 +895,7 @@ impl ManifestSpec { } /// Returns the CPU profile record. - pub(super) fn cpu(&mut self) -> &mut CpuSpec { + pub(in crate::host) fn cpu(&mut self) -> &mut CpuSpec { self.contract() .cpu .as_mut() @@ -903,7 +903,7 @@ impl ManifestSpec { } /// Returns the fixed NIC. - pub(super) fn network(&mut self) -> &mut NetworkSpec { + pub(in crate::host) fn network(&mut self) -> &mut NetworkSpec { self.contract() .network .as_mut() @@ -911,7 +911,7 @@ impl ManifestSpec { } /// Encodes the manifest, with the fields of `extra` after the others. - pub(super) fn encode_with(&self, extra: Proto) -> Vec { + pub(in crate::host) fn encode_with(&self, extra: Proto) -> Vec { let (seconds, nanos) = self.created_at; // `mesh` writes an `i64` and an `i32` as varints of their two's complement in 64 bits. let created_at = Proto::default() @@ -941,18 +941,18 @@ impl ManifestSpec { } /// Encodes the manifest. - pub(super) fn encode(&self) -> Vec { + pub(in crate::host) fn encode(&self) -> Vec { self.encode_with(Proto::default()) } } /// Returns the artifact identity `sha256:` and 64 times `digit`. -pub(super) fn artifact(digit: char) -> ArtifactIdentity { +pub(in crate::host) fn artifact(digit: char) -> ArtifactIdentity { ArtifactIdentity::sha256(&digit.to_string().repeat(64)).unwrap() } /// Returns the class of the capture of [`ManifestSpec::template`]. -pub(super) fn class() -> CaptureClass { +pub(in crate::host) fn class() -> CaptureClass { CaptureClass { runtime: RuntimeIdentity::new(artifact('a'), artifact('b'), artifact('c')), guest_build: ArtifactIdentity::new("guest-build-1").unwrap(), @@ -978,7 +978,7 @@ pub(super) fn class() -> CaptureClass { } /// Returns the class of the capture of [`ManifestSpec::with_network`]. -pub(super) fn network_class() -> CaptureClass { +pub(in crate::host) fn network_class() -> CaptureClass { CaptureClass { network: Some( SandboxNetwork::new("10.0.0.2/24", NetworkPolicy::new(Access::Allow)).unwrap(), diff --git a/nvx-rs/src/host/template/wire.rs b/nvx-rs/src/host/snapshot/wire.rs similarity index 100% rename from nvx-rs/src/host/template/wire.rs rename to nvx-rs/src/host/snapshot/wire.rs diff --git a/nvx-rs/src/host/template/wire/tests.rs b/nvx-rs/src/host/snapshot/wire/tests.rs similarity index 100% rename from nvx-rs/src/host/template/wire/tests.rs rename to nvx-rs/src/host/snapshot/wire/tests.rs diff --git a/nvx-rs/src/host/template/clone/tests.rs b/nvx-rs/src/host/template/clone/tests.rs index e7bbdc651..62c98955b 100644 --- a/nvx-rs/src/host/template/clone/tests.rs +++ b/nvx-rs/src/host/template/clone/tests.rs @@ -27,12 +27,12 @@ use crate::host::sandbox::scratch::CLAIM_RELEASE_WAIT; use crate::host::sandbox::{SandboxDistro, SandboxNetwork, SandboxSettings, SandboxUpper}; use crate::host::seal::FileSeal; use crate::host::seal::tests::open_metadata_only; +use crate::host::snapshot::tests::{MIB, ManifestSpec, class, network_class}; use crate::host::store::{ CLONE_ACTIVATION_NAME, CLONE_BINDING_NAME, CLONE_SCRATCH_NAME, CallerFiles, LOG_NAME, SandboxStore, }; use crate::host::template::store::{CAPTURES_NAME, SNAPSHOT_NAME, TRANSACTION_NAME}; -use crate::host::template::tests::{MIB, ManifestSpec, class, network_class}; use crate::host::template::{CaptureClass, HostTime, KEY_NAME}; #[cfg(windows)] use crate::host::tests::junction; diff --git a/nvx-rs/src/host/template/clone/tests/launch.rs b/nvx-rs/src/host/template/clone/tests/launch.rs index ffe9849f0..c58043a4c 100644 --- a/nvx-rs/src/host/template/clone/tests/launch.rs +++ b/nvx-rs/src/host/template/clone/tests/launch.rs @@ -19,6 +19,7 @@ use crate::activation::{ReadyActivation, StoreGeneration, TransactionId}; use crate::host::artifacts; use crate::host::platform::Transport; use crate::host::process::{BootId, Process, ProcessRef}; +use crate::host::snapshot::tests::artifact; use crate::host::store::files::{sync_dir, write_private}; use crate::host::store::{ CLONE_ACTIVATION_NAME, CLONE_BINDING_NAME, CLONE_FAILURE_NAME, CLONE_PROGRESS_NAME, @@ -31,7 +32,6 @@ use crate::host::template::clone::launch::{Hooks, Point}; use crate::host::template::clone::reattach::{reattach_clone_syncing, reattach_clone_with}; use crate::host::template::clone::records::{read_failure, read_progress, write_failure}; use crate::host::template::store::tests::SNAPSHOT_ARTIFACTS; -use crate::host::template::tests::artifact; /// The environment variable that names the template store of a [`launch_role`]. const ROLE_STORE: &str = "NVX_CLONE_LAUNCH_TEST_STORE"; diff --git a/nvx-rs/src/host/template/mod.rs b/nvx-rs/src/host/template/mod.rs index 8bd161d34..298105cb1 100644 --- a/nvx-rs/src/host/template/mod.rs +++ b/nvx-rs/src/host/template/mod.rs @@ -64,35 +64,21 @@ //! what the clone's sandbox keeps of it, for the operations that list, inspect, or remove //! clones. //! -//! # Canonical encoding +//! # Snapshot metadata //! -//! A key and a class each have one canonical encoding, which [`TemplateKey::to_bytes`] and -//! [`CaptureClass::to_bytes`] write, and whose SHA-256 digest, after a domain of its own, is its -//! identity, a [`KeyIdentity`] or a [`ClassIdentity`]. The encoding starts with its version, and -//! each value in it has exactly one encoding: -//! -//! - An integer is its fixed number of little-endian bytes: one for a `u8`, two for a `u16`, four -//! for a `u32`, and eight for a `u64`. -//! - A boolean is one byte, 0 or 1. -//! - A byte string of fixed length, such as a digest or an address, is its bytes. -//! - A byte string of variable length is its length, a `u32`, then its bytes. A text is the byte -//! string of its UTF-8 encoding. -//! - An optional value is one byte: 0 without the value, and 1 before it. -//! - A list is its count, a `u32`, then its items in order. -//! -//! [`TemplateKey::from_bytes`] refuses any other encoding, and bytes left after it. The vectors in -//! `tests/vectors/template-key-v1.txt` fix version 1 of a key's encoding and of a class's. +//! The metadata types remain aliases of [`snapshot`](super::snapshot)'s types for template +//! users. That module describes their canonical encoding and conformance vectors. -mod canonical; mod clone; -mod eligibility; -mod key; -mod manifest; mod plan; mod store; -#[cfg(test)] -pub(crate) mod tests; -mod wire; + +pub use super::snapshot::{ + BlockGeometry, CaptureClass, ClassIdentity, Downtime, DowntimeSource, Eligibility, HostClock, + HostTime, Invariants, KeyIdentity, MANIFEST_NAME, MAX_DOWNTIME_NS, MAX_MANIFEST_LEN, + SnapshotKey as TemplateKey, SnapshotManifest as TemplateManifest, TimeContract, +}; +pub(super) use super::snapshot::{eligibility, key, manifest}; pub use self::clone::{ Activated, CloneControl, CloneFailure, ClonePlan, CloneRecords, CloneRequest, CloneUpper, @@ -100,13 +86,8 @@ pub use self::clone::{ READY_TO_START_TIMEOUT, RESTORE_READY_EVENT, RESTORE_TO_READY_TIMEOUT, ReattachedClone, RestoreDeadlines, Restoring, Stage, Started, Teardown, reattach_clone, status_evidence, }; -pub use self::eligibility::{Downtime, DowntimeSource, Eligibility, HostTime, MAX_DOWNTIME_NS}; -pub use self::key::{CaptureClass, ClassIdentity, Invariants, KeyIdentity, TemplateKey}; #[cfg(feature = "cli")] pub(crate) use self::manifest::read_attachments; -pub use self::manifest::{ - BlockGeometry, HostClock, MANIFEST_NAME, MAX_MANIFEST_LEN, TemplateManifest, TimeContract, -}; pub use self::plan::{MEMORY_BLOCK_SIZE, SCRATCH_NAME, TemplatePlan, TemplateResources}; pub use self::store::{ Acquired, CAPTURE_RECORD_NAME, CAPTURES_NAME, Capture, Created, GENERATIONS_NAME, Generation, diff --git a/nvx-rs/src/host/template/store/capture/tests.rs b/nvx-rs/src/host/template/store/capture/tests.rs index 02914db4b..b05b912d1 100644 --- a/nvx-rs/src/host/template/store/capture/tests.rs +++ b/nvx-rs/src/host/template/store/capture/tests.rs @@ -14,13 +14,13 @@ use serde_json::{Value, json}; use super::*; use crate::host::sandbox::distro::{DISTRO_POLICY_REVISION, PolicyVerdict}; use crate::host::sandbox::{SandboxDistro, SandboxUpper}; +use crate::host::snapshot::tests::{MIB, ManifestSpec, class, network_class}; use crate::host::store::{CallerFiles, JOURNAL_NAME, LaunchId}; use crate::host::template::eligibility::MAX_DOWNTIME_NS; use crate::host::template::store::Lease; use crate::host::template::store::tests::{ cause, link_dir, link_file, private_dir, publish_with, storage, store, }; -use crate::host::template::tests::{MIB, ManifestSpec, class, network_class}; use crate::protocol::root::RootImage; use crate::uuid::Uuid; diff --git a/nvx-rs/src/host/template/store/leases/tests.rs b/nvx-rs/src/host/template/store/leases/tests.rs index f8f573b48..1205e4ba3 100644 --- a/nvx-rs/src/host/template/store/leases/tests.rs +++ b/nvx-rs/src/host/template/store/leases/tests.rs @@ -16,6 +16,7 @@ use serde_json::{Value, json}; use super::*; use crate::activation::TemplateReference; use crate::host::process::{Process, ProcessRef}; +use crate::host::snapshot::tests::{ManifestSpec, artifact, network_class}; use crate::host::store::files::write_private; use crate::host::store::{ CLONE_ACTIVATION_NAME, CLONE_FAILURE_NAME, CLONE_PROGRESS_NAME, CLONE_SCRATCH_NAME, FORMAT, @@ -28,7 +29,6 @@ use crate::host::template::store::tests::{ cause, link_dir, link_file, publish, publish_with, remove, storage, store as new_store, unlink_dir, }; -use crate::host::template::tests::{ManifestSpec, artifact, network_class}; use crate::host::tests::released; use crate::protocol::CAPABILITY_LEN; diff --git a/nvx-rs/src/host/template/store/tests.rs b/nvx-rs/src/host/template/store/tests.rs index 2fa0fb136..59d2cb740 100644 --- a/nvx-rs/src/host/template/store/tests.rs +++ b/nvx-rs/src/host/template/store/tests.rs @@ -7,10 +7,10 @@ use std::sync::{Arc, Barrier, mpsc}; use serde_json::{Value, json}; use super::*; +use crate::host::snapshot::tests::{ManifestSpec, class}; use crate::host::template::MANIFEST_NAME; use crate::host::template::key::CaptureClass; use crate::host::template::manifest::TemplateManifest; -use crate::host::template::tests::{ManifestSpec, class}; #[cfg(any(target_os = "linux", windows))] pub(in crate::host::template) use super::capture::SNAPSHOT_ARTIFACTS; @@ -21,7 +21,7 @@ impl Store { pub(crate) fn publish_for_tests(&self) -> Generation { tests::publish( self, - &crate::host::template::tests::ManifestSpec::template(), + &crate::host::snapshot::tests::ManifestSpec::template(), tests::storage(1), ) } @@ -33,7 +33,7 @@ impl Store { pub(in crate::host::template) fn publish_spec_for_tests( &self, class: &crate::host::template::CaptureClass, - spec: &crate::host::template::tests::ManifestSpec, + spec: &crate::host::snapshot::tests::ManifestSpec, ) -> Generation { tests::publish_with(self, class, spec, tests::storage(1)) } diff --git a/nvx-rs/tests/vectors/README.md b/nvx-rs/tests/vectors/README.md index d8b5ffef8..23aec531a 100644 --- a/nvx-rs/tests/vectors/README.md +++ b/nvx-rs/tests/vectors/README.md @@ -12,7 +12,7 @@ yet breaks those peers. Only bytes that no codec produced catch such a change. | [`nvxc-v1.txt`](nvxc-v1.txt) | Version 1 of the control protocol: `NVXC` frames, their `EXEC`, `MAPS`, and features payloads, and `NVXS` records of NVX's host and guest | | [`nvxl-v1.txt`](nvxl-v1.txt) | Version 1 of the `NVXL` listener announcement | | [`activation-v2.txt`](activation-v2.txt) | Version 2 of the activation record of a layered root, and what Ready reports about an activation | -| [`template-key-v1.txt`](template-key-v1.txt) | Version 1 of the canonical encodings of a template's compatibility key and of a capture class, with their identities | +| [`snapshot-key-v1.txt`](snapshot-key-v1.txt) | Version 1 of the canonical encodings of a snapshot's compatibility key and of a capture class, with their identities | | [`openvmm/`](openvmm) | OpenVMM's vectors and cases of the `NVXS` session, and the excerpts of its sources that define the kernel command-line tokens of its platform tier and the error of a port forward that it cannot bind, unchanged | [4.4 Host-Guest Control Interface](../../../doc/design/4.4-host-guest-control-interface.md) @@ -23,7 +23,7 @@ describe the protocols, and the documentation of `nvx::activation`, in ## Line format -`nvxc-v1.txt`, `nvxl-v1.txt`, `activation-v2.txt`, and `template-key-v1.txt` +`nvxc-v1.txt`, `nvxl-v1.txt`, `activation-v2.txt`, and `snapshot-key-v1.txt` share one line format. A line that starts with `#` is a comment, and an empty line is ignored. Every other line is one vector, whose fields `|` separates: @@ -50,9 +50,9 @@ must encode the values to exactly its bytes. A kind whose name starts with `INVALID_` has no values: every decoder must refuse the bytes of its vectors. A key or a class holds too many values for one line, so the value of each -vector of `template-key-v1.txt` is its identity, and the file's header names +vector of `snapshot-key-v1.txt` is its identity, and the file's header names the captures whose keys and classes the vectors encode. The tests of -`nvx::host::template` derive each key from its capture, and check that it is +`nvx::host::snapshot` derive each key from its capture, and check that it is the key that the vector's bytes decode to. ## Rules @@ -61,18 +61,20 @@ the key that the vector's bytes decode to. its own, such as `nvxc-v2.txt` for the exec v2 of [microsoft/nvx#623](https://github.com/microsoft/nvx/issues/623), and the bytes of an earlier version that it refuses become its rejection vectors. - Version 1 has two exceptions. `MAPS|ROOT_SOURCE` of `nvxc-v1.txt` was the + Version 1 has three exceptions. `MAPS|ROOT_SOURCE` of `nvxc-v1.txt` was the rejection vector `INVALID_MAPS|EMPTY_SOURCE` until an empty source came to name the export's root, for a host whose export is one directory. NVX's hosts, whose exports are aggregates, send none, and a host whose export is one directory sends one only to a guest that deploys with it, so the C agent of earlier releases, which refuses it, never receives one. And `CLASS|NETWORK` of - `template-key-v1.txt` came to encode its network in place as the template + `snapshot-key-v1.txt` came to encode its network in place as the template captures it, under the complete deny-all policy: the encodings of a key and of a class have not been released, so a template store that an earlier build created is not supported, and is deleted and created again, since nothing - migrates it. + migrates it. The snapshot key also drops the obsolete guest-build field and + uses the `nvx snapshot key` hash domain in place: no snapshot outlives a + deployment, and the prior key encoding is not supported. - The bytes come from the protocol's definition, never from the code that they check, and so do the values of each vector. diff --git a/nvx-rs/tests/vectors/snapshot-key-v1.txt b/nvx-rs/tests/vectors/snapshot-key-v1.txt new file mode 100644 index 000000000..99ad0a9af --- /dev/null +++ b/nvx-rs/tests/vectors/snapshot-key-v1.txt @@ -0,0 +1,100 @@ +# Conformance vectors of version 1 of the canonical encodings of a snapshot's compatibility key, +# nvx::host::snapshot::SnapshotKey, and of a capture class, nvx::host::snapshot::CaptureClass, +# which the module nvx::host::snapshot describes. README.md describes the line format and the +# rules that the vectors follow. +# +# KEY|NAME|BYTES|IDENTITY +# The canonical encoding of a key, and its identity: the SHA-256 digest of "nvx snapshot key", a +# NUL byte, and the encoding. A decoder must decode the bytes, and an encoder must encode the key +# that they hold to the same bytes. +# CLASS|NAME|BYTES|IDENTITY +# The canonical encoding of a class, and its identity: the SHA-256 digest of "nvx capture class", +# a NUL byte, and the encoding. +# INVALID_KEY_VERSION|NAME|BYTES +# A key of another version of the encoding, which every decoder refuses as unsupported. +# INVALID_KEY|NAME|BYTES +# Bytes that every decoder of a key must refuse. +# +# The keys and classes are those of the captures that tests/fixtures/template/README.md +# describes, as microVM ABI 2 captured them, when every virtio device but the NIC also offered +# access-platform (feature bit 33), each console also offered its size (feature bit 0), and the +# virtio devices interrupted on ISA IRQs (the NIC on 10, the filesystem on 6, the consoles on 7 +# and 3, and the distro and scratch blocks on 4 and 11), with the OpenVMM, kernel, and initramfs +# identities sha256:a..., sha256:b..., and +# sha256:c..., boot contract 3, control contract +# nvx-microvm-v2-control-v2, control session 1, snapshot format 6, device-state schema 1, time +# ABI 1, restore packet 4, and activation contract 1. +# Capture classes alone also hold the guest build guest-build-1. +# The key of the template of a KVM microVM of 2 processors, all online at boot, and 512 MiB +# of RAM, of a capacity of 2 GiB, with a distro of 1 GiB, a scratch of 64 MiB, the dormant +# filesystem slot, a console, a control console, and no NIC, on the CPU profile +# intel.icelake-sp.v1, whose digest is 32 bytes of 5a and whose effective CPUID is the bytes +# 00 to 57: the capture of tests/fixtures/template/platform-kvm. +KEY|TEMPLATE|0100470000007368613235363a61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d7632010000000000000006000000000000000100000000000000010000000000000004000000000000000100000000000000030000006b766d05000000696e74656c0a0000006963656c616b652d7370010000005a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a58000000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f50515253545556570100000001000000020000000100000002000000000000000100000000752b7d0000000000c2eb0b00000000fa000000020000000000000000000020000000000000008000000000000000080000000001000000000000000000000000000020000000000100000000000020000000000000006000000000530100006561726c79636f6e3d78653920636f6e736f6c653d68766331207265626f6f743d742070616e69633d2d31206e76785f73616e64626f783d31206e76785f636f6e6669673d307864303031303030302c3635353336206e725f637075733d32206e76785f736e617073686f745f746965723d706c6174666f726d2076697274696f5f6d6d696f2e6465766963653d30783130303040307864303030313030303a362076697274696f5f6d6d696f2e6465766963653d30783130303040307864303030323030303a372076697274696f5f6d6d696f2e6465766963653d30783130303040307864303030333030303a342076697274696f5f6d6d696f2e6465766963653d30783130303040307864303030363030303a31312076697274696f5f6d6d696f2e6465766963653d30783130303040307864303030373030303a33206e76785f636f6e74726f6c5f7474793d6876633217f80f8858431ca75fcc7ca694ea68637e017ede02db15e18d0ed4581067858d000000400000000000020000001000000000000400000000000200000002000012000000656467652d7368617265642d737461747573000003000000000000100000000000001000000009000000706172746974696f6e09000000706172746974696f6e09000000706172746974696f6e00000000000000000000000000000000000000000003000000767030040000007663707509000000706172746974696f6e00000000000000000000000000000000000000000006000000766d74696d6505000000636c6f636b06000000766d74696d65000000000000000000000000000000000000000000030000007069630300000070696303000000706963000000000200000004000000706d696f2000000000000000020000000000000004000000706d696fa00000000000000002000000000000000000000000000000000000000006000000696f6170696306000000696f6170696306000000696f617069630000000001000000040000006d6d696f0000c0fe00000000001000000000000000000000000000000000000000050000006c61706963050000006c6170696309000000706172746974696f6e0000000001000000040000006d6d696f0000e0fe00000000001000000000000000000000000000000000000000030000007069740300000070697403000000706974000000000100000004000000706d696f400000000000000004000000000000000100000000000000000000000000000000030000007274630300000072746303000000727463000000000100000004000000706d696f7000000000000000020000000000000001080000000000000000000000000000000d0000006d6963726f766d2d706f72746205000000706f7274620d0000006d6963726f766d2d706f727462000000000100000004000000706d696fe900000000000000020000000000000000000000000000000000000000100000006d6963726f766d2d73687574646f776e0800000073687574646f776e100000006d6963726f766d2d73687574646f776e000000000100000004000000706d696f0406000000000000010000000000000000000000000000000000000000180000006d6963726f766d2d736e617073686f742d7265717565737410000000736e617073686f742d72657175657374180000006d6963726f766d2d736e617073686f742d72657175657374000000000100000004000000706d696f05060000000000000100000000000000000000000000000000000000000b00000066733a6d6963726f766d300900000076697274696f2d66731300000076697274696f66732d333438393636353032340b00000076697274696f2d6d6d696f01000000040000006d6d696f001000d000000000001000000000000001060000000200000000000030030000000200000002000000000100000001000017000000636f6e736f6c653a6d6963726f766d2d76697274696f300e00000076697274696f2d636f6e736f6c651900000076697274696f2d636f6e736f6c652d333438393636393132300b00000076697274696f2d6d6d696f01000000040000006d6d696f002000d000000000001000000000000001070000000200000001000030030000000200000002000000000100000001000012000000626c6b3a73616e64626f783a64697374726f0a00000076697274696f2d626c6b1500000076697274696f2d626c6b2d333438393637333231360b00000076697274696f2d6d6d696f01000000040000006d6d696f003000d0000000000010000000000000010400000002000000640600300300000001000000010000000001000013000000626c6b3a73616e64626f783a736372617463680a00000076697274696f2d626c6b1500000076697274696f2d626c6b2d333438393638353530340b00000076697274696f2d6d6d696f01000000040000006d6d696f006000d0000000000010000000000000010b00000002000000440600300300000001000000010000000001000018000000636f6e736f6c653a6d6963726f766d2d636f6e74726f6c301600000076697274696f2d636f6e74726f6c2d636f6e736f6c652100000076697274696f2d636f6e74726f6c2d636f6e736f6c652d333438393638393630300b00000076697274696f2d6d6d696f01000000040000006d6d696f007000d000000000001000000000000001030000000200000001000030030000000200000002000000000100000001000001000000070000006d6963726f766d0000000000|dc593980266a3bc96c177fbfb8fea08e958dc54609cdb07c988a33992d09aa32 +# The same with a fixed NIC at 10.0.0.2/24, with its IPv6 identity, under an allow-list +# policy whose digest is 32 bytes of 07, and the invariant settings isolation.seccomp=strict +# and limits.pids=512. +KEY|NETWORK|0100470000007368613235363a61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d7632010000000000000006000000000000000100000000000000010000000000000004000000000000000100000000000000030000006b766d05000000696e74656c0a0000006963656c616b652d7370010000005a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a58000000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f50515253545556570100000001000000020000000100000002000000000000000100000000752b7d0000000000c2eb0b00000000fa000000020000000000000000000020000000000000008000000000000000080000000001000000000000000000000000000020000000000100000000000020000000000000006000000000f20100006561726c79636f6e3d78653920636f6e736f6c653d68766331207265626f6f743d742070616e69633d2d31206e76785f73616e64626f783d31206e76785f636f6e6669673d307864303031303030302c3635353336206e725f637075733d32206e76785f736e617073686f745f746965723d706c6174666f726d2076697274696f5f6d6d696f2e6465766963653d30783130303040307864303030303030303a31302076697274696f5f6d6d696f2e6465766963653d30783130303040307864303030313030303a362076697274696f5f6d6d696f2e6465766963653d30783130303040307864303030323030303a372076697274696f5f6d6d696f2e6465766963653d30783130303040307864303030333030303a342076697274696f5f6d6d696f2e6465766963653d30783130303040307864303030363030303a31312076697274696f5f6d6d696f2e6465766963653d30783130303040307864303030373030303a33206e76785f636f6e74726f6c5f7474793d6876633220766972746e65745f69703d31302e302e302e3220766972746e65745f6d61736b3d3235352e3235352e3235352e3020766972746e65745f67773d31302e302e302e3120766972746e65745f6970363d666430303a3a6130303a322f31323020766972746e65745f6777363d666430303a3a6130303a315e7d49c200c9d60e74547b549917b665501635035894c15c2d7780210f95caf0000000400000000000020000001000000000000400000000000200000002000012000000656467652d7368617265642d737461747573000003000000000000100000000000001100000009000000706172746974696f6e09000000706172746974696f6e09000000706172746974696f6e00000000000000000000000000000000000000000003000000767030040000007663707509000000706172746974696f6e00000000000000000000000000000000000000000006000000766d74696d6505000000636c6f636b06000000766d74696d65000000000000000000000000000000000000000000030000007069630300000070696303000000706963000000000200000004000000706d696f2000000000000000020000000000000004000000706d696fa00000000000000002000000000000000000000000000000000000000006000000696f6170696306000000696f6170696306000000696f617069630000000001000000040000006d6d696f0000c0fe00000000001000000000000000000000000000000000000000050000006c61706963050000006c6170696309000000706172746974696f6e0000000001000000040000006d6d696f0000e0fe00000000001000000000000000000000000000000000000000030000007069740300000070697403000000706974000000000100000004000000706d696f400000000000000004000000000000000100000000000000000000000000000000030000007274630300000072746303000000727463000000000100000004000000706d696f7000000000000000020000000000000001080000000000000000000000000000000d0000006d6963726f766d2d706f72746205000000706f7274620d0000006d6963726f766d2d706f727462000000000100000004000000706d696fe900000000000000020000000000000000000000000000000000000000100000006d6963726f766d2d73687574646f776e0800000073687574646f776e100000006d6963726f766d2d73687574646f776e000000000100000004000000706d696f0406000000000000010000000000000000000000000000000000000000180000006d6963726f766d2d736e617073686f742d7265717565737410000000736e617073686f742d72657175657374180000006d6963726f766d2d736e617073686f742d72657175657374000000000100000004000000706d696f05060000000000000100000000000000000000000000000000000000000c0000006e65743a6d6963726f766d300a00000076697274696f2d6e65741500000076697274696f2d6e65742d333438393636303932380b00000076697274696f2d6d6d696f01000000040000006d6d696f000000d0000000000010000000000000010a000000020000002000000001000000020000000200000000010000000100000b00000066733a6d6963726f766d300900000076697274696f2d66731300000076697274696f66732d333438393636353032340b00000076697274696f2d6d6d696f01000000040000006d6d696f001000d000000000001000000000000001060000000200000000000030030000000200000002000000000100000001000017000000636f6e736f6c653a6d6963726f766d2d76697274696f300e00000076697274696f2d636f6e736f6c651900000076697274696f2d636f6e736f6c652d333438393636393132300b00000076697274696f2d6d6d696f01000000040000006d6d696f002000d000000000001000000000000001070000000200000001000030030000000200000002000000000100000001000012000000626c6b3a73616e64626f783a64697374726f0a00000076697274696f2d626c6b1500000076697274696f2d626c6b2d333438393637333231360b00000076697274696f2d6d6d696f01000000040000006d6d696f003000d0000000000010000000000000010400000002000000640600300300000001000000010000000001000013000000626c6b3a73616e64626f783a736372617463680a00000076697274696f2d626c6b1500000076697274696f2d626c6b2d333438393638353530340b00000076697274696f2d6d6d696f01000000040000006d6d696f006000d0000000000010000000000000010b00000002000000440600300300000001000000010000000001000018000000636f6e736f6c653a6d6963726f766d2d636f6e74726f6c301600000076697274696f2d636f6e74726f6c2d636f6e736f6c652100000076697274696f2d636f6e74726f6c2d636f6e736f6c652d333438393638393630300b00000076697274696f2d6d6d696f01000000040000006d6d696f007000d000000000001000000000000001030000000200000001000030030000000200000002000000000100000001000001000000070000006d6963726f766d0108000000706f727461626c655254000000025254000000010a000002180a00000101fd00000000000000000000000a00000278fd00000000000000000000000a0000010a000000616c6c6f772d6c69737407070707070707070707070707070707070707070707070707070707070707070104000000020000001100000069736f6c6174696f6e2e736563636f6d70060000007374726963740b0000006c696d6974732e7069647303000000353132|af73b6bf51095c0c2ab84fb114bfa63d3e0dc1fd2b6f56f9a729391e19c762f9 +# TEMPLATE on the host profile intel.host.v1. +KEY|HOST_PROFILE|0100470000007368613235363a61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d7632010000000000000006000000000000000100000000000000010000000000000004000000000000000100000000000000030000006b766d05000000696e74656c04000000686f7374010000005a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a58000000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f50515253545556570100000001000000020000000100000002000000000000000100000000752b7d0000000000c2eb0b00000000fa000000020000000000000000000020000000000000008000000000000000080000000001000000000000000000000000000020000000000100000000000020000000000000006000000000530100006561726c79636f6e3d78653920636f6e736f6c653d68766331207265626f6f743d742070616e69633d2d31206e76785f73616e64626f783d31206e76785f636f6e6669673d307864303031303030302c3635353336206e725f637075733d32206e76785f736e617073686f745f746965723d706c6174666f726d2076697274696f5f6d6d696f2e6465766963653d30783130303040307864303030313030303a362076697274696f5f6d6d696f2e6465766963653d30783130303040307864303030323030303a372076697274696f5f6d6d696f2e6465766963653d30783130303040307864303030333030303a342076697274696f5f6d6d696f2e6465766963653d30783130303040307864303030363030303a31312076697274696f5f6d6d696f2e6465766963653d30783130303040307864303030373030303a33206e76785f636f6e74726f6c5f7474793d6876633217f80f8858431ca75fcc7ca694ea68637e017ede02db15e18d0ed4581067858d000000400000000000020000001000000000000400000000000200000002000012000000656467652d7368617265642d737461747573000003000000000000100000000000001000000009000000706172746974696f6e09000000706172746974696f6e09000000706172746974696f6e00000000000000000000000000000000000000000003000000767030040000007663707509000000706172746974696f6e00000000000000000000000000000000000000000006000000766d74696d6505000000636c6f636b06000000766d74696d65000000000000000000000000000000000000000000030000007069630300000070696303000000706963000000000200000004000000706d696f2000000000000000020000000000000004000000706d696fa00000000000000002000000000000000000000000000000000000000006000000696f6170696306000000696f6170696306000000696f617069630000000001000000040000006d6d696f0000c0fe00000000001000000000000000000000000000000000000000050000006c61706963050000006c6170696309000000706172746974696f6e0000000001000000040000006d6d696f0000e0fe00000000001000000000000000000000000000000000000000030000007069740300000070697403000000706974000000000100000004000000706d696f400000000000000004000000000000000100000000000000000000000000000000030000007274630300000072746303000000727463000000000100000004000000706d696f7000000000000000020000000000000001080000000000000000000000000000000d0000006d6963726f766d2d706f72746205000000706f7274620d0000006d6963726f766d2d706f727462000000000100000004000000706d696fe900000000000000020000000000000000000000000000000000000000100000006d6963726f766d2d73687574646f776e0800000073687574646f776e100000006d6963726f766d2d73687574646f776e000000000100000004000000706d696f0406000000000000010000000000000000000000000000000000000000180000006d6963726f766d2d736e617073686f742d7265717565737410000000736e617073686f742d72657175657374180000006d6963726f766d2d736e617073686f742d72657175657374000000000100000004000000706d696f05060000000000000100000000000000000000000000000000000000000b00000066733a6d6963726f766d300900000076697274696f2d66731300000076697274696f66732d333438393636353032340b00000076697274696f2d6d6d696f01000000040000006d6d696f001000d000000000001000000000000001060000000200000000000030030000000200000002000000000100000001000017000000636f6e736f6c653a6d6963726f766d2d76697274696f300e00000076697274696f2d636f6e736f6c651900000076697274696f2d636f6e736f6c652d333438393636393132300b00000076697274696f2d6d6d696f01000000040000006d6d696f002000d000000000001000000000000001070000000200000001000030030000000200000002000000000100000001000012000000626c6b3a73616e64626f783a64697374726f0a00000076697274696f2d626c6b1500000076697274696f2d626c6b2d333438393637333231360b00000076697274696f2d6d6d696f01000000040000006d6d696f003000d0000000000010000000000000010400000002000000640600300300000001000000010000000001000013000000626c6b3a73616e64626f783a736372617463680a00000076697274696f2d626c6b1500000076697274696f2d626c6b2d333438393638353530340b00000076697274696f2d6d6d696f01000000040000006d6d696f006000d0000000000010000000000000010b00000002000000440600300300000001000000010000000001000018000000636f6e736f6c653a6d6963726f766d2d636f6e74726f6c301600000076697274696f2d636f6e74726f6c2d636f6e736f6c652100000076697274696f2d636f6e74726f6c2d636f6e736f6c652d333438393638393630300b00000076697274696f2d6d6d696f01000000040000006d6d696f007000d000000000001000000000000001030000000200000001000030030000000200000002000000000100000001000001000000070000006d6963726f766d0000000000|35f14fb1b596b299a43751b7827b7e7b88bc5cd330ff0d8eae2ee40b3d7e0fc2 +# A machine of one processor and one device, and no NIC, which the invalid vectors change. +KEY|MINIMAL|0100470000007368613235363a61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d7632010000000000000006000000000000000100000000000000010000000000000004000000000000000100000000000000030000006b766d03000000616d640500000067656e6f610100000011111111111111111111111111111111111111111111111111111111111111112c000000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b01000000010000000100000001000000010000000000000000ca9a3b0000000000e1f505000000000000000001000000000000000000000800000000000000080000000000000008000000000100000000000000000000000000000800000000000000000c000000636f6e736f6c653d687663308c7f813b328f96bdb26c4e97b6f5c874cbd968e8664778addc56a7c81ea55113001000000000000000020000000200000010000000000000000200000002000012000000656467652d7368617265642d737461747573000003000000000000100000000000000100000009000000706172746974696f6e09000000706172746974696f6e09000000706172746974696f6e00000000000000000000000000000000000000000001000000070000006d6963726f766d0000000000|9adf5b7b4c5509968914b0cae4664263c768bab0e8e010616b562b0023331d64 + +# The class of the capture of TEMPLATE: the CPU profile auto, and 2 processors, all online at +# boot. +CLASS|TEMPLATE|0100470000007368613235363a61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d763201000000000000000d00000067756573742d6275696c642d3106000000000000000100000000000000010000000000000004000000000000000100000000000000030000006b766d040000006175746f02000000020000000000002000000000000000800000000000000040000000000002000000100000000000040000000000020000000200000000000000000000|b53b0169db5d983b31f24bec900cd0b962d26f12480d90803f21ae1d5c3ff334 +# The class of the capture of NETWORK, whose NIC the capture attaches under the complete +# deny-all policy, whatever the policy of the class's network, here one that allows egress. +CLASS|NETWORK|0100470000007368613235363a61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d763201000000000000000d00000067756573742d6275696c642d3106000000000000000100000000000000010000000000000004000000000000000100000000000000030000006b766d040000006175746f02000000020000000000002000000000000000800000000000000040000000000002000000100000000000040000000000020000000200000a000000050000002d2d6e65740b00000031302e302e302e322f3234110000002d2d6e6574776f726b2d70726f66696c6508000000706f727461626c65100000002d2d6e6574776f726b2d6567726573730400000064656e79110000002d2d6e6574776f726b2d696e67726573730400000064656e790f0000002d2d686f73742d6c6f6f706261636b0400000064656e79020000001100000069736f6c6174696f6e2e736563636f6d70060000007374726963740b0000006c696d6974732e7069647303000000353132|2f32edae7e9eb532625af600232c68aa78b92e02c8116cb49f857f13ff5fcc7c + +# MINIMAL in other versions of the encoding. +INVALID_KEY_VERSION|VERSION_0|0000470000007368613235363a61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d7632010000000000000006000000000000000100000000000000010000000000000004000000000000000100000000000000030000006b766d03000000616d640500000067656e6f610100000011111111111111111111111111111111111111111111111111111111111111112c000000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b01000000010000000100000001000000010000000000000000ca9a3b0000000000e1f505000000000000000001000000000000000000000800000000000000080000000000000008000000000100000000000000000000000000000800000000000000000c000000636f6e736f6c653d687663308c7f813b328f96bdb26c4e97b6f5c874cbd968e8664778addc56a7c81ea55113001000000000000000020000000200000010000000000000000200000002000012000000656467652d7368617265642d737461747573000003000000000000100000000000000100000009000000706172746974696f6e09000000706172746974696f6e09000000706172746974696f6e00000000000000000000000000000000000000000001000000070000006d6963726f766d0000000000 +INVALID_KEY_VERSION|VERSION_2|0200470000007368613235363a61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d7632010000000000000006000000000000000100000000000000010000000000000004000000000000000100000000000000030000006b766d03000000616d640500000067656e6f610100000011111111111111111111111111111111111111111111111111111111111111112c000000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b01000000010000000100000001000000010000000000000000ca9a3b0000000000e1f505000000000000000001000000000000000000000800000000000000080000000000000008000000000100000000000000000000000000000800000000000000000c000000636f6e736f6c653d687663308c7f813b328f96bdb26c4e97b6f5c874cbd968e8664778addc56a7c81ea55113001000000000000000020000000200000010000000000000000200000002000012000000656467652d7368617265642d737461747573000003000000000000100000000000000100000009000000706172746974696f6e09000000706172746974696f6e09000000706172746974696f6e00000000000000000000000000000000000000000001000000070000006d6963726f766d0000000000 +INVALID_KEY_VERSION|VERSION_65535|ffff470000007368613235363a61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d7632010000000000000006000000000000000100000000000000010000000000000004000000000000000100000000000000030000006b766d03000000616d640500000067656e6f610100000011111111111111111111111111111111111111111111111111111111111111112c000000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b01000000010000000100000001000000010000000000000000ca9a3b0000000000e1f505000000000000000001000000000000000000000800000000000000080000000000000008000000000100000000000000000000000000000800000000000000000c000000636f6e736f6c653d687663308c7f813b328f96bdb26c4e97b6f5c874cbd968e8664778addc56a7c81ea55113001000000000000000020000000200000010000000000000000200000002000012000000656467652d7368617265642d737461747573000003000000000000100000000000000100000009000000706172746974696f6e09000000706172746974696f6e09000000706172746974696f6e00000000000000000000000000000000000000000001000000070000006d6963726f766d0000000000 + +# No bytes. +INVALID_KEY|EMPTY| +# MINIMAL without its last byte. +INVALID_KEY|TRUNCATED|0100470000007368613235363a61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d7632010000000000000006000000000000000100000000000000010000000000000004000000000000000100000000000000030000006b766d03000000616d640500000067656e6f610100000011111111111111111111111111111111111111111111111111111111111111112c000000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b01000000010000000100000001000000010000000000000000ca9a3b0000000000e1f505000000000000000001000000000000000000000800000000000000080000000000000008000000000100000000000000000000000000000800000000000000000c000000636f6e736f6c653d687663308c7f813b328f96bdb26c4e97b6f5c874cbd968e8664778addc56a7c81ea55113001000000000000000020000000200000010000000000000000200000002000012000000656467652d7368617265642d737461747573000003000000000000100000000000000100000009000000706172746974696f6e09000000706172746974696f6e09000000706172746974696f6e00000000000000000000000000000000000000000001000000070000006d6963726f766d00000000 +# MINIMAL and a byte after it. +INVALID_KEY|TRAILING_BYTE|0100470000007368613235363a61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d7632010000000000000006000000000000000100000000000000010000000000000004000000000000000100000000000000030000006b766d03000000616d640500000067656e6f610100000011111111111111111111111111111111111111111111111111111111111111112c000000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b01000000010000000100000001000000010000000000000000ca9a3b0000000000e1f505000000000000000001000000000000000000000800000000000000080000000000000008000000000100000000000000000000000000000800000000000000000c000000636f6e736f6c653d687663308c7f813b328f96bdb26c4e97b6f5c874cbd968e8664778addc56a7c81ea55113001000000000000000020000000200000010000000000000000200000002000012000000656467652d7368617265642d737461747573000003000000000000100000000000000100000009000000706172746974696f6e09000000706172746974696f6e09000000706172746974696f6e00000000000000000000000000000000000000000001000000070000006d6963726f766d000000000000 +# A command line whose digest does not match it. +INVALID_KEY|COMMAND_LINE_DIGEST|0100470000007368613235363a61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d7632010000000000000006000000000000000100000000000000010000000000000004000000000000000100000000000000030000006b766d03000000616d640500000067656e6f610100000011111111111111111111111111111111111111111111111111111111111111112c000000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b01000000010000000100000001000000010000000000000000ca9a3b0000000000e1f505000000000000000001000000000000000000000800000000000000080000000000000008000000000100000000000000000000000000000800000000000000000c000000636f6e736f6c653d687663300000000000000000000000000000000000000000000000000000000000000000001000000000000000020000000200000010000000000000000200000002000012000000656467652d7368617265642d737461747573000003000000000000100000000000000100000009000000706172746974696f6e09000000706172746974696f6e09000000706172746974696f6e00000000000000000000000000000000000000000001000000070000006d6963726f766d0000000000 +# A backend that does not exist. +INVALID_KEY|UNKNOWN_BACKEND|0100470000007368613235363a61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d76320100000000000000060000000000000001000000000000000100000000000000040000000000000001000000000000000300000078656e03000000616d640500000067656e6f610100000011111111111111111111111111111111111111111111111111111111111111112c000000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b01000000010000000100000001000000010000000000000000ca9a3b0000000000e1f505000000000000000001000000000000000000000800000000000000080000000000000008000000000100000000000000000000000000000800000000000000000c000000636f6e736f6c653d687663308c7f813b328f96bdb26c4e97b6f5c874cbd968e8664778addc56a7c81ea55113001000000000000000020000000200000010000000000000000200000002000012000000656467652d7368617265642d737461747573000003000000000000100000000000000100000009000000706172746974696f6e09000000706172746974696f6e09000000706172746974696f6e00000000000000000000000000000000000000000001000000070000006d6963726f766d0000000000 +# A device range of an address space that does not exist. +INVALID_KEY|UNKNOWN_ADDRESS_SPACE|0100470000007368613235363a61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d7632010000000000000006000000000000000100000000000000010000000000000004000000000000000100000000000000030000006b766d03000000616d640500000067656e6f610100000011111111111111111111111111111111111111111111111111111111111111112c000000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b01000000010000000100000001000000010000000000000000ca9a3b0000000000e1f505000000000000000001000000000000000000000800000000000000080000000000000008000000000100000000000000000000000000000800000000000000000c000000636f6e736f6c653d687663308c7f813b328f96bdb26c4e97b6f5c874cbd968e8664778addc56a7c81ea55113001000000000000000020000000200000010000000000000000200000002000012000000656467652d7368617265642d737461747573000003000000000000100000000000000100000009000000706172746974696f6e09000000706172746974696f6e09000000706172746974696f6e000000000100000004000000706f7274200000000000000002000000000000000000000000000000000000000001000000070000006d6963726f766d0000000000 +# An interrupt delivery mode that is not UTF-8. +INVALID_KEY|INTERRUPT_MODE_NOT_UTF8|0100470000007368613235363a61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d7632010000000000000006000000000000000100000000000000010000000000000004000000000000000100000000000000030000006b766d03000000616d640500000067656e6f610100000011111111111111111111111111111111111111111111111111111111111111112c000000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b01000000010000000100000001000000010000000000000000ca9a3b0000000000e1f505000000000000000001000000000000000000000800000000000000080000000000000008000000000100000000000000000000000000000800000000000000000c000000636f6e736f6c653d687663308c7f813b328f96bdb26c4e97b6f5c874cbd968e8664778addc56a7c81ea55113001000000000000000020000000200000010000000000000000200000002000013000000656467652d7368617265642dff737461747573000003000000000000100000000000000100000009000000706172746974696f6e09000000706172746974696f6e09000000706172746974696f6e00000000000000000000000000000000000000000001000000070000006d6963726f766d0000000000 +# A NIC whose presence tag is 2. +INVALID_KEY|PRESENCE_TAG_2|0100470000007368613235363a61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d7632010000000000000006000000000000000100000000000000010000000000000004000000000000000100000000000000030000006b766d03000000616d640500000067656e6f610100000011111111111111111111111111111111111111111111111111111111111111112c000000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b01000000010000000100000001000000010000000000000000ca9a3b0000000000e1f505000000000000000001000000000000000000000800000000000000080000000000000008000000000100000000000000000000000000000800000000000000000c000000636f6e736f6c653d687663308c7f813b328f96bdb26c4e97b6f5c874cbd968e8664778addc56a7c81ea55113001000000000000000020000000200000010000000000000000200000002000012000000656467652d7368617265642d737461747573000003000000000000100000000000000100000009000000706172746974696f6e09000000706172746974696f6e09000000706172746974696f6e00000000000000000000000000000000000000000001000000070000006d6963726f766d0200000000 +# A NIC whose policy's enforcement is 2. +INVALID_KEY|BOOLEAN_2|0100470000007368613235363a61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d7632010000000000000006000000000000000100000000000000010000000000000004000000000000000100000000000000030000006b766d03000000616d640500000067656e6f610100000011111111111111111111111111111111111111111111111111111111111111112c000000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b01000000010000000100000001000000010000000000000000ca9a3b0000000000e1f505000000000000000001000000000000000000000800000000000000080000000000000008000000000100000000000000000000000000000800000000000000000c000000636f6e736f6c653d687663308c7f813b328f96bdb26c4e97b6f5c874cbd968e8664778addc56a7c81ea55113001000000000000000020000000200000010000000000000000200000002000012000000656467652d7368617265642d737461747573000003000000000000100000000000000100000009000000706172746974696f6e09000000706172746974696f6e09000000706172746974696f6e00000000000000000000000000000000000000000001000000070000006d6963726f766d0108000000706f727461626c655254000000025254000000010a000002180a00000101fd00000000000000000000000a00000278fd00000000000000000000000a0000010a000000616c6c6f772d6c6973740707070707070707070707070707070707070707070707070707070707070707020400000000000000 +# Invariant settings out of the order of their names. +INVALID_KEY|UNSORTED_SETTINGS|0100470000007368613235363a61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d7632010000000000000006000000000000000100000000000000010000000000000004000000000000000100000000000000030000006b766d03000000616d640500000067656e6f610100000011111111111111111111111111111111111111111111111111111111111111112c000000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b01000000010000000100000001000000010000000000000000ca9a3b0000000000e1f505000000000000000001000000000000000000000800000000000000080000000000000008000000000100000000000000000000000000000800000000000000000c000000636f6e736f6c653d687663308c7f813b328f96bdb26c4e97b6f5c874cbd968e8664778addc56a7c81ea55113001000000000000000020000000200000010000000000000000200000002000012000000656467652d7368617265642d737461747573000003000000000000100000000000000100000009000000706172746974696f6e09000000706172746974696f6e09000000706172746974696f6e00000000000000000000000000000000000000000001000000070000006d6963726f766d00020000000b0000006c696d6974732e70696473030000003531321100000069736f6c6174696f6e2e736563636f6d7006000000737472696374 +# An invariant setting named twice. +INVALID_KEY|DUPLICATE_SETTINGS|0100470000007368613235363a61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d7632010000000000000006000000000000000100000000000000010000000000000004000000000000000100000000000000030000006b766d03000000616d640500000067656e6f610100000011111111111111111111111111111111111111111111111111111111111111112c000000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b01000000010000000100000001000000010000000000000000ca9a3b0000000000e1f505000000000000000001000000000000000000000800000000000000080000000000000008000000000100000000000000000000000000000800000000000000000c000000636f6e736f6c653d687663308c7f813b328f96bdb26c4e97b6f5c874cbd968e8664778addc56a7c81ea55113001000000000000000020000000200000010000000000000000200000002000012000000656467652d7368617265642d737461747573000003000000000000100000000000000100000009000000706172746974696f6e09000000706172746974696f6e09000000706172746974696f6e00000000000000000000000000000000000000000001000000070000006d6963726f766d00020000000b0000006c696d6974732e70696473030000003531320b0000006c696d6974732e7069647303000000353132 +# An invariant setting whose name holds an uppercase letter. +INVALID_KEY|UPPERCASE_SETTING|0100470000007368613235363a61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d7632010000000000000006000000000000000100000000000000010000000000000004000000000000000100000000000000030000006b766d03000000616d640500000067656e6f610100000011111111111111111111111111111111111111111111111111111111111111112c000000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b01000000010000000100000001000000010000000000000000ca9a3b0000000000e1f505000000000000000001000000000000000000000800000000000000080000000000000008000000000100000000000000000000000000000800000000000000000c000000636f6e736f6c653d687663308c7f813b328f96bdb26c4e97b6f5c874cbd968e8664778addc56a7c81ea55113001000000000000000020000000200000010000000000000000200000002000012000000656467652d7368617265642d737461747573000003000000000000100000000000000100000009000000706172746974696f6e09000000706172746974696f6e09000000706172746974696f6e00000000000000000000000000000000000000000001000000070000006d6963726f766d00010000000b0000004c696d6974732e7069647303000000353132 +# More APIC IDs than a microVM has processors. +INVALID_KEY|TOO_MANY_APIC_IDS|0100470000007368613235363a61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d7632010000000000000006000000000000000100000000000000010000000000000004000000000000000100000000000000030000006b766d03000000616d640500000067656e6f610100000011111111111111111111111111111111111111111111111111111111111111112c000000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b010000000100000001000000010000000900000000000000010000000200000003000000040000000500000006000000070000000800000000ca9a3b0000000000e1f505000000000000000001000000000000000000000800000000000000080000000000000008000000000100000000000000000000000000000800000000000000000c000000636f6e736f6c653d687663308c7f813b328f96bdb26c4e97b6f5c874cbd968e8664778addc56a7c81ea55113001000000000000000020000000200000010000000000000000200000002000012000000656467652d7368617265642d737461747573000003000000000000100000000000000100000009000000706172746974696f6e09000000706172746974696f6e09000000706172746974696f6e00000000000000000000000000000000000000000001000000070000006d6963726f766d0000000000 +# 3 processors, which a microVM cannot have. +INVALID_KEY|THREE_PROCESSORS|0100470000007368613235363a61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d7632010000000000000006000000000000000100000000000000010000000000000004000000000000000100000000000000030000006b766d03000000616d640500000067656e6f610100000011111111111111111111111111111111111111111111111111111111111111112c000000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b010000000100000003000000010000000300000000000000010000000200000000ca9a3b0000000000e1f505000000000000000003000000000000000000000800000000000000080000000000000008000000000100000000000000000000000000000800000000000000000c000000636f6e736f6c653d687663308c7f813b328f96bdb26c4e97b6f5c874cbd968e8664778addc56a7c81ea55113001000000000000000020000000200000010000000000000000200000002000012000000656467652d7368617265642d737461747573000003000000000000100000000000000100000009000000706172746974696f6e09000000706172746974696f6e09000000706172746974696f6e00000000000000000000000000000000000000000001000000070000006d6963726f766d0000000000 +# RAM ranges that do not hold the RAM. +INVALID_KEY|MEMORY_RANGES|0100470000007368613235363a61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d7632010000000000000006000000000000000100000000000000010000000000000004000000000000000100000000000000030000006b766d03000000616d640500000067656e6f610100000011111111111111111111111111111111111111111111111111111111111111112c000000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b01000000010000000100000001000000010000000000000000ca9a3b0000000000e1f505000000000000000001000000000000000000000800000000000000080000000000000008000000000100000000000000000000000000000400000000000000000c000000636f6e736f6c653d687663308c7f813b328f96bdb26c4e97b6f5c874cbd968e8664778addc56a7c81ea55113001000000000000000020000000200000010000000000000000200000002000012000000656467652d7368617265642d737461747573000003000000000000100000000000000100000009000000706172746974696f6e09000000706172746974696f6e09000000706172746974696f6e00000000000000000000000000000000000000000001000000070000006d6963726f766d0000000000 +# A machine without devices. +INVALID_KEY|NO_DEVICES|0100470000007368613235363a61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d7632010000000000000006000000000000000100000000000000010000000000000004000000000000000100000000000000030000006b766d03000000616d640500000067656e6f610100000011111111111111111111111111111111111111111111111111111111111111112c000000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b01000000010000000100000001000000010000000000000000ca9a3b0000000000e1f505000000000000000001000000000000000000000800000000000000080000000000000008000000000100000000000000000000000000000800000000000000000c000000636f6e736f6c653d687663308c7f813b328f96bdb26c4e97b6f5c874cbd968e8664778addc56a7c81ea55113001000000000000000020000000200000010000000000000000200000002000012000000656467652d7368617265642d737461747573000003000000000000100000000000000000000001000000070000006d6963726f766d0000000000 +# A device ID twice. +INVALID_KEY|DUPLICATE_DEVICE|0100470000007368613235363a61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d7632010000000000000006000000000000000100000000000000010000000000000004000000000000000100000000000000030000006b766d03000000616d640500000067656e6f610100000011111111111111111111111111111111111111111111111111111111111111112c000000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b01000000010000000100000001000000010000000000000000ca9a3b0000000000e1f505000000000000000001000000000000000000000800000000000000080000000000000008000000000100000000000000000000000000000800000000000000000c000000636f6e736f6c653d687663308c7f813b328f96bdb26c4e97b6f5c874cbd968e8664778addc56a7c81ea55113001000000000000000020000000200000010000000000000000200000002000012000000656467652d7368617265642d737461747573000003000000000000100000000000000200000009000000706172746974696f6e09000000706172746974696f6e09000000706172746974696f6e00000000000000000000000000000000000000000009000000706172746974696f6e05000000636c6f636b06000000766d74696d6500000000000000000000000000000000000000000001000000070000006d6963726f766d0000000000 +# A filesystem slot that is not the dormant slot of version 1. +INVALID_KEY|SLOT_VERSION_0|0100470000007368613235363a61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d7632010000000000000006000000000000000100000000000000010000000000000004000000000000000100000000000000030000006b766d03000000616d640500000067656e6f610100000011111111111111111111111111111111111111111111111111111111111111112c000000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b01000000010000000100000001000000010000000000000000ca9a3b0000000000e1f505000000000000000001000000000000000000000800000000000000080000000000000008000000000100000000000000000000000000000800000000000000000c000000636f6e736f6c653d687663308c7f813b328f96bdb26c4e97b6f5c874cbd968e8664778addc56a7c81ea55113001000000000000000020000000200000010000000000000000200000002000012000000656467652d7368617265642d737461747573000003000000000000100000000000000100000009000000706172746974696f6e09000000706172746974696f6e09000000706172746974696f6e00000000000000000000000000000000000000000000000000070000006d6963726f766d0000000000 +# A filesystem slot without a tag. +INVALID_KEY|EMPTY_TAG|0100470000007368613235363a61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d7632010000000000000006000000000000000100000000000000010000000000000004000000000000000100000000000000030000006b766d03000000616d640500000067656e6f610100000011111111111111111111111111111111111111111111111111111111111111112c000000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b01000000010000000100000001000000010000000000000000ca9a3b0000000000e1f505000000000000000001000000000000000000000800000000000000080000000000000008000000000100000000000000000000000000000800000000000000000c000000636f6e736f6c653d687663308c7f813b328f96bdb26c4e97b6f5c874cbd968e8664778addc56a7c81ea55113001000000000000000020000000200000010000000000000000200000002000012000000656467652d7368617265642d737461747573000003000000000000100000000000000100000009000000706172746974696f6e09000000706172746974696f6e09000000706172746974696f6e00000000000000000000000000000000000000000001000000000000000000000000 +# A distro whose logical block size is 256. +INVALID_KEY|DISTRO_BLOCK_SIZE|0100470000007368613235363a61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d7632010000000000000006000000000000000100000000000000010000000000000004000000000000000100000000000000030000006b766d03000000616d640500000067656e6f610100000011111111111111111111111111111111111111111111111111111111111111112c000000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b01000000010000000100000001000000010000000000000000ca9a3b0000000000e1f505000000000000000001000000000000000000000800000000000000080000000000000008000000000100000000000000000000000000000800000000000000000c000000636f6e736f6c653d687663308c7f813b328f96bdb26c4e97b6f5c874cbd968e8664778addc56a7c81ea55113001000000000000000010000000200000010000000000000000200000002000012000000656467652d7368617265642d737461747573000003000000000000100000000000000100000009000000706172746974696f6e09000000706172746974696f6e09000000706172746974696f6e00000000000000000000000000000000000000000001000000070000006d6963726f766d0000000000 +# An OpenVMM identity that holds a space. +INVALID_KEY|ARTIFACT_WITH_SPACE|0100470000007368613235363a20616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d7632010000000000000006000000000000000100000000000000010000000000000004000000000000000100000000000000030000006b766d03000000616d640500000067656e6f610100000011111111111111111111111111111111111111111111111111111111111111112c000000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b01000000010000000100000001000000010000000000000000ca9a3b0000000000e1f505000000000000000001000000000000000000000800000000000000080000000000000008000000000100000000000000000000000000000800000000000000000c000000636f6e736f6c653d687663308c7f813b328f96bdb26c4e97b6f5c874cbd968e8664778addc56a7c81ea55113001000000000000000020000000200000010000000000000000200000002000012000000656467652d7368617265642d737461747573000003000000000000100000000000000100000009000000706172746974696f6e09000000706172746974696f6e09000000706172746974696f6e00000000000000000000000000000000000000000001000000070000006d6963726f766d0000000000 +# A CPU profile of revision 0. +INVALID_KEY|CPU_PROFILE_REVISION_0|0100470000007368613235363a61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d7632010000000000000006000000000000000100000000000000010000000000000004000000000000000100000000000000030000006b766d03000000616d640500000067656e6f610000000011111111111111111111111111111111111111111111111111111111111111112c000000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b01000000010000000100000001000000010000000000000000ca9a3b0000000000e1f505000000000000000001000000000000000000000800000000000000080000000000000008000000000100000000000000000000000000000800000000000000000c000000636f6e736f6c653d687663308c7f813b328f96bdb26c4e97b6f5c874cbd968e8664778addc56a7c81ea55113001000000000000000020000000200000010000000000000000200000002000012000000656467652d7368617265642d737461747573000003000000000000100000000000000100000009000000706172746974696f6e09000000706172746974696f6e09000000706172746974696f6e00000000000000000000000000000000000000000001000000070000006d6963726f766d0000000000 +# An effective CPUID that is not whole entries of 44 bytes. +INVALID_KEY|CPUID_LENGTH|0100470000007368613235363a61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d7632010000000000000006000000000000000100000000000000010000000000000004000000000000000100000000000000030000006b766d03000000616d640500000067656e6f610100000011111111111111111111111111111111111111111111111111111111111111112b000000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a01000000010000000100000001000000010000000000000000ca9a3b0000000000e1f505000000000000000001000000000000000000000800000000000000080000000000000008000000000100000000000000000000000000000800000000000000000c000000636f6e736f6c653d687663308c7f813b328f96bdb26c4e97b6f5c874cbd968e8664778addc56a7c81ea55113001000000000000000020000000200000010000000000000000200000002000012000000656467652d7368617265642d737461747573000003000000000000100000000000000100000009000000706172746974696f6e09000000706172746974696f6e09000000706172746974696f6e00000000000000000000000000000000000000000001000000070000006d6963726f766d0000000000 diff --git a/nvx-rs/tests/vectors/template-key-v1.txt b/nvx-rs/tests/vectors/template-key-v1.txt deleted file mode 100644 index 1694806a6..000000000 --- a/nvx-rs/tests/vectors/template-key-v1.txt +++ /dev/null @@ -1,99 +0,0 @@ -# Conformance vectors of version 1 of the canonical encodings of a template's compatibility key, -# nvx::host::template::TemplateKey, and of a capture class, nvx::host::template::CaptureClass, -# which the module nvx::host::template describes. README.md describes the line format and the -# rules that the vectors follow. -# -# KEY|NAME|BYTES|IDENTITY -# The canonical encoding of a key, and its identity: the SHA-256 digest of "nvx template key", a -# NUL byte, and the encoding. A decoder must decode the bytes, and an encoder must encode the key -# that they hold to the same bytes. -# CLASS|NAME|BYTES|IDENTITY -# The canonical encoding of a class, and its identity: the SHA-256 digest of "nvx capture class", -# a NUL byte, and the encoding. -# INVALID_KEY_VERSION|NAME|BYTES -# A key of another version of the encoding, which every decoder refuses as unsupported. -# INVALID_KEY|NAME|BYTES -# Bytes that every decoder of a key must refuse. -# -# The keys and classes are those of the captures that tests/fixtures/template/README.md -# describes, as microVM ABI 2 captured them, when every virtio device but the NIC also offered -# access-platform (feature bit 33), each console also offered its size (feature bit 0), and the -# virtio devices interrupted on ISA IRQs (the NIC on 10, the filesystem on 6, the consoles on 7 -# and 3, and the distro and scratch blocks on 4 and 11), with the OpenVMM, kernel, and initramfs -# identities sha256:a..., sha256:b..., and -# sha256:c..., the guest build guest-build-1, boot contract 3, control contract -# nvx-microvm-v2-control-v2, control session 1, snapshot format 6, device-state schema 1, time -# ABI 1, restore packet 4, and activation contract 1. -# The key of the template of a KVM microVM of 2 processors, all online at boot, and 512 MiB -# of RAM, of a capacity of 2 GiB, with a distro of 1 GiB, a scratch of 64 MiB, the dormant -# filesystem slot, a console, a control console, and no NIC, on the CPU profile -# intel.icelake-sp.v1, whose digest is 32 bytes of 5a and whose effective CPUID is the bytes -# 00 to 57: the capture of tests/fixtures/template/platform-kvm. -KEY|TEMPLATE|0100470000007368613235363a61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d763201000000000000000d00000067756573742d6275696c642d3106000000000000000100000000000000010000000000000004000000000000000100000000000000030000006b766d05000000696e74656c0a0000006963656c616b652d7370010000005a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a58000000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f50515253545556570100000001000000020000000100000002000000000000000100000000752b7d0000000000c2eb0b00000000fa000000020000000000000000000020000000000000008000000000000000080000000001000000000000000000000000000020000000000100000000000020000000000000006000000000530100006561726c79636f6e3d78653920636f6e736f6c653d68766331207265626f6f743d742070616e69633d2d31206e76785f73616e64626f783d31206e76785f636f6e6669673d307864303031303030302c3635353336206e725f637075733d32206e76785f736e617073686f745f746965723d706c6174666f726d2076697274696f5f6d6d696f2e6465766963653d30783130303040307864303030313030303a362076697274696f5f6d6d696f2e6465766963653d30783130303040307864303030323030303a372076697274696f5f6d6d696f2e6465766963653d30783130303040307864303030333030303a342076697274696f5f6d6d696f2e6465766963653d30783130303040307864303030363030303a31312076697274696f5f6d6d696f2e6465766963653d30783130303040307864303030373030303a33206e76785f636f6e74726f6c5f7474793d6876633217f80f8858431ca75fcc7ca694ea68637e017ede02db15e18d0ed4581067858d000000400000000000020000001000000000000400000000000200000002000012000000656467652d7368617265642d737461747573000003000000000000100000000000001000000009000000706172746974696f6e09000000706172746974696f6e09000000706172746974696f6e00000000000000000000000000000000000000000003000000767030040000007663707509000000706172746974696f6e00000000000000000000000000000000000000000006000000766d74696d6505000000636c6f636b06000000766d74696d65000000000000000000000000000000000000000000030000007069630300000070696303000000706963000000000200000004000000706d696f2000000000000000020000000000000004000000706d696fa00000000000000002000000000000000000000000000000000000000006000000696f6170696306000000696f6170696306000000696f617069630000000001000000040000006d6d696f0000c0fe00000000001000000000000000000000000000000000000000050000006c61706963050000006c6170696309000000706172746974696f6e0000000001000000040000006d6d696f0000e0fe00000000001000000000000000000000000000000000000000030000007069740300000070697403000000706974000000000100000004000000706d696f400000000000000004000000000000000100000000000000000000000000000000030000007274630300000072746303000000727463000000000100000004000000706d696f7000000000000000020000000000000001080000000000000000000000000000000d0000006d6963726f766d2d706f72746205000000706f7274620d0000006d6963726f766d2d706f727462000000000100000004000000706d696fe900000000000000020000000000000000000000000000000000000000100000006d6963726f766d2d73687574646f776e0800000073687574646f776e100000006d6963726f766d2d73687574646f776e000000000100000004000000706d696f0406000000000000010000000000000000000000000000000000000000180000006d6963726f766d2d736e617073686f742d7265717565737410000000736e617073686f742d72657175657374180000006d6963726f766d2d736e617073686f742d72657175657374000000000100000004000000706d696f05060000000000000100000000000000000000000000000000000000000b00000066733a6d6963726f766d300900000076697274696f2d66731300000076697274696f66732d333438393636353032340b00000076697274696f2d6d6d696f01000000040000006d6d696f001000d000000000001000000000000001060000000200000000000030030000000200000002000000000100000001000017000000636f6e736f6c653a6d6963726f766d2d76697274696f300e00000076697274696f2d636f6e736f6c651900000076697274696f2d636f6e736f6c652d333438393636393132300b00000076697274696f2d6d6d696f01000000040000006d6d696f002000d000000000001000000000000001070000000200000001000030030000000200000002000000000100000001000012000000626c6b3a73616e64626f783a64697374726f0a00000076697274696f2d626c6b1500000076697274696f2d626c6b2d333438393637333231360b00000076697274696f2d6d6d696f01000000040000006d6d696f003000d0000000000010000000000000010400000002000000640600300300000001000000010000000001000013000000626c6b3a73616e64626f783a736372617463680a00000076697274696f2d626c6b1500000076697274696f2d626c6b2d333438393638353530340b00000076697274696f2d6d6d696f01000000040000006d6d696f006000d0000000000010000000000000010b00000002000000440600300300000001000000010000000001000018000000636f6e736f6c653a6d6963726f766d2d636f6e74726f6c301600000076697274696f2d636f6e74726f6c2d636f6e736f6c652100000076697274696f2d636f6e74726f6c2d636f6e736f6c652d333438393638393630300b00000076697274696f2d6d6d696f01000000040000006d6d696f007000d000000000001000000000000001030000000200000001000030030000000200000002000000000100000001000001000000070000006d6963726f766d0000000000|81901eda9602b4f2099c44415b7a38b035ff215b9bc50f860c8c70ca2c6f593f -# The same with a fixed NIC at 10.0.0.2/24, with its IPv6 identity, under an allow-list -# policy whose digest is 32 bytes of 07, and the invariant settings isolation.seccomp=strict -# and limits.pids=512. -KEY|NETWORK|0100470000007368613235363a61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d763201000000000000000d00000067756573742d6275696c642d3106000000000000000100000000000000010000000000000004000000000000000100000000000000030000006b766d05000000696e74656c0a0000006963656c616b652d7370010000005a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a58000000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f50515253545556570100000001000000020000000100000002000000000000000100000000752b7d0000000000c2eb0b00000000fa000000020000000000000000000020000000000000008000000000000000080000000001000000000000000000000000000020000000000100000000000020000000000000006000000000f20100006561726c79636f6e3d78653920636f6e736f6c653d68766331207265626f6f743d742070616e69633d2d31206e76785f73616e64626f783d31206e76785f636f6e6669673d307864303031303030302c3635353336206e725f637075733d32206e76785f736e617073686f745f746965723d706c6174666f726d2076697274696f5f6d6d696f2e6465766963653d30783130303040307864303030303030303a31302076697274696f5f6d6d696f2e6465766963653d30783130303040307864303030313030303a362076697274696f5f6d6d696f2e6465766963653d30783130303040307864303030323030303a372076697274696f5f6d6d696f2e6465766963653d30783130303040307864303030333030303a342076697274696f5f6d6d696f2e6465766963653d30783130303040307864303030363030303a31312076697274696f5f6d6d696f2e6465766963653d30783130303040307864303030373030303a33206e76785f636f6e74726f6c5f7474793d6876633220766972746e65745f69703d31302e302e302e3220766972746e65745f6d61736b3d3235352e3235352e3235352e3020766972746e65745f67773d31302e302e302e3120766972746e65745f6970363d666430303a3a6130303a322f31323020766972746e65745f6777363d666430303a3a6130303a315e7d49c200c9d60e74547b549917b665501635035894c15c2d7780210f95caf0000000400000000000020000001000000000000400000000000200000002000012000000656467652d7368617265642d737461747573000003000000000000100000000000001100000009000000706172746974696f6e09000000706172746974696f6e09000000706172746974696f6e00000000000000000000000000000000000000000003000000767030040000007663707509000000706172746974696f6e00000000000000000000000000000000000000000006000000766d74696d6505000000636c6f636b06000000766d74696d65000000000000000000000000000000000000000000030000007069630300000070696303000000706963000000000200000004000000706d696f2000000000000000020000000000000004000000706d696fa00000000000000002000000000000000000000000000000000000000006000000696f6170696306000000696f6170696306000000696f617069630000000001000000040000006d6d696f0000c0fe00000000001000000000000000000000000000000000000000050000006c61706963050000006c6170696309000000706172746974696f6e0000000001000000040000006d6d696f0000e0fe00000000001000000000000000000000000000000000000000030000007069740300000070697403000000706974000000000100000004000000706d696f400000000000000004000000000000000100000000000000000000000000000000030000007274630300000072746303000000727463000000000100000004000000706d696f7000000000000000020000000000000001080000000000000000000000000000000d0000006d6963726f766d2d706f72746205000000706f7274620d0000006d6963726f766d2d706f727462000000000100000004000000706d696fe900000000000000020000000000000000000000000000000000000000100000006d6963726f766d2d73687574646f776e0800000073687574646f776e100000006d6963726f766d2d73687574646f776e000000000100000004000000706d696f0406000000000000010000000000000000000000000000000000000000180000006d6963726f766d2d736e617073686f742d7265717565737410000000736e617073686f742d72657175657374180000006d6963726f766d2d736e617073686f742d72657175657374000000000100000004000000706d696f05060000000000000100000000000000000000000000000000000000000c0000006e65743a6d6963726f766d300a00000076697274696f2d6e65741500000076697274696f2d6e65742d333438393636303932380b00000076697274696f2d6d6d696f01000000040000006d6d696f000000d0000000000010000000000000010a000000020000002000000001000000020000000200000000010000000100000b00000066733a6d6963726f766d300900000076697274696f2d66731300000076697274696f66732d333438393636353032340b00000076697274696f2d6d6d696f01000000040000006d6d696f001000d000000000001000000000000001060000000200000000000030030000000200000002000000000100000001000017000000636f6e736f6c653a6d6963726f766d2d76697274696f300e00000076697274696f2d636f6e736f6c651900000076697274696f2d636f6e736f6c652d333438393636393132300b00000076697274696f2d6d6d696f01000000040000006d6d696f002000d000000000001000000000000001070000000200000001000030030000000200000002000000000100000001000012000000626c6b3a73616e64626f783a64697374726f0a00000076697274696f2d626c6b1500000076697274696f2d626c6b2d333438393637333231360b00000076697274696f2d6d6d696f01000000040000006d6d696f003000d0000000000010000000000000010400000002000000640600300300000001000000010000000001000013000000626c6b3a73616e64626f783a736372617463680a00000076697274696f2d626c6b1500000076697274696f2d626c6b2d333438393638353530340b00000076697274696f2d6d6d696f01000000040000006d6d696f006000d0000000000010000000000000010b00000002000000440600300300000001000000010000000001000018000000636f6e736f6c653a6d6963726f766d2d636f6e74726f6c301600000076697274696f2d636f6e74726f6c2d636f6e736f6c652100000076697274696f2d636f6e74726f6c2d636f6e736f6c652d333438393638393630300b00000076697274696f2d6d6d696f01000000040000006d6d696f007000d000000000001000000000000001030000000200000001000030030000000200000002000000000100000001000001000000070000006d6963726f766d0108000000706f727461626c655254000000025254000000010a000002180a00000101fd00000000000000000000000a00000278fd00000000000000000000000a0000010a000000616c6c6f772d6c69737407070707070707070707070707070707070707070707070707070707070707070104000000020000001100000069736f6c6174696f6e2e736563636f6d70060000007374726963740b0000006c696d6974732e7069647303000000353132|f7418d9454a78af64bc5bc46e82206ccd085baf64cf7140e5ae4faf04b7c1ebe -# TEMPLATE on the host profile intel.host.v1. -KEY|HOST_PROFILE|0100470000007368613235363a61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d763201000000000000000d00000067756573742d6275696c642d3106000000000000000100000000000000010000000000000004000000000000000100000000000000030000006b766d05000000696e74656c04000000686f7374010000005a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a58000000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f50515253545556570100000001000000020000000100000002000000000000000100000000752b7d0000000000c2eb0b00000000fa000000020000000000000000000020000000000000008000000000000000080000000001000000000000000000000000000020000000000100000000000020000000000000006000000000530100006561726c79636f6e3d78653920636f6e736f6c653d68766331207265626f6f743d742070616e69633d2d31206e76785f73616e64626f783d31206e76785f636f6e6669673d307864303031303030302c3635353336206e725f637075733d32206e76785f736e617073686f745f746965723d706c6174666f726d2076697274696f5f6d6d696f2e6465766963653d30783130303040307864303030313030303a362076697274696f5f6d6d696f2e6465766963653d30783130303040307864303030323030303a372076697274696f5f6d6d696f2e6465766963653d30783130303040307864303030333030303a342076697274696f5f6d6d696f2e6465766963653d30783130303040307864303030363030303a31312076697274696f5f6d6d696f2e6465766963653d30783130303040307864303030373030303a33206e76785f636f6e74726f6c5f7474793d6876633217f80f8858431ca75fcc7ca694ea68637e017ede02db15e18d0ed4581067858d000000400000000000020000001000000000000400000000000200000002000012000000656467652d7368617265642d737461747573000003000000000000100000000000001000000009000000706172746974696f6e09000000706172746974696f6e09000000706172746974696f6e00000000000000000000000000000000000000000003000000767030040000007663707509000000706172746974696f6e00000000000000000000000000000000000000000006000000766d74696d6505000000636c6f636b06000000766d74696d65000000000000000000000000000000000000000000030000007069630300000070696303000000706963000000000200000004000000706d696f2000000000000000020000000000000004000000706d696fa00000000000000002000000000000000000000000000000000000000006000000696f6170696306000000696f6170696306000000696f617069630000000001000000040000006d6d696f0000c0fe00000000001000000000000000000000000000000000000000050000006c61706963050000006c6170696309000000706172746974696f6e0000000001000000040000006d6d696f0000e0fe00000000001000000000000000000000000000000000000000030000007069740300000070697403000000706974000000000100000004000000706d696f400000000000000004000000000000000100000000000000000000000000000000030000007274630300000072746303000000727463000000000100000004000000706d696f7000000000000000020000000000000001080000000000000000000000000000000d0000006d6963726f766d2d706f72746205000000706f7274620d0000006d6963726f766d2d706f727462000000000100000004000000706d696fe900000000000000020000000000000000000000000000000000000000100000006d6963726f766d2d73687574646f776e0800000073687574646f776e100000006d6963726f766d2d73687574646f776e000000000100000004000000706d696f0406000000000000010000000000000000000000000000000000000000180000006d6963726f766d2d736e617073686f742d7265717565737410000000736e617073686f742d72657175657374180000006d6963726f766d2d736e617073686f742d72657175657374000000000100000004000000706d696f05060000000000000100000000000000000000000000000000000000000b00000066733a6d6963726f766d300900000076697274696f2d66731300000076697274696f66732d333438393636353032340b00000076697274696f2d6d6d696f01000000040000006d6d696f001000d000000000001000000000000001060000000200000000000030030000000200000002000000000100000001000017000000636f6e736f6c653a6d6963726f766d2d76697274696f300e00000076697274696f2d636f6e736f6c651900000076697274696f2d636f6e736f6c652d333438393636393132300b00000076697274696f2d6d6d696f01000000040000006d6d696f002000d000000000001000000000000001070000000200000001000030030000000200000002000000000100000001000012000000626c6b3a73616e64626f783a64697374726f0a00000076697274696f2d626c6b1500000076697274696f2d626c6b2d333438393637333231360b00000076697274696f2d6d6d696f01000000040000006d6d696f003000d0000000000010000000000000010400000002000000640600300300000001000000010000000001000013000000626c6b3a73616e64626f783a736372617463680a00000076697274696f2d626c6b1500000076697274696f2d626c6b2d333438393638353530340b00000076697274696f2d6d6d696f01000000040000006d6d696f006000d0000000000010000000000000010b00000002000000440600300300000001000000010000000001000018000000636f6e736f6c653a6d6963726f766d2d636f6e74726f6c301600000076697274696f2d636f6e74726f6c2d636f6e736f6c652100000076697274696f2d636f6e74726f6c2d636f6e736f6c652d333438393638393630300b00000076697274696f2d6d6d696f01000000040000006d6d696f007000d000000000001000000000000001030000000200000001000030030000000200000002000000000100000001000001000000070000006d6963726f766d0000000000|93afa8bdde64df606707f5534c58420b92888acbbb6c8245e83006768c3ac940 -# A machine of one processor and one device, and no NIC, which the invalid vectors change. -KEY|MINIMAL|0100470000007368613235363a61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d763201000000000000000d00000067756573742d6275696c642d3106000000000000000100000000000000010000000000000004000000000000000100000000000000030000006b766d03000000616d640500000067656e6f610100000011111111111111111111111111111111111111111111111111111111111111112c000000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b01000000010000000100000001000000010000000000000000ca9a3b0000000000e1f505000000000000000001000000000000000000000800000000000000080000000000000008000000000100000000000000000000000000000800000000000000000c000000636f6e736f6c653d687663308c7f813b328f96bdb26c4e97b6f5c874cbd968e8664778addc56a7c81ea55113001000000000000000020000000200000010000000000000000200000002000012000000656467652d7368617265642d737461747573000003000000000000100000000000000100000009000000706172746974696f6e09000000706172746974696f6e09000000706172746974696f6e00000000000000000000000000000000000000000001000000070000006d6963726f766d0000000000|d79a8fefc401da8568586cdc595a93a7e6c988aefbc62b03038901940211c1f1 - -# The class of the capture of TEMPLATE: the CPU profile auto, and 2 processors, all online at -# boot. -CLASS|TEMPLATE|0100470000007368613235363a61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d763201000000000000000d00000067756573742d6275696c642d3106000000000000000100000000000000010000000000000004000000000000000100000000000000030000006b766d040000006175746f02000000020000000000002000000000000000800000000000000040000000000002000000100000000000040000000000020000000200000000000000000000|b53b0169db5d983b31f24bec900cd0b962d26f12480d90803f21ae1d5c3ff334 -# The class of the capture of NETWORK, whose NIC the capture attaches under the complete -# deny-all policy, whatever the policy of the class's network, here one that allows egress. -CLASS|NETWORK|0100470000007368613235363a61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d763201000000000000000d00000067756573742d6275696c642d3106000000000000000100000000000000010000000000000004000000000000000100000000000000030000006b766d040000006175746f02000000020000000000002000000000000000800000000000000040000000000002000000100000000000040000000000020000000200000a000000050000002d2d6e65740b00000031302e302e302e322f3234110000002d2d6e6574776f726b2d70726f66696c6508000000706f727461626c65100000002d2d6e6574776f726b2d6567726573730400000064656e79110000002d2d6e6574776f726b2d696e67726573730400000064656e790f0000002d2d686f73742d6c6f6f706261636b0400000064656e79020000001100000069736f6c6174696f6e2e736563636f6d70060000007374726963740b0000006c696d6974732e7069647303000000353132|2f32edae7e9eb532625af600232c68aa78b92e02c8116cb49f857f13ff5fcc7c - -# MINIMAL in other versions of the encoding. -INVALID_KEY_VERSION|VERSION_0|0000470000007368613235363a61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d763201000000000000000d00000067756573742d6275696c642d3106000000000000000100000000000000010000000000000004000000000000000100000000000000030000006b766d03000000616d640500000067656e6f610100000011111111111111111111111111111111111111111111111111111111111111112c000000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b01000000010000000100000001000000010000000000000000ca9a3b0000000000e1f505000000000000000001000000000000000000000800000000000000080000000000000008000000000100000000000000000000000000000800000000000000000c000000636f6e736f6c653d687663308c7f813b328f96bdb26c4e97b6f5c874cbd968e8664778addc56a7c81ea55113001000000000000000020000000200000010000000000000000200000002000012000000656467652d7368617265642d737461747573000003000000000000100000000000000100000009000000706172746974696f6e09000000706172746974696f6e09000000706172746974696f6e00000000000000000000000000000000000000000001000000070000006d6963726f766d0000000000 -INVALID_KEY_VERSION|VERSION_2|0200470000007368613235363a61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d763201000000000000000d00000067756573742d6275696c642d3106000000000000000100000000000000010000000000000004000000000000000100000000000000030000006b766d03000000616d640500000067656e6f610100000011111111111111111111111111111111111111111111111111111111111111112c000000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b01000000010000000100000001000000010000000000000000ca9a3b0000000000e1f505000000000000000001000000000000000000000800000000000000080000000000000008000000000100000000000000000000000000000800000000000000000c000000636f6e736f6c653d687663308c7f813b328f96bdb26c4e97b6f5c874cbd968e8664778addc56a7c81ea55113001000000000000000020000000200000010000000000000000200000002000012000000656467652d7368617265642d737461747573000003000000000000100000000000000100000009000000706172746974696f6e09000000706172746974696f6e09000000706172746974696f6e00000000000000000000000000000000000000000001000000070000006d6963726f766d0000000000 -INVALID_KEY_VERSION|VERSION_65535|ffff470000007368613235363a61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d763201000000000000000d00000067756573742d6275696c642d3106000000000000000100000000000000010000000000000004000000000000000100000000000000030000006b766d03000000616d640500000067656e6f610100000011111111111111111111111111111111111111111111111111111111111111112c000000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b01000000010000000100000001000000010000000000000000ca9a3b0000000000e1f505000000000000000001000000000000000000000800000000000000080000000000000008000000000100000000000000000000000000000800000000000000000c000000636f6e736f6c653d687663308c7f813b328f96bdb26c4e97b6f5c874cbd968e8664778addc56a7c81ea55113001000000000000000020000000200000010000000000000000200000002000012000000656467652d7368617265642d737461747573000003000000000000100000000000000100000009000000706172746974696f6e09000000706172746974696f6e09000000706172746974696f6e00000000000000000000000000000000000000000001000000070000006d6963726f766d0000000000 - -# No bytes. -INVALID_KEY|EMPTY| -# MINIMAL without its last byte. -INVALID_KEY|TRUNCATED|0100470000007368613235363a61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d763201000000000000000d00000067756573742d6275696c642d3106000000000000000100000000000000010000000000000004000000000000000100000000000000030000006b766d03000000616d640500000067656e6f610100000011111111111111111111111111111111111111111111111111111111111111112c000000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b01000000010000000100000001000000010000000000000000ca9a3b0000000000e1f505000000000000000001000000000000000000000800000000000000080000000000000008000000000100000000000000000000000000000800000000000000000c000000636f6e736f6c653d687663308c7f813b328f96bdb26c4e97b6f5c874cbd968e8664778addc56a7c81ea55113001000000000000000020000000200000010000000000000000200000002000012000000656467652d7368617265642d737461747573000003000000000000100000000000000100000009000000706172746974696f6e09000000706172746974696f6e09000000706172746974696f6e00000000000000000000000000000000000000000001000000070000006d6963726f766d00000000 -# MINIMAL and a byte after it. -INVALID_KEY|TRAILING_BYTE|0100470000007368613235363a61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d763201000000000000000d00000067756573742d6275696c642d3106000000000000000100000000000000010000000000000004000000000000000100000000000000030000006b766d03000000616d640500000067656e6f610100000011111111111111111111111111111111111111111111111111111111111111112c000000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b01000000010000000100000001000000010000000000000000ca9a3b0000000000e1f505000000000000000001000000000000000000000800000000000000080000000000000008000000000100000000000000000000000000000800000000000000000c000000636f6e736f6c653d687663308c7f813b328f96bdb26c4e97b6f5c874cbd968e8664778addc56a7c81ea55113001000000000000000020000000200000010000000000000000200000002000012000000656467652d7368617265642d737461747573000003000000000000100000000000000100000009000000706172746974696f6e09000000706172746974696f6e09000000706172746974696f6e00000000000000000000000000000000000000000001000000070000006d6963726f766d000000000000 -# A command line whose digest does not match it. -INVALID_KEY|COMMAND_LINE_DIGEST|0100470000007368613235363a61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d763201000000000000000d00000067756573742d6275696c642d3106000000000000000100000000000000010000000000000004000000000000000100000000000000030000006b766d03000000616d640500000067656e6f610100000011111111111111111111111111111111111111111111111111111111111111112c000000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b01000000010000000100000001000000010000000000000000ca9a3b0000000000e1f505000000000000000001000000000000000000000800000000000000080000000000000008000000000100000000000000000000000000000800000000000000000c000000636f6e736f6c653d687663300000000000000000000000000000000000000000000000000000000000000000001000000000000000020000000200000010000000000000000200000002000012000000656467652d7368617265642d737461747573000003000000000000100000000000000100000009000000706172746974696f6e09000000706172746974696f6e09000000706172746974696f6e00000000000000000000000000000000000000000001000000070000006d6963726f766d0000000000 -# A backend that does not exist. -INVALID_KEY|UNKNOWN_BACKEND|0100470000007368613235363a61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d763201000000000000000d00000067756573742d6275696c642d31060000000000000001000000000000000100000000000000040000000000000001000000000000000300000078656e03000000616d640500000067656e6f610100000011111111111111111111111111111111111111111111111111111111111111112c000000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b01000000010000000100000001000000010000000000000000ca9a3b0000000000e1f505000000000000000001000000000000000000000800000000000000080000000000000008000000000100000000000000000000000000000800000000000000000c000000636f6e736f6c653d687663308c7f813b328f96bdb26c4e97b6f5c874cbd968e8664778addc56a7c81ea55113001000000000000000020000000200000010000000000000000200000002000012000000656467652d7368617265642d737461747573000003000000000000100000000000000100000009000000706172746974696f6e09000000706172746974696f6e09000000706172746974696f6e00000000000000000000000000000000000000000001000000070000006d6963726f766d0000000000 -# A device range of an address space that does not exist. -INVALID_KEY|UNKNOWN_ADDRESS_SPACE|0100470000007368613235363a61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d763201000000000000000d00000067756573742d6275696c642d3106000000000000000100000000000000010000000000000004000000000000000100000000000000030000006b766d03000000616d640500000067656e6f610100000011111111111111111111111111111111111111111111111111111111111111112c000000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b01000000010000000100000001000000010000000000000000ca9a3b0000000000e1f505000000000000000001000000000000000000000800000000000000080000000000000008000000000100000000000000000000000000000800000000000000000c000000636f6e736f6c653d687663308c7f813b328f96bdb26c4e97b6f5c874cbd968e8664778addc56a7c81ea55113001000000000000000020000000200000010000000000000000200000002000012000000656467652d7368617265642d737461747573000003000000000000100000000000000100000009000000706172746974696f6e09000000706172746974696f6e09000000706172746974696f6e000000000100000004000000706f7274200000000000000002000000000000000000000000000000000000000001000000070000006d6963726f766d0000000000 -# An interrupt delivery mode that is not UTF-8. -INVALID_KEY|INTERRUPT_MODE_NOT_UTF8|0100470000007368613235363a61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d763201000000000000000d00000067756573742d6275696c642d3106000000000000000100000000000000010000000000000004000000000000000100000000000000030000006b766d03000000616d640500000067656e6f610100000011111111111111111111111111111111111111111111111111111111111111112c000000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b01000000010000000100000001000000010000000000000000ca9a3b0000000000e1f505000000000000000001000000000000000000000800000000000000080000000000000008000000000100000000000000000000000000000800000000000000000c000000636f6e736f6c653d687663308c7f813b328f96bdb26c4e97b6f5c874cbd968e8664778addc56a7c81ea55113001000000000000000020000000200000010000000000000000200000002000013000000656467652d7368617265642dff737461747573000003000000000000100000000000000100000009000000706172746974696f6e09000000706172746974696f6e09000000706172746974696f6e00000000000000000000000000000000000000000001000000070000006d6963726f766d0000000000 -# A NIC whose presence tag is 2. -INVALID_KEY|PRESENCE_TAG_2|0100470000007368613235363a61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d763201000000000000000d00000067756573742d6275696c642d3106000000000000000100000000000000010000000000000004000000000000000100000000000000030000006b766d03000000616d640500000067656e6f610100000011111111111111111111111111111111111111111111111111111111111111112c000000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b01000000010000000100000001000000010000000000000000ca9a3b0000000000e1f505000000000000000001000000000000000000000800000000000000080000000000000008000000000100000000000000000000000000000800000000000000000c000000636f6e736f6c653d687663308c7f813b328f96bdb26c4e97b6f5c874cbd968e8664778addc56a7c81ea55113001000000000000000020000000200000010000000000000000200000002000012000000656467652d7368617265642d737461747573000003000000000000100000000000000100000009000000706172746974696f6e09000000706172746974696f6e09000000706172746974696f6e00000000000000000000000000000000000000000001000000070000006d6963726f766d0200000000 -# A NIC whose policy's enforcement is 2. -INVALID_KEY|BOOLEAN_2|0100470000007368613235363a61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d763201000000000000000d00000067756573742d6275696c642d3106000000000000000100000000000000010000000000000004000000000000000100000000000000030000006b766d03000000616d640500000067656e6f610100000011111111111111111111111111111111111111111111111111111111111111112c000000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b01000000010000000100000001000000010000000000000000ca9a3b0000000000e1f505000000000000000001000000000000000000000800000000000000080000000000000008000000000100000000000000000000000000000800000000000000000c000000636f6e736f6c653d687663308c7f813b328f96bdb26c4e97b6f5c874cbd968e8664778addc56a7c81ea55113001000000000000000020000000200000010000000000000000200000002000012000000656467652d7368617265642d737461747573000003000000000000100000000000000100000009000000706172746974696f6e09000000706172746974696f6e09000000706172746974696f6e00000000000000000000000000000000000000000001000000070000006d6963726f766d0108000000706f727461626c655254000000025254000000010a000002180a00000101fd00000000000000000000000a00000278fd00000000000000000000000a0000010a000000616c6c6f772d6c6973740707070707070707070707070707070707070707070707070707070707070707020400000000000000 -# Invariant settings out of the order of their names. -INVALID_KEY|UNSORTED_SETTINGS|0100470000007368613235363a61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d763201000000000000000d00000067756573742d6275696c642d3106000000000000000100000000000000010000000000000004000000000000000100000000000000030000006b766d03000000616d640500000067656e6f610100000011111111111111111111111111111111111111111111111111111111111111112c000000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b01000000010000000100000001000000010000000000000000ca9a3b0000000000e1f505000000000000000001000000000000000000000800000000000000080000000000000008000000000100000000000000000000000000000800000000000000000c000000636f6e736f6c653d687663308c7f813b328f96bdb26c4e97b6f5c874cbd968e8664778addc56a7c81ea55113001000000000000000020000000200000010000000000000000200000002000012000000656467652d7368617265642d737461747573000003000000000000100000000000000100000009000000706172746974696f6e09000000706172746974696f6e09000000706172746974696f6e00000000000000000000000000000000000000000001000000070000006d6963726f766d00020000000b0000006c696d6974732e70696473030000003531321100000069736f6c6174696f6e2e736563636f6d7006000000737472696374 -# An invariant setting named twice. -INVALID_KEY|DUPLICATE_SETTINGS|0100470000007368613235363a61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d763201000000000000000d00000067756573742d6275696c642d3106000000000000000100000000000000010000000000000004000000000000000100000000000000030000006b766d03000000616d640500000067656e6f610100000011111111111111111111111111111111111111111111111111111111111111112c000000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b01000000010000000100000001000000010000000000000000ca9a3b0000000000e1f505000000000000000001000000000000000000000800000000000000080000000000000008000000000100000000000000000000000000000800000000000000000c000000636f6e736f6c653d687663308c7f813b328f96bdb26c4e97b6f5c874cbd968e8664778addc56a7c81ea55113001000000000000000020000000200000010000000000000000200000002000012000000656467652d7368617265642d737461747573000003000000000000100000000000000100000009000000706172746974696f6e09000000706172746974696f6e09000000706172746974696f6e00000000000000000000000000000000000000000001000000070000006d6963726f766d00020000000b0000006c696d6974732e70696473030000003531320b0000006c696d6974732e7069647303000000353132 -# An invariant setting whose name holds an uppercase letter. -INVALID_KEY|UPPERCASE_SETTING|0100470000007368613235363a61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d763201000000000000000d00000067756573742d6275696c642d3106000000000000000100000000000000010000000000000004000000000000000100000000000000030000006b766d03000000616d640500000067656e6f610100000011111111111111111111111111111111111111111111111111111111111111112c000000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b01000000010000000100000001000000010000000000000000ca9a3b0000000000e1f505000000000000000001000000000000000000000800000000000000080000000000000008000000000100000000000000000000000000000800000000000000000c000000636f6e736f6c653d687663308c7f813b328f96bdb26c4e97b6f5c874cbd968e8664778addc56a7c81ea55113001000000000000000020000000200000010000000000000000200000002000012000000656467652d7368617265642d737461747573000003000000000000100000000000000100000009000000706172746974696f6e09000000706172746974696f6e09000000706172746974696f6e00000000000000000000000000000000000000000001000000070000006d6963726f766d00010000000b0000004c696d6974732e7069647303000000353132 -# More APIC IDs than a microVM has processors. -INVALID_KEY|TOO_MANY_APIC_IDS|0100470000007368613235363a61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d763201000000000000000d00000067756573742d6275696c642d3106000000000000000100000000000000010000000000000004000000000000000100000000000000030000006b766d03000000616d640500000067656e6f610100000011111111111111111111111111111111111111111111111111111111111111112c000000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b010000000100000001000000010000000900000000000000010000000200000003000000040000000500000006000000070000000800000000ca9a3b0000000000e1f505000000000000000001000000000000000000000800000000000000080000000000000008000000000100000000000000000000000000000800000000000000000c000000636f6e736f6c653d687663308c7f813b328f96bdb26c4e97b6f5c874cbd968e8664778addc56a7c81ea55113001000000000000000020000000200000010000000000000000200000002000012000000656467652d7368617265642d737461747573000003000000000000100000000000000100000009000000706172746974696f6e09000000706172746974696f6e09000000706172746974696f6e00000000000000000000000000000000000000000001000000070000006d6963726f766d0000000000 -# 3 processors, which a microVM cannot have. -INVALID_KEY|THREE_PROCESSORS|0100470000007368613235363a61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d763201000000000000000d00000067756573742d6275696c642d3106000000000000000100000000000000010000000000000004000000000000000100000000000000030000006b766d03000000616d640500000067656e6f610100000011111111111111111111111111111111111111111111111111111111111111112c000000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b010000000100000003000000010000000300000000000000010000000200000000ca9a3b0000000000e1f505000000000000000003000000000000000000000800000000000000080000000000000008000000000100000000000000000000000000000800000000000000000c000000636f6e736f6c653d687663308c7f813b328f96bdb26c4e97b6f5c874cbd968e8664778addc56a7c81ea55113001000000000000000020000000200000010000000000000000200000002000012000000656467652d7368617265642d737461747573000003000000000000100000000000000100000009000000706172746974696f6e09000000706172746974696f6e09000000706172746974696f6e00000000000000000000000000000000000000000001000000070000006d6963726f766d0000000000 -# RAM ranges that do not hold the RAM. -INVALID_KEY|MEMORY_RANGES|0100470000007368613235363a61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d763201000000000000000d00000067756573742d6275696c642d3106000000000000000100000000000000010000000000000004000000000000000100000000000000030000006b766d03000000616d640500000067656e6f610100000011111111111111111111111111111111111111111111111111111111111111112c000000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b01000000010000000100000001000000010000000000000000ca9a3b0000000000e1f505000000000000000001000000000000000000000800000000000000080000000000000008000000000100000000000000000000000000000400000000000000000c000000636f6e736f6c653d687663308c7f813b328f96bdb26c4e97b6f5c874cbd968e8664778addc56a7c81ea55113001000000000000000020000000200000010000000000000000200000002000012000000656467652d7368617265642d737461747573000003000000000000100000000000000100000009000000706172746974696f6e09000000706172746974696f6e09000000706172746974696f6e00000000000000000000000000000000000000000001000000070000006d6963726f766d0000000000 -# A machine without devices. -INVALID_KEY|NO_DEVICES|0100470000007368613235363a61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d763201000000000000000d00000067756573742d6275696c642d3106000000000000000100000000000000010000000000000004000000000000000100000000000000030000006b766d03000000616d640500000067656e6f610100000011111111111111111111111111111111111111111111111111111111111111112c000000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b01000000010000000100000001000000010000000000000000ca9a3b0000000000e1f505000000000000000001000000000000000000000800000000000000080000000000000008000000000100000000000000000000000000000800000000000000000c000000636f6e736f6c653d687663308c7f813b328f96bdb26c4e97b6f5c874cbd968e8664778addc56a7c81ea55113001000000000000000020000000200000010000000000000000200000002000012000000656467652d7368617265642d737461747573000003000000000000100000000000000000000001000000070000006d6963726f766d0000000000 -# A device ID twice. -INVALID_KEY|DUPLICATE_DEVICE|0100470000007368613235363a61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d763201000000000000000d00000067756573742d6275696c642d3106000000000000000100000000000000010000000000000004000000000000000100000000000000030000006b766d03000000616d640500000067656e6f610100000011111111111111111111111111111111111111111111111111111111111111112c000000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b01000000010000000100000001000000010000000000000000ca9a3b0000000000e1f505000000000000000001000000000000000000000800000000000000080000000000000008000000000100000000000000000000000000000800000000000000000c000000636f6e736f6c653d687663308c7f813b328f96bdb26c4e97b6f5c874cbd968e8664778addc56a7c81ea55113001000000000000000020000000200000010000000000000000200000002000012000000656467652d7368617265642d737461747573000003000000000000100000000000000200000009000000706172746974696f6e09000000706172746974696f6e09000000706172746974696f6e00000000000000000000000000000000000000000009000000706172746974696f6e05000000636c6f636b06000000766d74696d6500000000000000000000000000000000000000000001000000070000006d6963726f766d0000000000 -# A filesystem slot that is not the dormant slot of version 1. -INVALID_KEY|SLOT_VERSION_0|0100470000007368613235363a61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d763201000000000000000d00000067756573742d6275696c642d3106000000000000000100000000000000010000000000000004000000000000000100000000000000030000006b766d03000000616d640500000067656e6f610100000011111111111111111111111111111111111111111111111111111111111111112c000000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b01000000010000000100000001000000010000000000000000ca9a3b0000000000e1f505000000000000000001000000000000000000000800000000000000080000000000000008000000000100000000000000000000000000000800000000000000000c000000636f6e736f6c653d687663308c7f813b328f96bdb26c4e97b6f5c874cbd968e8664778addc56a7c81ea55113001000000000000000020000000200000010000000000000000200000002000012000000656467652d7368617265642d737461747573000003000000000000100000000000000100000009000000706172746974696f6e09000000706172746974696f6e09000000706172746974696f6e00000000000000000000000000000000000000000000000000070000006d6963726f766d0000000000 -# A filesystem slot without a tag. -INVALID_KEY|EMPTY_TAG|0100470000007368613235363a61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d763201000000000000000d00000067756573742d6275696c642d3106000000000000000100000000000000010000000000000004000000000000000100000000000000030000006b766d03000000616d640500000067656e6f610100000011111111111111111111111111111111111111111111111111111111111111112c000000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b01000000010000000100000001000000010000000000000000ca9a3b0000000000e1f505000000000000000001000000000000000000000800000000000000080000000000000008000000000100000000000000000000000000000800000000000000000c000000636f6e736f6c653d687663308c7f813b328f96bdb26c4e97b6f5c874cbd968e8664778addc56a7c81ea55113001000000000000000020000000200000010000000000000000200000002000012000000656467652d7368617265642d737461747573000003000000000000100000000000000100000009000000706172746974696f6e09000000706172746974696f6e09000000706172746974696f6e00000000000000000000000000000000000000000001000000000000000000000000 -# A distro whose logical block size is 256. -INVALID_KEY|DISTRO_BLOCK_SIZE|0100470000007368613235363a61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d763201000000000000000d00000067756573742d6275696c642d3106000000000000000100000000000000010000000000000004000000000000000100000000000000030000006b766d03000000616d640500000067656e6f610100000011111111111111111111111111111111111111111111111111111111111111112c000000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b01000000010000000100000001000000010000000000000000ca9a3b0000000000e1f505000000000000000001000000000000000000000800000000000000080000000000000008000000000100000000000000000000000000000800000000000000000c000000636f6e736f6c653d687663308c7f813b328f96bdb26c4e97b6f5c874cbd968e8664778addc56a7c81ea55113001000000000000000010000000200000010000000000000000200000002000012000000656467652d7368617265642d737461747573000003000000000000100000000000000100000009000000706172746974696f6e09000000706172746974696f6e09000000706172746974696f6e00000000000000000000000000000000000000000001000000070000006d6963726f766d0000000000 -# An OpenVMM identity that holds a space. -INVALID_KEY|ARTIFACT_WITH_SPACE|0100470000007368613235363a20616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d763201000000000000000d00000067756573742d6275696c642d3106000000000000000100000000000000010000000000000004000000000000000100000000000000030000006b766d03000000616d640500000067656e6f610100000011111111111111111111111111111111111111111111111111111111111111112c000000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b01000000010000000100000001000000010000000000000000ca9a3b0000000000e1f505000000000000000001000000000000000000000800000000000000080000000000000008000000000100000000000000000000000000000800000000000000000c000000636f6e736f6c653d687663308c7f813b328f96bdb26c4e97b6f5c874cbd968e8664778addc56a7c81ea55113001000000000000000020000000200000010000000000000000200000002000012000000656467652d7368617265642d737461747573000003000000000000100000000000000100000009000000706172746974696f6e09000000706172746974696f6e09000000706172746974696f6e00000000000000000000000000000000000000000001000000070000006d6963726f766d0000000000 -# A CPU profile of revision 0. -INVALID_KEY|CPU_PROFILE_REVISION_0|0100470000007368613235363a61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d763201000000000000000d00000067756573742d6275696c642d3106000000000000000100000000000000010000000000000004000000000000000100000000000000030000006b766d03000000616d640500000067656e6f610000000011111111111111111111111111111111111111111111111111111111111111112c000000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b01000000010000000100000001000000010000000000000000ca9a3b0000000000e1f505000000000000000001000000000000000000000800000000000000080000000000000008000000000100000000000000000000000000000800000000000000000c000000636f6e736f6c653d687663308c7f813b328f96bdb26c4e97b6f5c874cbd968e8664778addc56a7c81ea55113001000000000000000020000000200000010000000000000000200000002000012000000656467652d7368617265642d737461747573000003000000000000100000000000000100000009000000706172746974696f6e09000000706172746974696f6e09000000706172746974696f6e00000000000000000000000000000000000000000001000000070000006d6963726f766d0000000000 -# An effective CPUID that is not whole entries of 44 bytes. -INVALID_KEY|CPUID_LENGTH|0100470000007368613235363a61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161470000007368613235363a62626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262470000007368613235363a636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363630300000000000000190000006e76782d6d6963726f766d2d76322d636f6e74726f6c2d763201000000000000000d00000067756573742d6275696c642d3106000000000000000100000000000000010000000000000004000000000000000100000000000000030000006b766d03000000616d640500000067656e6f610100000011111111111111111111111111111111111111111111111111111111111111112b000000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a01000000010000000100000001000000010000000000000000ca9a3b0000000000e1f505000000000000000001000000000000000000000800000000000000080000000000000008000000000100000000000000000000000000000800000000000000000c000000636f6e736f6c653d687663308c7f813b328f96bdb26c4e97b6f5c874cbd968e8664778addc56a7c81ea55113001000000000000000020000000200000010000000000000000200000002000012000000656467652d7368617265642d737461747573000003000000000000100000000000000100000009000000706172746974696f6e09000000706172746974696f6e09000000706172746974696f6e00000000000000000000000000000000000000000001000000070000006d6963726f766d0000000000 diff --git a/tests/runtime-adapter/tests/vm_template.rs b/tests/runtime-adapter/tests/vm_template.rs index 726a22d96..51f04e59b 100644 --- a/tests/runtime-adapter/tests/vm_template.rs +++ b/tests/runtime-adapter/tests/vm_template.rs @@ -406,15 +406,10 @@ fn assert_captured(templates: &Templates, created: &Printed, template: &Template let key = store.read_key(generation).unwrap(); assert_eq!(key.identity(), generation.key()); - // The runtime of the adapter's VMs, with the guest agent's build, and the machine that the - // scenario asked for. + // The runtime of the adapter's VMs, and the machine that the scenario asked for. let artifacts = env::var_os(Artifacts::ENV_DIR).unwrap(); let runtime = Runtime::from_dir(artifacts, GUEST_BUILD).unwrap(); assert_eq!(key.runtime(), &runtime.identity); - assert_eq!( - key.guest_build().as_str(), - format!("runtime-adapter-guest/{GUEST_BUILD}") - ); assert_eq!(key.hypervisor(), Hypervisor::from_env_or_default().unwrap()); let processors = template.processors(); assert_eq!(key.processors(), processors); From b7f0db5195f8ed9a624b0ab7430254ac1185c80f Mon Sep 17 00:00:00 2001 From: Enrique Saurez Date: Sat, 7 Nov 2026 01:13:26 -0800 Subject: [PATCH 2/3] host: retain template clock parsing across the metadata move Keep HostClock parsing visible to the existing template store within the host boundary. Moving the manifest must not hide the parser from its current caller. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 7f9c3ba3-e38b-427c-8ed6-da7a970c21a9 Copilot-Session: 0325d032-38a9-4c7f-9899-687a4ec93a51 --- nvx-rs/src/host/snapshot/manifest.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nvx-rs/src/host/snapshot/manifest.rs b/nvx-rs/src/host/snapshot/manifest.rs index 6148f89da..d21fe338f 100644 --- a/nvx-rs/src/host/snapshot/manifest.rs +++ b/nvx-rs/src/host/snapshot/manifest.rs @@ -137,7 +137,7 @@ impl HostClock { } /// Parses the spelling of a clock in a manifest. - pub(super) fn parse(text: &str) -> Option { + pub(in crate::host) fn parse(text: &str) -> Option { match text { "linux-boottime" => Some(Self::LinuxBoottime), "windows-interrupt-time" => Some(Self::WindowsInterruptTime), From 1106886aa8e397113aac4f5cc4f148656f766c53 Mon Sep 17 00:00:00 2001 From: Enrique Saurez Date: Sat, 7 Nov 2026 01:48:07 -0800 Subject: [PATCH 3/3] host: preserve metadata parser parity and acyclic ownership Keep the existing key-identity error shared by the template lease parser, and update the clone test for the renamed key. Retain Generation eligibility at the template boundary so snapshot metadata does not depend on its legacy store. Update the directly affected metadata documentation. The snapshot module exports metadata only, independent of cold VM preparation and spawning. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 7f9c3ba3-e38b-427c-8ed6-da7a970c21a9 Copilot-Session: 0325d032-38a9-4c7f-9899-687a4ec93a51 --- nvx-rs/src/host/mod.rs | 13 ++++++------- nvx-rs/src/host/snapshot/eligibility.rs | 10 ---------- nvx-rs/src/host/snapshot/key.rs | 2 +- nvx-rs/src/host/snapshot/key/tests.rs | 2 +- nvx-rs/src/host/template/clone/tests.rs | 2 +- nvx-rs/src/host/template/mod.rs | 9 +++++++++ nvx-rs/tests/fixtures/template/README.md | 2 +- tests/runtime-adapter/README.md | 9 +++++---- 8 files changed, 24 insertions(+), 25 deletions(-) diff --git a/nvx-rs/src/host/mod.rs b/nvx-rs/src/host/mod.rs index cdf254640..08f9826b1 100644 --- a/nvx-rs/src/host/mod.rs +++ b/nvx-rs/src/host/mod.rs @@ -29,13 +29,12 @@ //! with a bounded forced step on request, and reattaches to it after the orchestrator restarts //! within the same host boot. The private `spawn` module, whose items `supervisor` re-exports, //! starts the VMM detached, with no other descriptor or handle of the caller's. -//! - [`template`] holds the metadata of templates, captures from which clones are restored: the -//! compatibility key of a template, [`TemplateKey`](template::TemplateKey), which it derives -//! from the [`CaptureClass`](template::CaptureClass) of the capture and the capture's -//! [`TemplateManifest`](template::TemplateManifest), the [`Store`](template::Store) of the -//! generations of templates that a host published, which leases them to clones, and the plan -//! of a template's capture, [`TemplatePlan`](template::TemplatePlan), which it lowers from an -//! adapter's plan. +//! - [`snapshot`] holds the compatibility key, [`SnapshotKey`](snapshot::SnapshotKey), derived +//! from a [`CaptureClass`](snapshot::CaptureClass) and [`SnapshotManifest`](snapshot::SnapshotManifest), +//! the strict manifest reader, and the capture's public time and eligibility information. +//! - [`template`] retains the legacy capture and clone plans, the [`Store`](template::Store) of +//! published generations and their leases, and aliases of the snapshot metadata. Its +//! [`TemplatePlan`](template::TemplatePlan) lowers an adapter's plan for a capture. //! - [`session`] speaks NVX's control protocol, `NVXC`, over [`nvxs`], which runs the host's role //! of the NVXS session for it and for any other application protocol, over a platform //! transport. [`platform`] holds the primitives of Linux and Windows hosts. Other hosts compile diff --git a/nvx-rs/src/host/snapshot/eligibility.rs b/nvx-rs/src/host/snapshot/eligibility.rs index 65d3b7e6d..44083f7ae 100644 --- a/nvx-rs/src/host/snapshot/eligibility.rs +++ b/nvx-rs/src/host/snapshot/eligibility.rs @@ -12,7 +12,6 @@ use super::manifest::{HostClock, TimeContract}; use crate::error::{Error, ErrorKind, Result}; use crate::host::platform; use crate::host::process::BootId; -use crate::host::template::Generation; /// The longest interval by which a restore advances a clone's VM time, from the cut of the /// captured VM's time to the restoring host's time, in nanoseconds: 30 days, as version @@ -213,12 +212,3 @@ impl TimeContract { } } } - -impl Generation { - /// Returns whether a clone may restore the generation at the host's time `now`, by the - /// restore window of its capture's time contract, as [`TimeContract::eligibility`] decides - /// it. - pub fn eligibility(&self, now: &HostTime) -> Eligibility { - self.time().eligibility(now) - } -} diff --git a/nvx-rs/src/host/snapshot/key.rs b/nvx-rs/src/host/snapshot/key.rs index 34da58d2d..9f0c77169 100644 --- a/nvx-rs/src/host/snapshot/key.rs +++ b/nvx-rs/src/host/snapshot/key.rs @@ -211,7 +211,7 @@ identity!( /// [`activation::Identity`] by which a clone's lease and durable records name the key of its /// template, in their [`TemplateReference`](activation::TemplateReference), without loss. KeyIdentity, - "a snapshot key's identity" + "a template key's identity" ); impl From for activation::Identity { diff --git a/nvx-rs/src/host/snapshot/key/tests.rs b/nvx-rs/src/host/snapshot/key/tests.rs index 1a6ff2f91..c7fce6252 100644 --- a/nvx-rs/src/host/snapshot/key/tests.rs +++ b/nvx-rs/src/host/snapshot/key/tests.rs @@ -889,7 +889,7 @@ fn identities_have_a_text_form() { assert_eq!(error.code(), ErrorCode::Unsupported); assert_eq!( error.message(), - format!("{invalid:?} is not a snapshot key's identity, which is 64 hexadecimal digits") + format!("{invalid:?} is not a template key's identity, which is 64 hexadecimal digits") ); } let class = network_class().identity().unwrap(); diff --git a/nvx-rs/src/host/template/clone/tests.rs b/nvx-rs/src/host/template/clone/tests.rs index 62c98955b..a3ac200ac 100644 --- a/nvx-rs/src/host/template/clone/tests.rs +++ b/nvx-rs/src/host/template/clone/tests.rs @@ -1356,7 +1356,7 @@ fn keys_of_another_encoding_version_are_failures_of_the_host_that_quarantine_not ); assert_eq!(failure.code(), ErrorCode::FormatUnsupported, "{failure}"); let unread = format!( - "the template key has encoding version {version}; this build reads version {} only", + "the snapshot key has encoding version {version}; this build reads version {} only", TemplateKey::VERSION ); assert!(failure.message().contains(&unread), "{failure}"); diff --git a/nvx-rs/src/host/template/mod.rs b/nvx-rs/src/host/template/mod.rs index 298105cb1..8c37873a2 100644 --- a/nvx-rs/src/host/template/mod.rs +++ b/nvx-rs/src/host/template/mod.rs @@ -95,3 +95,12 @@ pub use self::store::{ Retirement, SNAPSHOT_NAME, STORE_FORMAT, STORE_RECORD_NAME, StorageGeneration, Store, StoreId, TOMBSTONES_NAME, TRANSACTION_NAME, }; + +impl Generation { + /// Returns whether a clone may restore the generation at the host's time `now`, by the + /// restore window of its capture's time contract, as [`TimeContract::eligibility`] decides + /// it. + pub fn eligibility(&self, now: &HostTime) -> Eligibility { + self.time().eligibility(now) + } +} diff --git a/nvx-rs/tests/fixtures/template/README.md b/nvx-rs/tests/fixtures/template/README.md index 62eef3eb8..337184a62 100644 --- a/nvx-rs/tests/fixtures/template/README.md +++ b/nvx-rs/tests/fixtures/template/README.md @@ -3,7 +3,7 @@ Each directory holds the `manifest.bin` of a template's capture, as OpenVMM writes it: one `openvmm.snapshot.SnapshotManifest` of version 2 of OpenVMM's snapshot format, in the protobuf wire format of its `mesh`. The tests of -`nvx::host::template` read them with `TemplateManifest::read`, so that the +`nvx::host::snapshot` read them with `SnapshotManifest::read`, so that the reader is checked against bytes that OpenVMM's own code wrote, rather than against its own idea of them. diff --git a/tests/runtime-adapter/README.md b/tests/runtime-adapter/README.md index c25cdcc81..4ff575ec0 100644 --- a/tests/runtime-adapter/README.md +++ b/tests/runtime-adapter/README.md @@ -1448,8 +1448,7 @@ command's options choose of the template, and `Request::capture` returns NVX's capture refuses one that anyone else may change; - the capture class, from which the store takes the slot that serializes the class's captures, and the template's compatibility key: the runtime identity - of the adapter's VMs, with the guest agent's build, - `runtime-adapter-guest/BUILD`, the backend and the CPU profile, the + of the adapter's VMs, the backend and the CPU profile, the processors, those online at boot, 1 unless the command names more, the fewest that the template's clones take, the RAM and its capacity, the geometries of the placeholder and of the dormant scratch, as OpenVMM presents @@ -1457,7 +1456,9 @@ command's options choose of the template, and `Request::capture` returns NVX's the capture attaches its NIC, which no network's policy changes, and, for a template whose clones delay their repair, for tests, the delay, in milliseconds, as its one invariant setting, - `runtime-adapter.repair-delay-ms`, so that the class is one of its own; + `runtime-adapter.repair-delay-ms`, so that the class is one of its own. The + class also records the guest agent's build, `runtime-adapter-guest/BUILD`, + which the compatibility key does not hold; - NVX's artifacts, with the initramfs that puts the guest agent in place of NVX's agents, and holds the file of the delay of each clone's repair, if the template has one, which the command writes into a directory of its own in the @@ -2905,7 +2906,7 @@ Unless a test says otherwise, a template has 1 processor, online at boot, 256 MiB of RAM, its capacity, and a 64 MiB scratch. A captured template is the store's one generation, whose payload holds the record of its capture, its key, and its snapshot, and whose key holds what the test asked for: the runtime -identity of the adapter's VMs with the guest agent's build, the backend, the +identity of the adapter's VMs, the backend, the processors and those online at boot, none for a template whose processors are all online at boot, the RAM and its capacity, the geometries of the placeholder and of the scratch, the NIC, and a kernel command line of the platform tier's