Repository navigation
Description
Parent: #1084, in #1076. Needs: #1101, #1103. Unblocks: #1114, #1117, #1118, #1130, #1131.
Goal. NVXC gains two messages: the capture request, with a flag that asks the init to kill its executions first, and the activate message, which carries the activation record and nvx-init's workload setup, a restore's workload identity included. ControlSession::capture sends the request. the private restore driver drives a restore over NVXC, blocking: it checks that the restore-ready client and the control server are the VM's process, sends the activate message on each session, races every pending accept, read and write against the step's deadline, the caller's cancellation and the VM's verified exit, and after Done sends MAPS and Start and returns the live ControlSession.
Notes.
- NVXC still lives in
nvx(nvx::protocol::app) and becomes private in nvx-rs slimming 4.3.4: NVXC, the host's platform layer and the guest's space are private #1127.
PRs, in order. Each PR has one goal, leaves dev green, and names in its description each old test of its area as kept, rewritten or retired, with each change that check_test_changes.py reports. Its tests follow the repository's test layout: a module's unit tests, and the code that only they use, sit in its tests.rs or tests/ and move with it. The estimates count core lines (code, not comments, docs or tests) and counted files; each PR records its measured values. Each PR does what its Scope says and no more: a case, input or layout that its Scope doesn't name, and whatever "Not in this PR" lists, is out of scope. Address every review comment within the scope, and ask before acting on one that asks for more. A PR whose measured core lines pass the stop that its Estimate names (twice the estimate, at most 600) stops and asks before continuing.
-
SL4.2: NVX's host can ask for a snapshot, and activate a restore.
- Objective: NVX's host cannot yet ask nvx-init to capture a VM or supply the guest state that activates a restored VM. This PR adds those two NVXC exchanges and gives host callers a typed capture operation.
- Contents: Two new crate-private NVXC messages in
protocol::app: the capture request, with its flag that asks nvx-init to kill its executions first, and the activate message, which carries the activation record and nvx-init's workload setup, a restore's workload identity included; crate-privateControlSession::capture. Each carriesexpect(dead_code)until its first caller, SL4.3 or nvx-init, whose reason names that caller. - Scope:
- The crate-private
protocol::appmessages innvx-rs/src/protocol/app.rsandControlSession::captureinnvx-rs/src/host/session.rs, with codec tests innvx-rs/src/protocol/tests.rsand session tests innvx-rs/src/host/session/tests.rs. - A capture request whose flag tells nvx-init whether to kill running executions before capture.
- An activate message carrying the activation record and nvx-init's workload setup, including the restored workload's identity.
ControlSession::capture, which sends the capture request and validates its response.- Each new crate-private item carries
expect(dead_code)until its first caller, whose reason names that caller.
- The crate-private
- Not in this PR:
- Guest handling of capture or activation: SL7.7a and SL7.7b add those paths.
- A blocking restore driver, retry policy, restore deadlines or peer verification: SL4.3 adds them.
- Making
protocol::appprivate: that happens with the rest of NVXC in SL6.12. - NVXC v2 framing or streaming: SL4.4a through SL4.4c add those later.
- Approach: Extend the existing v1 application-frame codec and
ControlSessionrequest pattern in place. Keep the new messages and method crate-private, withexpect(dead_code)naming their first callers. Reuse the activation and workload types already defined for restore; do not introduce a second transport, a protocol abstraction, or restore orchestration in this PR. - Done when:
- The capture request round-trips with both values of its kill-executions flag.
- The activate message round-trips with its activation record, workload setup and workload identity.
ControlSession::capturesends the request and accepts the specified acknowledgement.
- Needs: SL2.5b, in nvx-rs slimming 2.3.1: activation record v2 carries only what the guest applies #1101.
- Estimate: 150 core lines, 2 counted files. Past 300 core lines, stop and ask before continuing.
-
SL4.3: A blocking caller can drive a restore.
- Objective: Blocking CLI callers need one bounded operation that completes the restore state machine over NVXC and returns a usable control session. This PR adds that crate-private driver beside the host's NVXC session, with verified peers, cancellation, deadlines and controlled reconnection.
- Contents: A crate-private,
cli-gated restore driver beside the host's NVXC session (host::session):restore(&mut Launched, &ActivationRecord, &Workload, &[HostMap], &Cancel) -> Result<ControlSession, ControlRestoreError>, the blocking driver overRestoreMachine. It checks that the restore-ready client and the control server are the VM's process; sends the activate message on each session; races every pending accept, read and write against the step's deadline, the caller's cancellation and the VM's verified exit; connects again after a lost session, up to 3 sessions; and afterDonesendsMAPSand Start, and returns the live session. Crate-privateControlRestoreErroris the machine's error, or a MAPS or Start failure. Its defaults are 60 s to Ready and 30 s to Start. - Scope:
- A crate-private,
cli-gatedrestore(&mut Launched, &ActivationRecord, &Workload, &[HostMap], &Cancel) -> Result<ControlSession, ControlRestoreError>besidehost::session, drivingControlSessionandRestoreMachine. - Verification that the restore-ready client and control-session server are the launched VM's held process.
- The activate exchange on every session, reconnection after a lost session, and a maximum of three sessions.
- Every pending accept, read and write races the current step's deadline, caller cancellation and verified VM exit.
- After
Done, MAPS and Start are sent and the liveControlSessionis returned; defaults are 60 seconds to Ready and 30 seconds to Start.
- A crate-private,
- Not in this PR:
- A public or asynchronous restore API: callers that need asynchronous integration drive
RestoreMachinethemselves. - More than three sessions, adaptive retries or configurable retry policies: no caller needs them.
- Snapshot-store locking, launch recovery or durable restore records: the CLI owns locking and recovery, and keeps no durable in-flight restore record.
- NVXC v2 or exec streaming: SL4.4a through SL4.4c add those later.
- A public or asynchronous restore API: callers that need asynchronous integration drive
- Approach: Drive the existing sans-I/O
RestoreMachinedirectly with blocking transport and process primitives besidehost::session. Keep one loop over machine actions, use the machine's phase and evidence for failures, and centralize the three race conditions around each I/O operation; do not create another restore state machine or public API. - Done when:
- Tests cover the 60-second Ready budget, 30-second Start budget and three-session limit.
- Deadline, cancellation and verified VM exit interrupt each pending accept, read and write.
- A lost session reconnects and receives the same activate message, while either unverified peer is refused.
- After
Done, MAPS and Start succeed and the returned live session can be used. - Machine, MAPS and Start failures produce distinct
ControlRestoreErrorvariants.
- Needs: SL4.2, above; SL2.16, in nvx-rs slimming 2.3.3: a VM restores from a snapshot, through a sans-I/O restore machine #1103; SL2.18b, in nvx-rs slimming 2.3.3: a VM restores from a snapshot, through a sans-I/O restore machine #1103.
- Estimate: 340 core lines, 3 counted files. Past 600 core lines, stop and ask before continuing.
Tests. Round trips of both messages, and ControlSession::capture. The driver: 60 s to Ready, 30 s to Start and at most 3 sessions; the deadline, a cancellation and a verified VM exit during each pending accept, read and write; the refusal of a restore-ready client or a control server that isn't the VM's process; a new session after one is lost, with the same activate message; MAPS and Start after Done, and the live ControlSession returned; and distinct machine, MAPS and Start failures in ControlRestoreError.
Done when: every PR above has merged, with dev green.
Activity
esaurez commentedon Nov 10, 2026
Workstream source/progress checkpoint - 2026-11-10 UTC
Checked boxes below mean merged scope, not merely an implemented first iteration. Implementation branches are source checkpoints, not automatic qualification, Ready or merge approval. Some starting inputs are frozen/anonymous commits rather than standalone branches; their exact SHAs and known merged producer refs are recorded explicitly.
SL4.2 - merged via pull request 1331.
esaurez/slim-3.2.1-sl4.2-canonical-20261107at3f217d54f9d8e19bbe512a7df64dbc7c3d9d328e.feature/nvx-refactoratbc9cecac747b460d89159914154b9f6ce3732968; merge commit3ad5e49df09ff3e1d5a702260ba127fc521d962d.SL4.3 - First implementation committed; not merged.
esaurez/slim-3.2.1-sl4.3-private-20261108; exact headb30be68869e256d74c55cf6a5933e20d8a6c6fb7.59662ea2dad715b6fd127406bf5f5c8339da11ce.The original technical scope remains authoritative, supplemented only by any portable technical clarification in this issue. No machine-specific execution policy is part of this checkpoint.
ppenna commentedon Nov 11, 2026
Both PRs of this group have merged into
feature/nvx-refactor: SL4.2 (#1331) and SL4.3 (#1476). SL4.3's merge,35cedfdbc3, passed CI on its head: https://github.com/microsoft/nvx/actions/runs/42986776627. Closing this group as complete;devreceives it whenfeature/nvx-refactorlands there.