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
6 changes: 3 additions & 3 deletions doc/acceptance-case-matrix.md
Original file line number Diff line number Diff line change
Expand Up @@ -480,7 +480,7 @@ 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 195)` | kept | Its capture preparation and admission fence leave (#1087), whose PR rewrites it on `guest::snapshot::capture` |
| `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/state.rs - guest::activation::state::Activation (line 56)` | kept | |
| `nvx-rs/src/guest/cgroup.rs - guest::cgroup (line 36)` | kept | Its module leaves with the exec engine (#1087), whose PR retires it |
| `nvx-rs/src/guest/entry.rs - guest::entry (line 90)` | kept | Its module leaves with the exec engine (#1087), whose PR retires it |
Expand All @@ -489,7 +489,7 @@ this matrix. The README's own code is no doctest.
| `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/table.rs - guest::mappings::table::MappingTable (line 47)` | kept | |
| `nvx-rs/src/guest/mod.rs - guest (line 40)` | kept | The guest-agent guidelines quote it |
| `nvx-rs/src/guest/mod.rs - guest (line 39)` | 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)` | kept | Its module leaves with the exec engine (#1087), whose PR retires it |
| `nvx-rs/src/guest/process.rs - guest::process (line 39)` | kept | Its module leaves with the exec engine (#1087), whose PR retires it |
Expand All @@ -499,7 +499,7 @@ this matrix. The README's own code is no doctest.
| `nvx-rs/src/guest/spawn.rs - guest::spawn (line 41)` | kept | Its module leaves with the exec engine (#1087), whose PR retires it |
| `nvx-rs/src/guest/spawn.rs - guest::spawn::LaunchStage::from_code (line 201)` | rewritten | `nvx-rs/src/guest/spawn/tests.rs::launch_stages_keep_their_numbers`. The exec engine's launch failure and outcome, which the example read, leave with the engine (SL6.11a) |
| `nvx-rs/src/guest/terminal.rs - guest::terminal (line 10)` | kept | |
| `nvx-rs/src/guest/time/mod.rs - guest::time (line 15)` | kept | |
| `nvx-rs/src/guest/time/mod.rs - guest::time (line 9)` | kept | SL6.11c removed its capture and restore finish, which became crate-private: `guest::snapshot::capture` runs them |
| `nvx-rs/src/host/sandbox/prepared.rs - host::sandbox::prepared::PreparedLaunch (line 92)` | kept | Its launch type leaves with the old launch paths (#1087), whose PR retires it |
| `nvx-rs/src/host/store/mod.rs - host::store (line 72)` | retired | The sandbox store leaves (SL6.1, #1121) |
| `nvx-rs/src/host/supervisor/mod.rs - host::supervisor (line 32)` | retired | The store-coupled supervisor leaves with the sandbox store (SL6.1, #1121); `host::supervisor` stays only as the transitional public path of the low-level spawn, until SL6.3 (#1122), with no doc test |
Expand Down
7 changes: 4 additions & 3 deletions doc/guest-agent-guidelines.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,10 @@ The library's calls leave all of this to the init:
listeners, then replaces itself with nvx-init, which inherits both as its
children.

One other call starts processes, which an init can avoid: a report-only
[`TimeAbi::restore_finish`](../nvx-rs/src/guest/time/api.rs), which
`capture`'s repair calls, runs the restore's deferred time work itself when
One other call starts processes, which an init can avoid: `capture`, whose
repair finishes the restore through the time ABI's private
[`TimeAbi::restore_finish`](../nvx-rs/src/guest/time/api.rs). In report-only
mode, the finish runs the restore's deferred time work itself when
no time daemon runs, in a calling process that must have no other thread: it
forks a child, which waits for a grandchild that forces an RCU grace period,
and collects only the child, so a grandchild that outlives the RCU stall
Expand Down
115 changes: 41 additions & 74 deletions nvx-rs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,9 +139,9 @@ changes only when the module's purpose does.
| [`nvx::guest::process`](#nvxguestprocess) | `Child`: the status of one child that the caller names, and of no other |
| [`nvx::guest::cgroup`](#nvxguestcgroup) | Cgroup v2 handles through which a guest init or agent places, accounts, kills, and settles its executions |
| [`nvx::guest::exec`](#nvxguestexec) | `Execution`: drives one program as an execution, for any guest init or agent |
| [`nvx::guest::time`](#nvxguesttime) | x86_64: the steps of NVX time ABI v1 as typed calls in the caller's process, for any guest init or agent |
| [`nvx::guest::time`](#nvxguesttime) | x86_64: the boot steps of NVX time ABI v1 as typed calls in the caller's process, for any guest init or agent |
| [`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, with the retained template capture and clone repair interface |
| [`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 bootstrap, assembly, shares, export, mappings, and teardown |
| [`nvx::guest::view`](#nvxguestview) | The VM-wide hostname, machine ID, and single-server resolver, whose binds the layered root owns |
Expand Down Expand Up @@ -1438,23 +1438,22 @@ NVX's managed agent is one caller.

### `nvx::guest::time`

x86_64: `TimeAbi`, the steps of NVX time ABI v1 as typed calls in the caller's
process, for any guest init or agent: the cold-boot time step and, separately,
the start of the time daemon in a child process that the caller supervises, the
VM generation ID, a `CaptureRequest` that repairs a `Restore`, and a
`RestoreFinish`.
x86_64: `TimeAbi`, the boot steps of NVX time ABI v1 as typed calls in the
caller's process, for any guest init or agent: the cold-boot time step and,
separately, the start of the time daemon in a child process that the caller
supervises, and the VM generation ID.

The request's mode selects how a restore hands over its fresh entropy: the file
mode, which `nvx-time` keeps, writes it to a file, and the in-memory mode
returns it as the `Restore`'s owned `Seed`, and writes no file.
The ABI's capture request, which repairs the time of a restore, and the
restore's finish are private: `nvx::guest::snapshot::capture` runs them, and
hands the restore's fresh entropy to its repair in memory, as an owned `Seed`,
while `nvx-time capture` writes it to a file.

A violation of the ABI stops the VM in enforcing mode, with the time ABI's
status, as `nvx-time` does; in strict mode, `TimeAbi::strict`, which a caller
that owns the VM's exit status and shutdown selects, the call fails with the
`Violation`, whose `status` is the one with which enforcing mode stops the VM,
and the time daemon and the legacy activation capture's preparation enforce
the ABI all the same. The single-call snapshot capture below uses strict
preparation instead.
and the time daemon enforces the ABI all the same, while the single-call
snapshot capture below prepares strictly.

A call takes the permission for OpenVMM's ports on the calling thread for each
port transaction alone, and fails with `TimeError::PortRelease` if the thread
Expand Down Expand Up @@ -1496,74 +1495,42 @@ The caller owns its transport. After answering the capture request, send
nothing until `capture` returns. After `Continued` or a `Resumed` failure,
report on the same session. After `Restored`, take the session's RESET, then
call `GuestConnection::acknowledge(window)` on that session before receiving
the activation record. The activation module retains its legacy Device-shaped
capture and repair interfaces.
the activation record.

### `nvx::guest::activation`

x86_64: the preparation of a template's guest for a capture before its root's
assembly, and the repair of each clone that a restore of its snapshot starts,
for a guest init or agent, whether or not it is PID 1.
x86_64: the activation of each clone that a restore of a template's snapshot
starts, once `nvx::guest::snapshot::capture` repaired it, for a guest init or
agent, whether or not it is PID 1.

`nvx::guest::clone` remains a compatibility alias. Activation itself holds no
admission fence and starts no process; the older capture interface below
retains its caller-owned fence.

`CapturePreparation`, of the caller's `AdmissionFence` and the `Devices` that
the template's clones replace, the `distro` and scratch block devices, which
their MMIO windows name, and the host filesystem device's virtio-fs tag:
`prepare` closes the fence, so that no execution starts, refuses with a
`Mounted` the first mount from those devices, a distro partition included, or
from an overlay, bind mounts included, in a bounded read of
`/proc/self/mountinfo` of at most `MOUNT_TABLE_LIMIT` bytes, then waits for the
time ABI's boot checks, runs its capture checks, and suppresses the stall
detectors, as `nvx-time pre-capture` does, and returns an owned
`CaptureBarrier`.

`CaptureBarrier::capture` requests the capture with the platform tier's request,
in the in-memory mode, through `TimeAbi::capture`, and returns
`Captured::Continued` once it opened the fence and restored the detectors'
settings, or, in a clone, `Captured::Restored`, with the fence still closed,
since nothing else may run before repair acknowledges the restore, and the
detectors suppressed until the time daemon restores their settings:
`Restored::into_parts` hands the `Restore` that repair takes next, which holds
the restore's `Seed`, and the closed fence to the caller, which keeps it closed
through the repair and opens it once the clone may admit executions, such as
once it is activated.

`CaptureBarrier::cancel`, a dropped barrier, and a failure to read the VM
generation ID open the fence and restore the detectors' settings; a capture
request that fails restores the settings but leaves the fence closed, since it
may fail in a clone whose restore it could not repair. Each failure is a
`CaptureError`, with its `CaptureStage` and `CaptureCause`.

`repair`, or a `Repair` that the caller may retry, repairs the clone of a
`Restore` next: it checks that the online CPUs are a prefix that the restore's
processor target does not undercut, brings the target's other CPUs online
through sysfs, and verifies them; with a memory target, it checks, before it
adds any memory block, that the kernel's block size is 128 MiB and that the
restore's ranges continue the captured RAM in logical order, with no gap,
overlap, or range in the MMIO aperture, while the host bounds the target by the
snapshot's capacity, then adds and onlines the blocks through sysfs, as
`nvx-snapshot` does, and verifies them; it reseeds the kernel's random number
generator with the `Seed`, having drawn no randomness before, and drops it; and
it finishes the restore through `TimeAbi::restore_finish`, with the CPUs that
the restore brought online and the acknowledgement when the host gates its input
until then, which hands the deferred time work to the time daemon that the
caller supervises.
admission fence and starts no process.

In a clone, the capture repairs the restore before it returns: it checks that
the online CPUs are a prefix that the restore's processor target does not
undercut, brings the target's other CPUs online through sysfs, and verifies
them; with a memory target, it checks, before it adds any memory block, that
the kernel's block size is 128 MiB and that the restore's ranges continue the
captured RAM in logical order, with no gap, overlap, or range in the MMIO
aperture, while the host bounds the target by the snapshot's capacity, then
adds and onlines the blocks through sysfs, as `nvx-snapshot` does, and verifies
them; it reseeds the kernel's random number generator with the `Seed`, having
drawn no randomness before, and drops it; and it finishes the restore through
the time ABI, with the CPUs that the restore brought online and the
acknowledgement when the host gates its input until then, which hands the
deferred time work to the time daemon that the caller supervises.

It returns the `Repaired` clone, with its generation ID, its online CPUs and
memory, and when it acknowledged the restore, and never touches the fence. It
adds no memory block twice, and reseeds and finishes at most once, so a failure
at or after the reseed is final.
memory, and when it acknowledged the restore. It adds no memory block twice,
and reseeds and finishes at most once.

Each failure is a `RepairError`, with its `RepairStage`, its `RepairCause`, and
the repair's `RepairProgress`, and `RepairError::status` selects the status, of
`nvx::protocol::status`, with which the caller ends the VM.

The capture and the repair take the time ABI in strict mode, so that a violation
of it fails them, with its status, rather than stopping the VM, and only the
capture's preparation and the time daemon enforce it.
time daemon enforces it.

An `Activation` of the `Repaired` clone, or, with `Activation::with_resources`,
of the resources and the instant of the acknowledgement that a repair reports,
Expand Down Expand Up @@ -2945,14 +2912,14 @@ their host mapping table through
`mappings`, from its mount of the host's export, beneath `/` in direct mode and
beneath the container's assembled root in sandbox mode, where it unmounts the
table before it returns to the init agent, and any other guest init or agent
can use them too. Any guest init or agent can also run the steps of `nvx-time`
and `nvx-reseed` in its own process, through the
can use them too. Any guest init or agent can also run the boot steps of
`nvx-time` and the steps of `nvx-reseed` in its own process, through the
`nvx::guest::time` and `nvx::guest::reseed` calls, on which both programs run,
and a template's guest prepares for a capture before its root's assembly through
`nvx::guest::clone`, which runs the steps of `nvx-time pre-capture` behind the
caller's fence of workload admission, and through which each clone repairs its
restore: it activates the restore's memory target, reseeds the kernel's random
number generator, and finishes the restore, as `nvx-snapshot` does.
and a template's guest captures before its root's assembly through
`nvx::guest::snapshot::capture`, which runs the steps of `nvx-time pre-capture`
and, in each clone, repairs its restore: it activates the restore's memory
target, reseeds the kernel's random number generator, and finishes the restore,
as `nvx-snapshot` does.
Nor is the hidden `gpt` module a program: it reads the partition table of a GPT
disk's block device.

Expand Down
Loading
Loading