Skip to content

nvx-rs slimming, phase 3.3: nvx-init boots, captures and restores layered roots #1085

Closed
3 of 3 issues completed

Description

Parent: #1076. Phase: 3, NVX's own binaries on the new interface. Needs: #1077, #1082; inside phase 3, groups of #1083, #1084 (see the table below). Unblocks: inside phase 3, groups of #1083, #1084; #1086, #1087, #1089, #1090. The lanes of phase 3 meet at group level, never in a cycle: each group issue names the groups that it needs.

Goal. nvx-init boots a layered root as PID 1 (#817): new code lives under the hidden guest::init module, builds the space where it is, switches into it once, and runs each exec as a plain process. The managed agent stays in guest::managed_agent; its direct mode shares nvx-init's exec core, and layered roots and managed blockless VMs share its NVXC loop. nvx-init captures when the host asks, activates a restore, and becomes the init of the layered roots and capture VMs that the new launches start; the old CLI paths keep the old layered init until the CLI replaces them.

Today (dev e42b1795) and after:

Area Today After
Layered init The shell nvx-init-agent: one-shot roots run through the container helpers (nvx-container-launch and nvx-container-enter), and managed roots hand their executions to nvx-managed-agent. The nvx-init binary over hidden guest::init, always managed, for the layered roots and capture VMs of the new launches; sandbox run becomes a cold boot, one exec and a stop in #1111. The old paths stay until #1110 and #1111 replace them.
Executions guest::{exec, spawn, process, cgroup, entry}, with a cgroup and namespaces per exec. A fork and exec in its own process group. The child resets oom_score_adj and nice, sets its credentials (no supplementary groups, empty capability sets, no_new_privs), changes to its working directory, and execs. No cgroups, no namespaces, no limits.
Priority None. PID 1 and its helpers run with oom_score_adj -1000 and nice -10.
Helpers Two long-running processes, which the shell starts and nothing tracks: the time daemon, which nvx-time boot forks, and, when listeners are published, the announcer /sbin/nvx-ingress. The same two processes, registered with nvx-init. The shell /init starts them before the switch and hands their process IDs to nvx-init; after a restore, nvx-init starts /sbin/nvx-ingress itself, after apply and before its switch. The VM ends if a helper fails. nvx-init runs no other guest tool: the capture's repair reseeds in process, and nvx-init powers off itself.
Capture The shell nvx-snapshot. NVXC's capture request: refuse while an execution runs or, when the request asks, kill the process groups and sweep every process but PID 1 and its helpers; then snapshot::capture; after MustEnd, power off with its status.
Restore The shell nvx-snapshot resumes a captured guest; the layered init has no activation protocol. Attach again; accept the activate message; Activation; apply; the runtime mounts; the announcer when listeners are published; the switch; completion; Ready; then the mapping table and Start.

Groups, in order. Each group issue lists its PRs, with their goals, contents, Needs and estimates.

Group issue Delivers PRs Needs
#1115 nvx-init boots a layered root, and runs each exec as a plain process SL7.5a, SL7.5b, SL7.5c, SL7.5d #1091, #1104, #1105
#1116 The managed agent's direct mode runs on nvx-init's exec core SL7.6a, SL7.6b #1109, #1115
#1117 nvx-init captures and restores, and boots the new launches' layered roots SL7.7a, SL7.7b, SL7.8a #1105, #1113, #1115, #1116

Notes.

Tests. PID 1's signals, reaping, console, exit statuses, priority, and shutdown by sync and power-off; the registry of the two helpers, and the VM's end when one fails. A cold boot parses the root's and the view's tokens, nvx_maps and nvx_share, the RAM upper's cap included, then assembles the root, mounts the export, the shares and the runtime filesystems, applies the view and switches once. Each exec's pipes, signals, exit status, credentials, default environment and PWD, and the end of a process group. Layered and blockless managed roots share the NVXC loop, and the direct-mode agent no longer announces EXEC_CGROUP. A capture is refused while an execution runs; when the request asks, the executions' process groups are killed, then every other process but PID 1 and its helpers is swept; nothing is sent until capture returns. A restore runs in order, and keeps the applied space, the mapper, the source root, the helpers and the Activation. The initramfs contains nvx-init; a layered root with OpenVMM's lifecycle token still boots through the old layered init, and a capture VM reaches nvx-init's capture loop without a root.

Done when: every group issue is closed, and the layered roots and capture VMs that the new launches start boot through nvx-init.

Activity

  1. ppenna commented on Nov 11, 2026

    @ppenna
    Contributor

    All three groups of this subphase are complete and closed: #1115 (nvx-init boots a layered root and runs plain-process execs), #1116 (SL7.6a #1310, SL7.6b #1421) and #1117 (SL7.7a #1431, SL7.7b #1447, SL7.8a #1453). Every PR has merged into feature/nvx-refactor, whose post-merge CI run at 394c89025e passed: https://github.com/microsoft/nvx/actions/runs/42952780739. Closing the subphase as complete.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

No labels
No labels

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions