Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions doc/acceptance-case-matrix.md
Original file line number Diff line number Diff line change
Expand Up @@ -222,15 +222,15 @@ The adapter's README said what each proved.
| --- | --- | --- |
| `a_clone_binds_the_resolver_of_its_policy_s_dns_server_read_only` | rewritten | `test-microvm --scenario untiered-network-policy`, whose restored guests' resolvers name exactly the DNS server of their policies; `test-microvm --scenario network-snapshot`; `nvx-rs/src/guest/root/tests/view.rs::actual_resolver_failures_keep_the_network_class_and_root_owned_bind` |
| `a_clone_maps_an_aggregate_of_directories_and_files_beneath_its_root_before_its_sandbox_starts` | rewritten | `test-microvm --scenario platform-aggregate-export`; `nvx-rs/src/guest/mappings/table/tests.rs::mappings_keep_the_paths_and_the_access_of_their_entries` |
| `a_clone_of_a_template_with_a_nic_maps_its_export_beside_its_resolver` | rewritten | `nvx-rs/src/guest/activation/state/apply/tests.rs::the_record_s_view_is_applied_once_with_its_own_dns_and_returned_machine_id`; `test-microvm --scenario filesystem-snapshot` |
| `a_clone_of_a_template_with_a_nic_maps_its_export_beside_its_resolver` | rewritten | `nvx-rs/src/guest/activation/state/apply/tests.rs::the_record_s_view_is_applied_once_with_its_own_dns`; `test-microvm --scenario filesystem-snapshot` |
| `a_clone_reads_no_more_of_its_disks_than_its_root_needs` | rewritten | A restore reads no content of its disks or snapshot: `nvx-rs/src/host/snapshot/tests.rs::snapshot_accepts_never_reopens_snapshot_paths_or_reads_runtime_artifacts`; `nvx-rs/src/host/sandbox/distro/tests.rs::the_staged_check_reads_no_content`; `nvx-rs/src/host/sandbox/scratch/tests.rs::checks_claim_the_image_without_reading_it`. The adapter's in-guest read statistics retire |
| `a_clone_refuses_a_scratch_image_whose_upper_an_earlier_clone_used` | rewritten | `nvx-rs/src/guest/root/tests.rs::a_fresh_upper_s_directories_must_be_missing_or_empty` |
| `a_clone_runs_the_executions_that_name_their_identity_once_it_is_ready` | retired | Executions that name their identities leave with the exec engine (#1087) |
| `a_clone_s_executions_find_the_proxy_of_its_policy` | rewritten | `nvx-rs/src/guest/managed_agent/launch/tests.rs::restored_proxy_defaults_replace_template_values_before_exec_overrides`; `test-microvm --scenario platform-network-policy` |
| `a_clone_s_time_settles_after_it_is_ready` | rewritten | `test-microvm --scenario time-host-correction`; `test-microvm --scenario restore-downtime` |
| `a_clone_whose_activation_fails_ends_before_it_is_ready` | rewritten | `nvx-rs/src/host/restore/tests.rs::restore_failures_attribute_the_existing_policy_free_evidence_classes`; `nvx-rs/src/host/restore/tests.rs::restore_exit_reports_keep_guest_status_classification_and_actual_details`; `nvx-rs/src/guest/init/boot/tests.rs::a_failed_activation_ends_the_vm_with_the_status_of_its_class`; `nvx-rs/src/guest/managed_agent/session/tests.rs::a_failed_restored_activation_gives_init_the_status_of_its_class`; `nvx-rs/src/host/cli/sandbox/lifecycle/start/tests/restore.rs::a_restore_that_fails_before_its_guest_is_ready_reports_its_attribution`; `test-microvm --scenario snapshot-core`, whose restore over a zeroed scratch image ends its VM before its workload runs, with nvx-init's status of an unusable root, 54, which the CLI attributes to the request. Quarantine and leases retire (#1121) |
| `a_clone_whose_mapping_fails_ends_before_its_sandbox_starts` | rewritten | `nvx-rs/src/guest/mappings/mapper/tests.rs::a_failure_at_any_step_leaves_nothing_mounted`; `nvx-rs/src/guest/mappings/table/tests.rs::a_failed_mapping_keeps_those_before_it_and_latches_the_table` |
| `a_clone_whose_view_cannot_be_set_ends_before_it_is_ready` | rewritten | `nvx-rs/src/guest/activation/state/apply/tests.rs::the_record_s_view_is_applied_once_with_its_own_dns_and_returned_machine_id`; `nvx-rs/src/guest/root/tests/view.rs::a_later_bind_failure_stays_owned_and_its_teardown_removes_the_earlier_bind` |
| `a_clone_whose_view_cannot_be_set_ends_before_it_is_ready` | rewritten | `nvx-rs/src/guest/activation/state/apply/tests.rs::the_record_s_view_is_applied_once_with_its_own_dns`; `nvx-rs/src/guest/root/tests/view.rs::a_later_bind_failure_stays_owned_and_its_teardown_removes_the_earlier_bind` |
| `a_clone_whose_vm_exits_once_a_stop_found_it_fails_before_its_lease_is_released` | retired | Clone records and leases leave with the old clone path (#1121). A stop that finds an exit: `nvx-rs/src/host/vm/tests.rs::stop_preserves_report_results_after_a_real_self_exit` |
| `a_forward_whose_port_another_socket_holds_fails_the_clone_as_the_host_s` | rewritten | `test-microvm --scenario platform-network-policy`; `nvx-rs/src/host/restore/tests.rs::restore_failures_attribute_the_existing_policy_free_evidence_classes` |
| `a_generation_is_eligible_by_the_clock_of_its_capture` | rewritten | `nvx-rs/src/host/snapshot/eligibility/tests.rs::within_one_boot_the_downtime_is_the_host_monotonic_clocks`; `nvx-rs/src/host/snapshot/tests.rs::snapshot_accepts_reports_early_and_expired_time_as_unavailable` |
Expand Down Expand Up @@ -478,21 +478,21 @@ this matrix. The README's own code is no doctest.
| `nvx-rs/src/activation/mod.rs - activation (line 130)` | kept | |
| `nvx-rs/src/exec/mod.rs - exec (line 113)` | retired | The exec engine leaves (SL6.11a) |
| `nvx-rs/src/gpt/mod.rs - gpt (line 43)` | kept | |
| `nvx-rs/src/guest/activation.rs - guest::activation (line 158)` | kept | SL6.11c rewrote it on `guest::snapshot::capture`, when its capture preparation and admission fence left (#1087) |
| `nvx-rs/src/guest/activation.rs - guest::activation (line 157)` | kept | SL6.11c rewrote it on `guest::snapshot::capture`, when its capture preparation and admission fence left (#1087) |
| `nvx-rs/src/guest/activation/state.rs - guest::activation::state::Activation (line 56)` | kept | |
| `nvx-rs/src/guest/cgroup.rs - guest::cgroup (line 36)` | retired | `guest::cgroup` leaves (SL6.11b) |
| `nvx-rs/src/guest/entry.rs - guest::entry (line 90)` | retired | `guest::entry` leaves (SL6.11b) |
| `nvx-rs/src/guest/exec.rs - guest::exec (line 79)` | retired | `guest::exec` leaves (SL6.11b) |
| `nvx-rs/src/guest/exec.rs - guest::exec::Execution::adopt (line 619)` | retired | `guest::exec` leaves (SL6.11b) |
| `nvx-rs/src/guest/gpt.rs - guest::gpt (line 18)` | kept | The guest's space becomes private (#1127), whose PR moves it to the space's unit tests |
| `nvx-rs/src/guest/mappings/mapper.rs - guest::mappings::mapper (line 107)` | kept | The guest's space becomes private (#1127), whose PR moves it to the space's unit tests |
| `nvx-rs/src/guest/mappings/mapper.rs - guest::mappings::mapper (line 107)` | kept | SL6.11d (#1123) moved it to the mapper's unit tests, `nvx-rs/src/guest/mappings/mapper/tests.rs::a_mapper_s_steps_compile`, which map and unmount through the seams that NVX's programs use, since the mapper's `apply` and `teardown`, which only tests used, left |
| `nvx-rs/src/guest/mappings/table.rs - guest::mappings::table::MappingTable (line 47)` | kept | |
| `nvx-rs/src/guest/mod.rs - guest (line 34)` | kept | The guest-agent guidelines quote it |
| `nvx-rs/src/guest/nvxs.rs - guest::nvxs (line 22)` | kept | |
| `nvx-rs/src/guest/process.rs - guest::process (line 12)` | retired | `guest::process` leaves (SL6.11b) |
| `nvx-rs/src/guest/process.rs - guest::process (line 39)` | retired | `guest::process` leaves (SL6.11b) |
| `nvx-rs/src/guest/reseed.rs - guest::reseed (line 17)` | kept | |
| `nvx-rs/src/guest/root.rs - guest::root (line 126)` | kept | SL6.11b removed its bootstrap, which left with the cgroups. The guest's space becomes private (#1127), whose PR moves it to the space's unit tests |
| `nvx-rs/src/guest/root.rs - guest::root (line 126)` | kept | SL6.11b removed its bootstrap, which left with the cgroups. SL6.11d (#1123) moved it to the root's unit tests, `nvx-rs/src/guest/root/tests.rs::a_layered_root_s_steps_compile`, without the first partition's bytes, the layers and `Root::map`, which only tests used, and which left |
| `nvx-rs/src/guest/snapshot.rs - guest::snapshot (line 25)` | kept | The guest-agent guidelines quote it |
| `nvx-rs/src/guest/spawn.rs - guest::spawn (line 41)` | retired | `guest::spawn` leaves (SL6.11b) |
| `nvx-rs/src/guest/spawn.rs - guest::spawn::LaunchStage::from_code (line 201)` | retired | `LaunchStage::from_code` and its test, `launch_stages_keep_their_numbers`, leave with `guest::spawn` (SL6.11b). The stages of nvx-init's executions keep their numbers in the crate's own fork boundary, whose launch report `nvx-rs/src/guest/init/tests/exec.rs::native_workload_cwd_accepts_procfs_links_but_closes_inherited_descriptors` reads from a real launch |
Expand Down
44 changes: 19 additions & 25 deletions nvx-rs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ changes only when the module's purpose does.
| [`nvx::guest::snapshot`](#nvxguestsnapshot) | x86_64: bounded Fresh capture with inline restore repair and staged failure dispositions, without execution control |
| [`nvx::guest::activation`](#nvxguestactivation) | x86_64: fence-free activation of each clone that its capture repaired |
| [`nvx::guest::reseed`](#nvxguestreseed) | A restore's fresh entropy, and the reseed of the kernel's random number generator with it |
| [`nvx::guest::root`](#nvxguestroot) | The operations of a layered root: its assembly, shares, export, mappings, and teardown |
| [`nvx::guest::root`](#nvxguestroot) | The operations of a layered root: its assembly, shares, export, and teardown |
| [`nvx::guest::view`](#nvxguestview) | The VM-wide hostname, machine ID, and single-server resolver, whose binds the layered root owns |
| [`nvx::guest::gpt`](#nvxguestgpt) | `read_disk`: the partition table of a GPT disk, read and checked through its block device |

Expand Down Expand Up @@ -1120,11 +1120,12 @@ restricted `nosuid`, `nodev`, and read-only when asked, `mount_setattr`, before
do no work; the first that fails is reported with its index as an `ApplyError`,
and latches the mapper.

`Mapper::teardown` detaches a mapping that a rename moved and that the attach
failed to detach, then unmounts the mappings in reverse order, and reports each
failure.
A layered root's teardown, which unmounts its mapper's mappings, first detaches
a mapping that a rename moved and that the attach failed to detach, then
unmounts the mappings in reverse order, and reports each failure.

`bind` applies one runtime bind through the same walk and attach.
A runtime bind, such as the view's machine ID, goes through the same walk and
attach.

`MappingTable` keeps a guest agent's account of a host mapping table: the
mappings that the host hands the agent in `MAPS` parts once it is ready, after
Expand All @@ -1136,16 +1137,16 @@ decode, holds no entry, does not continue the table, ends past the
announcement, or maps the export's root, which an empty source names, as a
`TableError::Refused` at the entry that it expects next, which changes nothing.
It hands the part's mappings to the caller, which applies them beneath the root
of its choice, such as through a `Mapper` or a layered `Root`; the first that
of its choice, such as through a `Mapper`; the first that
fails latches the table, which reports it as a `TableError::Failed` with its
entry, and refuses every later part. The table is complete once every announced
mapping is applied, and none failed, and the root's teardown tears it down.
mapping is applied, and none failed, and the caller's teardown tears it down.

Linux 6.8 or later. NVX's managed agent applies its host mapping table through
a `MappingTable` and a mapper, beneath `/` in direct mode; the table refuses an
empty source, since the export is an aggregate, whose root lists its children,
and NVX's hosts, whose exports are all aggregates, send none. A layered `Root`
applies its live shares and mappings through a mapper.
mounts its live shares through a mapper.

### `nvx::guest::nvxs`

Expand Down Expand Up @@ -1308,8 +1309,7 @@ export's `SourceRoot`, to map the host's mapping table from once the clone is
ready, `proxy` the network's proxy endpoint, which the adapter tells its
workloads as at a cold boot, and `publication` and `gateway`, from which its
caller starts and supervises ingress. Its `teardown` closes the export's root,
then tears the root down with its view binds; `into_parts` returns
`(Root, MachineId)`, retaining every bind in the root. A switched root unmounts
then tears the root down with its view binds. A switched root unmounts
nothing. A failure returns an
`ApplyError`, `Export` or `Network` among them, after which nothing that it
mounted or bound stays mounted unless the error reports the unmounts that
Expand Down Expand Up @@ -1378,9 +1378,6 @@ shows read-only or without the mode's options in effect, since the kernel mounts
one so, rather than fail, when its upper can't hold its work directory or its
extended attributes.

The `Root` reports the first partition's bytes, its `Lower` layers, its
`UpperKind`, and its `OverlayMode`.

`Root::mount_share` and `Root::mount_aggregate`: virtio-fs live shares at
targets in the root that it checks, against the targets that `protocol::share`
reserves among others, with one aggregate per root, which it attaches through
Expand All @@ -1392,23 +1389,21 @@ and a copy of each child's entry of the aggregate.
`protocol::export`, one per root, mounted `nosuid,nodev` with the access of its
`ExportMode` at `hostfs/root` in the runtime directory, out of the root, below a
directory that only root may enter, whose root it returns as the `SourceRoot` of
the caller's mappings.

`Root::map`: a caller's host mappings, through the same mapper. A share, a
child, the export, or a mapping that fails latches the root.
the caller's mappings, which the caller's own mapper applies. A share, a child,
or the export that fails latches the root.

`Root::mount_runtime`: the runtime's file systems, which an init mounts once
for its VM, before the root's first live share or mapping, after it makes every
for its VM, before the root's first live share, after it makes every
mount of the root's tree `nosuid,nodev`: procfs at `/proc`, sysfs at `/sys`,
read-only, a tmpfs at `/dev` with an execution's device nodes and links, devpts
at `/dev/pts`, and tmpfs at `/dev/shm` and `/run`, with an execution's options,
then the time status's directory, when the caller names one, bound read-only at
`/run/nvx/time`. It refuses a mount point that leads through a symbolic link or
where something is mounted already, and, before it changes anything, a call
while the root holds the runtime's mounts, whose `/dev` and `/dev/pts` a second
restriction would make `nodev`, or a live share or mapping, since the `/run`
restriction would make `nodev`, or a live share, since the `/run`
tmpfs would hide one beneath `/run` from the teardown. A call that fails
unmounts what it mounted. A later share or mapping beneath `/run` is on that
unmounts what it mounted. A later share beneath `/run` is on that
tmpfs, which the root's mapper owns, as a guest's mapper owns its `/tmp`.
Each attachment is checked at its named target before it is recorded. A runtime
mount whose attachment fails and which cannot be detached keeps its mount
Expand All @@ -1423,7 +1418,7 @@ refused, and dropping the root unmounts nothing, while descriptors opened before
the switch, such as a `TargetRoot` and a `SourceRoot`, still map. A move that
fails leaves the root where it was.

`Root::teardown`: the view's binds, then the shares and mappings in reverse order, a runtime mount whose
`Root::teardown`: the view's binds, then the shares in reverse order, a runtime mount whose
attachment failed and which could not be detached, then the mounts of an
aggregate, of the export, and of the runtime, the later first, the overlay,
the layers from the top down, and the upper, with every failed sync or unmount
Expand All @@ -1444,9 +1439,8 @@ Hidden, unstable internal reference code of the guest's space, like `root`.
hostname from the view's bytes. Image mode leaves `/etc/machine-id` untouched;
generated mode writes a new UUID at `MACHINE_ID_FILE` in the runtime directory
and binds it read-only over the image's ID. Optional DNS writes one server in
`RESOLVER_FILE` and binds it read-only over `/etc/resolv.conf`. The existing
`entry::MachineId` and hostname constants, and activation's file constants,
remain available through re-exports.
`RESOLVER_FILE` and binds it read-only over `/etc/resolv.conf`.
`nvx::guest::activation` re-exports both file constants.

The root owns every bind, including an attachment left by a failed call.
Teardown before the switch removes them; after the switch teardown refuses
Expand Down Expand Up @@ -2554,7 +2548,7 @@ account of a host's mapping table. NVX's own guest space is internal reference
code, hidden, unstable, and crate-private once nothing outside NVX uses it:
the mapper of `mappings` mounts host mappings beneath the descriptors of the
roots that its caller names, and `root` assembles a layered root, mounts live
shares and mappings in it through the mapper, and tears it down.
shares in it through the mapper, and tears it down.
`nvx-managed-agent` opens its control terminal and runs direct workloads through
nvx-init's plain-process core: each child resets its priority, drops its
credentials and capabilities, and enters its working directory before exec.
Expand Down
Loading
Loading