Repository navigation
Description
Parent: #1076. Phase: 2, the new interface, beside the old one. Needs: #1077; inside phase 2, groups of #1079, #1081 (see the table below). Unblocks: #1085, #1086, #1087, #1088, #1090.
Goal. The guest's space (guest::{root, gpt}, the mapper of guest::mappings and the activation's apply) becomes NVX's internal reference code, while MappingTable and the mapping values stay public: it stays in nvx for its current users, hidden from the docs and documented as unstable, until #1088 makes it crate-private where it is. It gains the runtime filesystems, one root switch and a VM-wide view. In the public guest surface, the activation holds no fence and starts no process, and a capture is one call, which also repairs a restore.
Today (dev e42b1795) and after:
| Area | Today | After |
|---|---|---|
| Guest space | Public guest::{root, mappings, gpt} and the activation's apply family. |
The mapper splits from the public mapping values and MappingTable, which stay. The rest is hidden reference code, with Root::{mount_runtime, switch} and view::apply; the same code, crate-private from #1088. |
| Runtime filesystems | Each exec mounts /proc, /sys, /dev, /dev/pts and /dev/shm; the time status is bound into the root once; /run isn't mounted per exec. |
Root::mount_runtime(time_status), once: nosuid,nodev on the tree first; /proc, /sys (read-only), /dev, /dev/pts, /dev/shm and /run; the time status, read-only, at /run/nvx/time. |
| Root switch | Each exec, in its own mount namespace, moves the root onto /, then calls chroot and chdir. |
Root::switch: move the root onto /, then chroot and chdir, once for the whole VM. Afterwards teardown refuses, and nothing unmounts the root. |
| View | Split: each exec's entry sets its hostname, and one-time binds put the machine ID, the time status and the resolver file into the root; a restore's activation writes the resolver file. | view::apply(&mut Root, &View, dns): the hostname for the whole VM, the machine ID and the resolver file with the DNS server; the root records their binds. |
| Activation | guest::clone, with an admission fence; it starts the announcer. |
guest::activation: Activation holds no fence. apply starts no process and reports the publication and the gateway, so the init starts /sbin/nvx-ingress itself, before its switch. |
| Capture | CapturePreparation, CaptureBarrier, AdmissionFence, and a public repair. |
guest::snapshot::capture(devices: &Devices, disks: Disks, deadline: Instant) -> Result<Captured, CaptureFailure>, with the non-exhaustive Disks::Fresh. It neither freezes nor checks executions. It returns Continued or Restored(Repaired), or a failure whose disposition is Resumed or MustEnd { status }. Devices names the devices by their MMIO windows. |
Groups, in order. Each group issue lists its PRs, with their goals, contents, Needs and estimates.
| Group issue | Delivers | PRs | Needs |
|---|---|---|---|
| #1104 | The guest's space becomes reference code, with runtime mounts, one switch and the view | SL7.0, SL7.1a, SL7.1b, SL7.2 | #1091, #1098 |
| #1105 | Activation holds no fence, and a capture is one guest call | SL7.3, SL7.4a, SL7.4b | #1101, #1104 |
Notes.
- The space's interface is a guideline.
doc/guest-agent-guidelines.md(nvx-rs slimming, phase 5.2: the docs, and the release #1090) gives it with its rules: inputs only from the public codecs;nosuid,nodevfirst;/sysand the time status read-only; the RAM upper'ssize=N%;MachineIdMode::Imagekeeps the image's own machine ID; the descriptors that a later step needs, and every helper, before the switch; one switch. guest::clonebecomesguest::activation, with an alias until the test adapter goes (nvx-rs slimming, phase 4.1: acceptance on real VMs, then the test adapter goes #1086).- Strict capture.
captureruns the time ABI's checks strictly, so a violation returnsMustEndinstead of stopping the VM; every step and wait before the request, the runtime lock's included, honors the deadline, and the request itself has none; and aPortReleaseat any stage isMustEnd. - The transport rule. The guest answers the host's capture request, then sends nothing until
capturereturns. AfterRestored, it takes the session's reset and attaches again; afterContinuedorResumed, it reports on the same session.
Tests. Hiding the space breaks none of its current users, and the rustdoc shows only the public guest surface. mount_runtime applies nosuid,nodev first; mounts /proc, /sys read-only, /dev, /dev/pts, /dev/shm and /run; binds the time status read-only at /run/nvx/time when asked; and undoes its mounts if one fails. switch runs once; afterwards teardown refuses and dropping the root unmounts nothing, and TargetRoot and SourceRoot opened before it still map. view::apply sets the VM's hostname; leaves the image's own /etc/machine-id with MachineIdMode::Image, or generates one and binds it over the image's with Generated; writes and binds the resolver file when given a DNS server (#860); and a teardown before the switch undoes its binds. Activation holds no fence; apply starts no process, Applied::{publication, gateway} report the publication and the gateway, and Applied::into_parts returns (Root, MachineId) while the root keeps the view's binds; the test adapter follows. capture returns Continued when no snapshot was taken, and Restored(Repaired) only after the repair succeeds, with Repaired::{generation_id, cpus, memory, acknowledged_at}. Every step and wait before the request, the runtime lock's included, honors the deadline, and the request itself has none. Each stage's failure has its disposition; a strict time-ABI violation is MustEnd with the violation's status; a PortRelease is MustEnd, and stays the cause even if a rollback also fails; and a failed repair is MustEnd.
Done when: every group issue is closed. With the other subphases of phases 1 and 2, this completes the API-ready commit.
Activity
nvxa library of mechanisms and value types #1076