Skip to content

nvx-rs, runtime-adapter: run a clone's restore sequence to its sandbox's start - #950

Open
Enrique Saurez (esaurez) wants to merge 3 commits into
esaurez/844-pr2-activation-restore-launch-20261024from
esaurez/844-pr3-restore-sequence-20261025
Open

Enrique Saurez (esaurez) wants to merge 3 commits into
esaurez/844-pr2-activation-restore-launch-20261024from
esaurez/844-pr3-restore-sequence-20261025

Conversation

@esaurez

@esaurez Enrique Saurez (esaurez) commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

Stacked on #949; this PR retargets when its parent merges.
Chain: #939 → #940 → #941 → #888 → #949 → this PR → #951, on dev; #879, #881, #885, #886, #877, #932, #884, #887, #933, #880, #936, and #937 have merged.

Part of #844 (PR 3 of 5: the restore sequence).

What and why

#949 launches a clone as OpenVMM's restore of its leased generation's snapshot and returns a Restoring. This PR runs the clone's restore sequence from there to its sandbox's start and the launch's commit, through the adapter's framing of the clone's control session, and frames that sequence in the test adapter.

The restore sequence

Restoring::activate runs the sequence through a CloneControl, a new trait for the adapter's framing of the control session, by a restore-to-Ready deadline that runs from the launch, RESTORE_TO_READY_TIMEOUT, 60 seconds by default:

  1. It reads OpenVMM's restore-ready event as soon as it comes, since OpenVMM on Windows waits until the host has read it, and refuses another process's connection and bytes that differ from the event. OpenVMM writes the event once and then closes its end, so the wait reads nothing past it.
  2. Only then does it connect to the clone's control endpoint, whose console bounds the host's authentication from the connection on, and attach with the launch's capability.
  3. It sends the record, read again from clone-activation.bin, which must still be byte for byte the launch's, in the adapter's Activate, as the session's first request.
  4. It checks that Ready reports the record's transaction ID, as ReadyActivation::of returns it. A Ready that reports none, as a cold boot's does, or another transaction, fails the sequence.

A session that the adapter lost is replaced by a new one that sends the same record first, in at most MAX_ACTIVATION_SESSIONS, three, sessions; nothing else is retried. Activated::start then starts the sandbox by a Ready-to-Start deadline that runs from the check of Ready, READY_TO_START_TIMEOUT, 30 seconds by default, and never sends the start again. Started::commit commits the launch, which writes its runtime record. The host sends nothing but the record before Ready, so the guest's mappings and start always follow it.

A failure ends the launch as Starting::abandon does. A crash before the commit leaves the journal, whose recovery ends the VMM, while the lease lasts until the release; a crash after it leaves a VM that reattaches with its lease.

The default deadlines keep a wide margin on WHP's CI runs, the slowest backend: restores within a third of a second, and 25 parallel layered launches of the test adapter within 19 seconds.

The platform layer's ReadyListener gains receive(), which checks the peer's process on both platforms, and reads with an overlapped pipe on Windows.

The test adapter's framing

The host client sends a clone's activation record with Client::activate, and refuses an Activate from the guest, which only the host sends. host::activate runs the first step of a clone's order in place of host::ready: it sends the record as the session's first request, and checks the build in Ready, which also reports the clone's activation.

host::CloneOrder implements CloneControl with these steps and host::start_sandbox. It takes a session for lost once a reset, the end of the broker's stream, or a failure of the transport ended it. OpenVMM's broker also ends the stream to refuse an attachment, so such a refusal is retried too, within the sequence's limit of sessions. Any other failure is final.

Not in this PR

Validation

At this head, 426403c, with OpenVMM at d2338ea2, per commit: on Windows, fmt and Clippy with -D warnings for nvx-rs in CI's three configurations (--all-targets --all-features, --lib, and --lib --no-default-features), tests/host_modules.rs, the tests of the platform, template, store, sandbox, and supervisor modules, and the test adapter's fmt, Clippy, and host tests; and for the x86_64 Linux target, Clippy with -D warnings in the same three configurations, the aarch64-apple-darwin check, and the test adapter's Linux host and musl guest Clippy.

The gates, every step of check-nvx-rs on Windows and on Linux x86_64 with the host tests as root on Linux, and the VM suites on WHP and MSHV, run at the final heads of the stack once its reviews are clean.

Tests added, with a fake VMM and a fake control: the sequence through the commit; a Ready of another transaction, a cold boot's, or none; a lost session replaced with the same record first; a changed record and a diverged Ready, which end the retries; failures that are not retried; the limit of sessions; a clone that ended after a lost session; both deadlines; a start that is never resent; a VMM that exits, or sends anything but its event; and crashes of the caller around Ready and the start, before and after the commit, each with the lease state that recovery or reattach leaves. In the test adapter, with the fake broker: the session's bootstrap, the record as the first request, after which the host waits for Ready, Ready with and without an activation, then the table and the start; a session that a later reset, the end of the stream, or a failed transport ended, whose successor sends the same record first; and the final failures.

No VM: real restores come with PR 5's VM tests.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The readiness-event read accepts a valid prefix with trailing data, allowing clone activation without verifying that the endpoint closes with no extra bytes under the same deadline.

1 open issue
What changed in this PR

This PR completes the host-side clone restore sequence for #844, building on #949’s launch support to activate a clone, start its sandbox, and commit the launch.

Changes:

  • Adds restore lifecycle types, deadlines, activation checks, and bounded retries for lost sessions.
  • Reads restore-ready events with peer-process checks on Linux and Windows.
  • Adds runtime-adapter framing, fake-VMM and session tests, and lifecycle documentation.
File Description
tests/​runtime-adapter/​tests/​host_session.rs Tests clone activation framing, retries, and failures.
tests/​runtime-adapter/​src/​lib.rs Documents the host’s clone order.
tests/​runtime-adapter/​src/​host/​order_error.rs Documents activation-related order errors.
tests/​runtime-adapter/​src/​host.rs Adds activation requests and CloneOrder.
tests/​runtime-adapter/​README.md Documents clone framing and test coverage.
nvx-rs/​src/​host/​template/​mod.rs Exports and documents restore APIs.
nvx-rs/​src/​host/​template/​clone/​tests/​restore.rs Tests restore sequencing, deadlines, and refusals.
nvx-rs/​src/​host/​template/​clone/​tests/​launch.rs Extends fake-VMM behavior and crash-recovery tests.
nvx-rs/​src/​host/​template/​clone/​tests.rs Registers restore tests.
nvx-rs/​src/​host/​template/​clone/​restore.rs Implements activation, start, and commit transitions.
nvx-rs/​src/​host/​template/​clone/​launch.rs Records launch timing and activation-record location.
nvx-rs/​src/​host/​template/​clone.rs Exports restore lifecycle types.
nvx-rs/​src/​host/​sys/​socket.rs Adds bounded socket readability polling.
nvx-rs/​src/​host/​sys/​mod.rs Exposes the readability helper internally.
nvx-rs/​src/​host/​supervisor/​mod.rs Documents restore lifecycle and recovery behavior.
nvx-rs/​src/​host/​platform/​windows.rs Adds overlapped restore-ready reads and peer checks.
nvx-rs/​src/​host/​platform/​other.rs Adds an unsupported-platform receive stub.
nvx-rs/​src/​host/​platform/​linux.rs Adds nonblocking restore-ready reads and peer checks.
nvx-rs/​README.md Documents the complete host restore sequence.

Review effort: Balanced

Comment thread nvx-rs/src/host/template/clone/restore.rs
@esaurez
Enrique Saurez (esaurez) force-pushed the esaurez/844-pr2-activation-restore-launch-20261024 branch from aa44693 to 49adcfe Compare October 28, 2026 04:38
@esaurez
Enrique Saurez (esaurez) force-pushed the esaurez/844-pr3-restore-sequence-20261025 branch from 281d8d0 to 2c8d550 Compare October 28, 2026 04:38
@esaurez
Enrique Saurez (esaurez) requested a balanced review from Copilot October 28, 2026 04:40

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

The coupled restore, authentication, recovery, and Windows overlapped-I/O changes need platform review or integrated KVM/MSHV/WHP validation because current tests rely on fake VMMs and transports.

No open issues 🎉

1 resolved since last review

Review effort: Balanced

@esaurez
Enrique Saurez (esaurez) force-pushed the esaurez/844-pr2-activation-restore-launch-20261024 branch from 49adcfe to 42cf6b4 Compare October 28, 2026 05:34
@esaurez
Enrique Saurez (esaurez) force-pushed the esaurez/844-pr3-restore-sequence-20261025 branch from 2c8d550 to 7ff6e1f Compare October 28, 2026 05:34
@esaurez
Enrique Saurez (esaurez) requested a balanced review from Copilot October 28, 2026 05:35

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

The cross-platform restore lifecycle and Windows overlapped-pipe handling have only fake-layer coverage, leaving real KVM/MSHV/WHP integration unverified until PR 5 and requiring human assessment.

No open issues 🎉

Review effort: Balanced

@esaurez
Enrique Saurez (esaurez) force-pushed the esaurez/844-pr2-activation-restore-launch-20261024 branch from 42cf6b4 to caa6a0b Compare October 28, 2026 06:19
@esaurez
Enrique Saurez (esaurez) force-pushed the esaurez/844-pr3-restore-sequence-20261025 branch from 7ff6e1f to cc3cefc Compare October 28, 2026 06:20
@esaurez
Enrique Saurez (esaurez) requested a balanced review from Copilot October 28, 2026 06:20

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

The restore handshake combines Windows overlapped I/O with crash-sensitive VM lifecycle ordering, but coverage uses fake VMM/control paths and real KVM, MSHV, and WHP validation is deferred to PR 5.

No open issues 🎉

Review effort: Balanced

@esaurez
Enrique Saurez (esaurez) force-pushed the esaurez/844-pr2-activation-restore-launch-20261024 branch from caa6a0b to 8fe2446 Compare October 28, 2026 07:02
@esaurez
Enrique Saurez (esaurez) force-pushed the esaurez/844-pr3-restore-sequence-20261025 branch from cc3cefc to 40ee8e4 Compare October 28, 2026 07:03
@esaurez
Enrique Saurez (esaurez) requested a balanced review from Copilot October 28, 2026 07:03

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Fake-VMM validation leaves real restore, reconnect, commit/recovery, and Windows pipe-handshake behavior unverified across KVM, MSHV, and WHP, requiring maintainer confirmation and platform tests deferred to PR 5.

No open issues 🎉

Review effort: Balanced

@esaurez
Enrique Saurez (esaurez) force-pushed the esaurez/844-pr2-activation-restore-launch-20261024 branch from 8fe2446 to 34638df Compare October 28, 2026 08:55
@esaurez
Enrique Saurez (esaurez) force-pushed the esaurez/844-pr3-restore-sequence-20261025 branch from 40ee8e4 to a4893fd Compare October 28, 2026 08:55
@esaurez
Enrique Saurez (esaurez) requested a balanced review from Copilot October 28, 2026 08:56

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Cross-platform restore sequencing and Windows pipe cancellation affect VM lifecycle safety, but coverage relies on fake VMMs and transports while real KVM/MSHV/WHP validation is deferred, requiring platform-maintainer review.

No open issues 🎉

Review effort: Balanced

@esaurez
Enrique Saurez (esaurez) force-pushed the esaurez/844-pr2-activation-restore-launch-20261024 branch from 34638df to 492a35e Compare October 28, 2026 14:36
@esaurez
Enrique Saurez (esaurez) force-pushed the esaurez/844-pr3-restore-sequence-20261025 branch from a4893fd to 933dc80 Compare October 28, 2026 14:36
@esaurez
Enrique Saurez (esaurez) requested a balanced review from Copilot October 28, 2026 14:37

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Human review is needed because cross-platform restore ordering and Windows overlapped-pipe handling have only fake-VMM/control coverage, while real clone-restore and exact-head KVM/MSHV/WHP validation remain deferred.

No open issues 🎉

Review effort: Balanced

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

The restore handoff and Windows pipe cancellation rely on fake-based tests, while real clone restore/Start validation across KVM, MSHV, and WHP remains deferred and needs human confirmation.

No open issues 🎉

Review effort: Balanced

@esaurez
Enrique Saurez (esaurez) force-pushed the esaurez/844-pr2-activation-restore-launch-20261024 branch from 8c12d92 to b48e295 Compare October 28, 2026 16:19
@esaurez
Enrique Saurez (esaurez) force-pushed the esaurez/844-pr3-restore-sequence-20261025 branch from a53a0fa to d6f9b68 Compare October 28, 2026 16:22
@esaurez
Enrique Saurez (esaurez) requested a balanced review from Copilot October 28, 2026 16:22

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

The restore lifecycle spans authentication, Windows overlapped I/O, and crash recovery, while fake-only validation leaves KVM/MSHV/WHP integration deferred and platform contracts needing human review.

No open issues 🎉

Review effort: Balanced

Enrique Saurez and others added 3 commits October 28, 2026 09:47
A clone that ClonePlan::launch started now runs its restore sequence through
the adapter's framing of its control session, a new CloneControl trait:

- Restoring::activate waits for OpenVMM's restore-ready event, reading it as
  soon as it comes, since OpenVMM on Windows waits until the host has read it,
  and refuses another process's connection and other bytes. Only then does it
  connect to the clone's control endpoint, whose console bounds the host's
  authentication from the connection on. It attaches with the launch's
  capability, sends the record, read again from clone-activation.bin and
  byte-equal to the launch's, in the adapter's Activate as the session's first
  request, and checks that Ready reports the record's transaction ID.
- All of it runs by a restore-to-Ready deadline from the launch, 60 seconds by
  default. A session that the adapter lost is replaced by a new one that sends
  the same record, in at most three sessions; nothing else is retried.
- Activated::start starts the sandbox by a Ready-to-Start deadline from the
  check of Ready, 30 seconds by default, and never sends the start again.
  Started::commit commits the launch, which writes its runtime record.
- A failure ends the launch as Starting::abandon does. A crash before the
  commit leaves the journal, whose recovery ends the VMM while the lease lasts
  until the release; a crash after it leaves a VM that reattaches with its
  lease.

The default deadlines keep a wide margin on WHP's CI runs, the slowest
backend: restores within a third of a second, and 25 parallel layered launches
of the test adapter within 19 seconds.

The platform layer's ReadyListener gains receive(), which checks the peer's
process on both platforms, and reads with an overlapped pipe on Windows.

Tests, with a fake VMM and a fake control: the sequence through the commit;
Ready of another transaction, a cold boot's, or none; a lost
session replaced with the same record first; a changed record and a diverged
Ready, which end the retries; failures that aren't retried; the limit of
sessions; a clone that ended after a lost session; both deadlines; a start
that's never resent; a VMM that exits, or sends anything but its event; and
crashes of the caller around Ready and the start, before and after the
commit, each with the lease state that recovery or reattach leaves.

Two of the launch tests asked their fake VMM to exit before they opened its
process, which no longer opens once the VMM has exited; a shared helper now
opens it first.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: a424884c-018a-45f5-a7fe-c57548a873f0
The host client sends a clone's activation record with Client::activate,
and refuses an Activate from the guest, which only the host sends.
host::activate runs the first step of a clone's order in place of
host::ready: it sends the record as the session's first request, and checks
the build in Ready, which also reports the clone's activation.

host::CloneOrder implements nvx's CloneControl with these steps and
host::start_sandbox. It takes a session for lost once a reset, the end of the
broker's stream, or a failure of the transport ended it. OpenVMM's broker
also ends the stream to refuse an attachment, so such a refusal is retried
too, within the sequence's limit of sessions. Any other failure is final.

Tests, with the fake broker: the session's bootstrap, the record as the first
request, Ready with and without an activation, then the table and the start;
a session that a later reset, the end of the stream, or a failed transport
ended, whose successor sends the same record first; and the final failures:
an ERROR refusal, deadlines, another build, a mismatched or undecodable
answer, and a record beyond the framing's limit.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: a424884c-018a-45f5-a7fe-c57548a873f0
OpenVMM writes the restore-ready event once, and then closes its end of
the endpoint, so the wait reads the event's bytes and nothing past them,
and refuses those that differ from the event, beside a connection of
another process than the clone's VMM. The documentation of the restore
sequence and the crate's README said that it refused "other bytes than
the event", which reads as if it refused bytes past the event too; they
now say what it does.

Part of #844.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: a424884c-018a-45f5-a7fe-c57548a873f0

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

The restore handshake and Windows overlapped-pipe lifecycle are validated only with fakes, leaving real clone restores on KVM, MSHV, and WHP requiring human confirmation before integration.

No open issues 🎉

Review effort: Balanced

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants