Repository navigation
guest: let nvx-ingress start spawn its announcer itself (SL6.13c) - #1494
Merged
Pedro Henrique Penna (ppenna) merged 2 commits intoNov 11, 2026
Merged
Pedro Henrique Penna (ppenna) merged 2 commits into
Pedro Henrique Penna (ppenna) merged 2 commits into
Conversation
Contributor
This pull request changes existing testsIt modifies or removes 15 existing test asset(s), listed below. Review each with care: a change to a test can hide a regression that the test caught. See doc/contribute.md#changes-to-existing-tests. Test code
Relocated unchanged: 2; added: 9. Compared the merge base |
Contributor
There was a problem hiding this comment.
🟢 Approval recommended
No active review issues remain to block the announcer-launch ownership refactor.
No open issues 🎉
What changed in this PR
This PR moves announcer launching into nvx-ingress start, removing its dependency on the library spawner ahead of the guest process-module removal tracked by #1120.
Changes:
- Launches the announcer with
std::process::Command, preserving privileged socket binding, session isolation and signal resets. - Removes
Announcer,PROGRAMandStartError; updates nvx-init and gives the temporary runtime adapter its own launcher. - Updates launch regression tests, documentation and the public API snapshot.
| File | Description |
|---|---|
tests/runtime-adapter/tests/guest_session.rs |
Uses adapter-owned announcement failures in the fake. |
tests/runtime-adapter/src/worker/tests.rs |
Tests announcer launch, cleanup and failed execution. |
tests/runtime-adapter/src/worker/activation/tests.rs |
Updates announcement failure classification coverage. |
tests/runtime-adapter/src/worker/activation.rs |
Classifies the adapter’s own announcement error. |
tests/runtime-adapter/src/worker.rs |
Adds an adapter-owned launcher and child cleanup. |
tests/runtime-adapter/README.md |
Documents adapter ownership and launcher tests. |
nvx-rs/tests/guest_tools.rs |
Updates the expected launch-failure message. |
nvx-rs/src/guest/sys/spawn.rs |
Adds announcer session and signal setup. |
nvx-rs/src/guest/sys/socket.rs |
Updates socket ownership documentation. |
nvx-rs/src/guest/sys/mod.rs |
Exposes the private announcer configuration helper. |
nvx-rs/src/guest/mod.rs |
Hides ingress and updates module documentation. |
nvx-rs/src/guest/init.rs |
Names the announcer executable directly. |
nvx-rs/src/guest/ingress/tests.rs |
Tests socket inheritance, sessions, signals and launch failures. |
nvx-rs/src/guest/ingress/mod.rs |
Implements direct socket binding and announcer spawning. |
nvx-rs/src/guest/ingress/announcer/tests.rs |
Removes the retired library spawner’s tests. |
nvx-rs/src/guest/ingress/announcer.rs |
Removes the library spawner and its public types. |
nvx-rs/README.md |
Documents the revised start implementation. |
nvx-rs/public-api/linux.txt |
Records removed APIs and the hidden ingress module. |
Review effort: Balanced
The runtime adapter's guest worker starts the announcer of a clone's listeners after the process-free application with nvx::guest::ingress::Announcer::start, and classifies its StartError. nvx-ingress start is to spawn its announcer itself, so that Announcer, PROGRAM and StartError leave nvx (SL6.13c), and the adapter is their last other user until SL5.2 deletes the adapter. Give the worker a launcher of its own, Announcement, with the launch that Announcer::start gave it: it binds a UDP socket to the highest free privileged source port, from 1023 down to 512, runs /sbin/nvx-ingress inherit GATEWAY_IPV4 through nvx::guest::spawn with that socket as its standard input, in a session of its own, with every signal's default disposition and none blocked, waits until the program runs, and stops and collects the announcer when the worker tears its root down or drops it. AnnounceFailure carries the launcher's io::Error, and the guest-session fake fails with it, so both still end the clone with ACTIVATION_NETWORK. The worker's new unit tests check the launch, the stop and the drop, and a failed exec, which leaves no child: they take over the cases of nvx's Announcer tests, which the next commit retires with Announcer. The case matrix gives them a fate: they retire with the adapter, and it points to the tests of nvx-ingress start's own launch. Validated on nvx-kvm-test (linux-kvm, virtual machine), where the adapter's protocol-only, host-only and musl guest-only configurations pass their CI checks, the new unit tests among them, and on nvx-mshv-test (linux-mshv, virtual machine), where vm_clone's scenario of the clones of every network policy passes: the host reaches a clone's listener once the announcer that Announcement started announced it. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
nvx-ingress start was the last user in nvx of Announcer, the library spawner of the announcer of a clone's listeners, which depends on the guest::spawn and guest::process modules that later PRs delete. start now binds the announcer's socket through the shared bind_privileged search, to the highest free privileged source port from 1023 down to 512, and spawns /sbin/nvx-ingress inherit GATEWAY_IPV4 with std::process::Command, with that socket as its standard input, and a pre-exec hook of the private OS layer, sys::configure_announcer, which gives it a session of its own and every signal's default disposition, none blocked, as Announcer::start did. It still exits with 0 once the program runs, and with 1 when it does not start, without waiting for any announcement. The message of a failed start no longer names the launch stage, which the standard library does not report. The standard library's spawn collects the status of a child that does not run the program, and panics when the kernel collected it first, as it does every child's when the caller ignores SIGCHLD, a disposition that exec keeps. So start restores SIGCHLD's default disposition with sys::reset_child_signal before it spawns, as nvx-init does before it collects its children, and still exits with 1 then, as it did with Announcer::start, which ignored a failure of that collection. Announcer, PROGRAM and StartError go with their tests, and guest::ingress, whose only public item is now its hidden main, becomes hidden. nvx-init's restored announcer, which took its path from PROGRAM, names /sbin/nvx-ingress itself; it still owns its announcer. The launch's new tests run a script in place of the program, and check its arguments, its socket as standard input, its own session without a terminal, its signals, which none of the caller's ignored or blocked ones reach, and a program that does not run, also from a caller that ignores SIGCHLD, where the spawn panics without the reset. They take over the cases of the retired Announcer tests that still apply; the cases of Announcer's pidfd, stop, drop and StartError go with them. ingress_start_fails_when_the_announcer_does_not_start takes the new message of a failed exec. Validated on nvx-kvm-test (linux-kvm, virtual machine), on feature/nvx-refactor 7bc238e: format, the Lint step's five Clippy runs, -p nvx --lib --no-default-features and the musl guest run, documentation, public API, test layout, MSRV and macOS checks pass, and so do the launch's tests, guest_tools's ingress cases and nvx-init's restore tests on the GNU and musl targets. The SIGCHLD case fails without the reset, with the standard library's panic, and passes with it. The whole musl guest suite fails only the 26 tests that it failed on that host's Linux 6.6 at the earlier base 8b77521. On nvx-mshv-test (linux-mshv, virtual machine), with OpenVMM, a kernel and an initramfs built from this change on 3340bbd, test-microvm's untiered-network-policy and private-network-ingress pass: the untiered restores whose policies publish the guest's listeners report their announcer running, and the host reaches the guest's server through the port that it publishes. Before the SIGCHLD reset, on 8b77521, host-loopback-policy, platform-network-policy and network-snapshot passed there too. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Pedro Henrique Penna (ppenna)
force-pushed
the
agents/slim-sl6-13c-ingress-announcer
branch
from
November 11, 2026 22:00
2928e3c to
797e0ac
Compare
Pedro Henrique Penna (ppenna)
marked this pull request as ready for review
November 11, 2026 22:00
Pedro Henrique Penna (ppenna)
merged commit Nov 11, 2026
584c2dd
into
feature/nvx-refactor
85 of 88 checks passed
Pedro Henrique Penna (ppenna)
deleted the
agents/slim-sl6-13c-ingress-announcer
branch
November 11, 2026 22:17
Pedro Henrique Penna (ppenna)
added a commit
that referenced
this pull request
Nov 11, 2026
The first draft of the guidelines predates the nvx-init that feature/nvx-refactor now holds: #1453 routes the new sandbox boots to it, #1431 serves capture requests, #1447 activates repaired sessions, #1439 keeps a restore's announcer as a helper, and #1490 runs sandbox run through it too. Check each statement against that code, and correct those that did not hold: - an execution takes the VM's one workload identity, which nvx-init resolves, or creates, once before its switch, not an account mode of its own request, which nothing selects yet; - the child also drops its capability bounding set, and nvx-init kills an execution's process group when its leader ends; - nvx-init captures only the Fresh boot of a platform capture, refuses a session with a root with ENOTSUP, and shares one 30-second deadline among its checks, its sweep and the capture; - the restored broker restarts at its first epoch with a reset queued, and nvx-init fails on anything but that reset; - the host sends no MAPS for an empty mapping table, which no nvx_maps token announces; - no launch of NVX's CLI carries OpenVMM's older lifecycle token, which still routes a layered launch to the older init agent; - since #1494, no call of nvx starts the announcer: nvx-init forks it and runs /sbin/nvx-ingress itself, and nvx-ingress start runs it for an agent that cannot hold it; - the crate still keeps older calls that start processes, which nvx-init does not use. Quote, and compile, the space's steps in the order of nvx-init's cold boot and restore, and replace the capture excerpt with one that handles each outcome and disposition. The steps compile in SL5.1a's unit test of nvx-init's boot, the_reference_space_steps_compile, which now holds them as the guidelines quote them, and the guidelines link SL5.1a's guest-workflows example. Organize the page by ownership, the space, the executions, the capture, the transport, the restore, failures and replay. Trim design 4.2 and 4.3 to the architecture and boundaries of nvx-init and of the older layered and blockless roots, which still run. Link the guidelines from the rustdoc of guest::activation too, list the page in the project structure, and give the case matrix the doc tests that the guidelines quote, and the lines to which the links move two others. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Pedro Henrique Penna (ppenna)
added a commit
that referenced
this pull request
Nov 11, 2026
The first draft of the guidelines predates the nvx-init that feature/nvx-refactor now holds: #1453 routes the new sandbox boots to it, #1431 serves capture requests, #1447 activates repaired sessions, #1439 keeps a restore's announcer as a helper, and #1490 runs sandbox run through it too. Check each statement against that code, and correct those that did not hold: - an execution takes the VM's one workload identity, which nvx-init resolves, or creates, once before its switch, not an account mode of its own request, which nothing selects yet; - the child also drops its capability bounding set, and nvx-init kills an execution's process group when its leader ends; - nvx-init captures only the Fresh boot of a platform capture, refuses a session with a root with ENOTSUP, and shares one 30-second deadline among its checks, its sweep and the capture; - the restored broker restarts at its first epoch with a reset queued, and nvx-init fails on anything but that reset; - the host sends no MAPS for an empty mapping table, which no nvx_maps token announces; - no launch of NVX's CLI carries OpenVMM's older lifecycle token, which still routes a layered launch to the older init agent; - since #1494, no call of nvx starts the announcer: nvx-init forks it and runs /sbin/nvx-ingress itself, and nvx-ingress start runs it for an agent that cannot hold it; - the crate still keeps older calls that start processes, which nvx-init does not use. Quote, and compile, the space's steps in the order of nvx-init's cold boot and restore, and replace the capture excerpt with one that handles each outcome and disposition. The steps compile in SL5.1a's unit test of nvx-init's boot, the_reference_space_steps_compile, which now holds them as the guidelines quote them, and the guidelines link SL5.1a's guest-workflows example. Organize the page by ownership, the space, the executions, the capture, the transport, the restore, failures and replay. Trim design 4.2 and 4.3 to the architecture and boundaries of nvx-init and of the older layered and blockless roots, which still run. Link the guidelines from the rustdoc of guest::activation too, list the page in the project structure, and give the case matrix the doc tests that the guidelines quote, and the lines to which the links move two others. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This was referenced Nov 11, 2026
Pedro Henrique Penna (ppenna)
added a commit
that referenced
this pull request
Nov 13, 2026
The first draft of the guidelines predates the nvx-init that feature/nvx-refactor now holds: #1453 routes the new sandbox boots to it, #1431 serves capture requests, #1447 activates repaired sessions, #1439 keeps a restore's announcer as a helper, and #1490 runs sandbox run through it too. Check each statement against that code, and correct those that did not hold: - an execution takes the VM's one workload identity, which nvx-init resolves, or creates, once before its switch, not an account mode of its own request, which nothing selects yet; - the child also drops its capability bounding set, and nvx-init kills an execution's process group when its leader ends; - nvx-init captures only the Fresh boot of a platform capture, refuses a session with a root with ENOTSUP, and shares one 30-second deadline among its checks, its sweep and the capture; - the restored broker restarts at its first epoch with a reset queued, and nvx-init fails on anything but that reset; - the host sends no MAPS for an empty mapping table, which no nvx_maps token announces; - no launch of NVX's CLI carries OpenVMM's older lifecycle token, which still routes a layered launch to the older init agent; - since #1494, no call of nvx starts the announcer: nvx-init forks it and runs /sbin/nvx-ingress itself, and nvx-ingress start runs it for an agent that cannot hold it; - the crate still keeps older calls that start processes, which nvx-init does not use. Quote, and compile, the space's steps in the order of nvx-init's cold boot and restore, and replace the capture excerpt with one that handles each outcome and disposition. The steps compile in SL5.1a's unit test of nvx-init's boot, the_reference_space_steps_compile, which now holds them as the guidelines quote them, and the guidelines link SL5.1a's guest-workflows example. Organize the page by ownership, the space, the executions, the capture, the transport, the restore, failures and replay. Trim design 4.2 and 4.3 to the architecture and boundaries of nvx-init and of the older layered and blockless roots, which still run. Link the guidelines from the rustdoc of guest::activation too, list the page in the project structure, and give the case matrix the doc tests that the guidelines quote, and the lines to which the links move two others. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Pedro Henrique Penna (ppenna)
added a commit
that referenced
this pull request
Nov 13, 2026
The first draft of the guidelines predates the nvx-init that feature/nvx-refactor now holds: #1453 routes the new sandbox boots to it, #1431 serves capture requests, #1447 activates repaired sessions, #1439 keeps a restore's announcer as a helper, and #1490 runs sandbox run through it too. Check each statement against that code, and correct those that did not hold: - an execution takes the VM's one workload identity, which nvx-init resolves, or creates, once before its switch, not an account mode of its own request, which nothing selects yet; - the child also drops its capability bounding set, and nvx-init kills an execution's process group when its leader ends; - nvx-init captures only the Fresh boot of a platform capture, refuses a session with a root with ENOTSUP, and shares one 30-second deadline among its checks, its sweep and the capture; - the restored broker restarts at its first epoch with a reset queued, and nvx-init fails on anything but that reset; - the host sends no MAPS for an empty mapping table, which no nvx_maps token announces; - no launch of NVX's CLI carries OpenVMM's older lifecycle token, which still routes a layered launch to the older init agent; - since #1494, no call of nvx starts the announcer: nvx-init forks it and runs /sbin/nvx-ingress itself, and nvx-ingress start runs it for an agent that cannot hold it; - the crate still keeps older calls that start processes, which nvx-init does not use. Quote, and compile, the space's steps in the order of nvx-init's cold boot and restore, and replace the capture excerpt with one that handles each outcome and disposition. The steps compile in SL5.1a's unit test of nvx-init's boot, the_reference_space_steps_compile, which now holds them as the guidelines quote them, and the guidelines link SL5.1a's guest-workflows example. Organize the page by ownership, the space, the executions, the capture, the transport, the restore, failures and replay. Trim design 4.2 and 4.3 to the architecture and boundaries of nvx-init and of the older layered and blockless roots, which still run. Link the guidelines from the rustdoc of guest::activation too, list the page in the project structure, and give the case matrix the doc tests that the guidelines quote, and the lines to which the links move two others. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part of #1120 (SL6.13c, "
nvx-ingress startspawns its announcer itself"). Parent #1087, umbrella #1076.What and why
nvx-ingress startwas the last user in nvx ofguest::ingress::Announcer, the library spawner of a clone's announcer, which depends onguest::spawnandguest::process, the process modules that later PRs delete. The program now starts its announcer itself, and the spawner goes:startcreates the announcer's IPv4 UDP socket and binds it with the existing sharedbind_privilegedsearch, to the highest free privileged source port from 1023 down to 512 (bind_announcer_socket). No copy of the search is added./sbin/nvx-ingress inherit GATEWAY_IPV4withstd::process::Command(launch):argv[0]isnvx-ingress, the socket is its standard input, and it keeps the caller's standard output and error. Apre_exechook of the private OS layer,sys::configure_announceringuest/sys/spawn.rs, callssetsidand the existingreset_signals. The child gets a session of its own without a controlling terminal, every signal's default disposition, and no blocked signal, asAnnouncer::startgave it throughguest::spawn.startreturns once the program runs, which the standard library learns from its close-on-exec report, and exits with 0. It exits with 1 when the program does not start. It waits for no scan or announcement, and leaves the announcer to init or to the nearest subreaper, as before.launchrestoresSIGCHLD's default disposition with the existingsys::reset_child_signal. The standard library's spawn collects the status of a child that does not run the program, and panics (wait() should either return Ok or panic) when the kernel has collected it already. The kernel collects every child's status whileSIGCHLDis ignored, a disposition thatexeckeeps.Announcer::startignored a failure of that collection and still failed with status 1. The code review of this branch found this; the new testan_announcer_does_not_start_without_its_program_when_its_caller_ignores_sigchldfails without the reset and passes with it.Announcer,PROGRAMandStartErrorare deleted with their tests.guest::ingress, whose only public item is now itsmain, which SL1.5 hid, becomes#[doc(hidden)].nvx-rs/public-api/linux.txtdrops their 17 lines and marks the module hidden. Thenvx-ingressrow of the README's guest-binary table and the rustdoc ofguest,guest::ingressandsys::UdpSocketdescribe the new launch.BOOT_CONTRACT_VERSIONandCONTROL_CONTRACT_REVISIONdon't change, and nothing new onfeature/nvx-refactorusesAnnouncer,PROGRAMorStartError.Deviations from the issue
The runtime adapter changes. The adapter's guest worker started a clone's announcer with
Announcer::startand classifiedStartError, so deleting them forces this change. SL5.2 (nvx-rs slimming 4.1.2: the test adapter is gone #1119) deletes the adapter later. The first commit gives the worker its own launcher,Announcement, with the launch thatAnnouncer::startgave it, built on the publicnvx::guest::spawn::Commandandnvx::guest::process::Child:/sbin/nvx-ingress inherit GATEWAY_IPV4in a session of its own, with every signal reset, and waits until the program runs;AnnounceFailurebecomes public and carries anio::Error, and the guest-session fake now fails with it. Both still end the clone withACTIVATION_NETWORK. The adapter is test code undertests/, so it adds no counted file.init.rschanges. nvx-init's restored announcer took its path fromPROGRAM, a use that guest: retain restored ingress as an init helper #1439 added. It now namesc"/sbin/nvx-ingress"itself, and nvx-init still owns its announcer. This one line makesguest/init.rsthe fourth counted file.The start-failure message loses its launch stage. The standard library reports only the
errnoof a failedexec. Sonvx-ingress: /sbin/nvx-ingress did not start: the exec launch stage failed: ...becomesnvx-ingress: /sbin/nvx-ingress did not start: No such file or directory (os error 2). A failed fork, whichStartError::Spawnreported as... cannot be started: ..., now reads... did not start: ...too. The exit status stays 1.History: the first implementation
Enrique Saurez (@esaurez)'s first implementation is
esaurez/slim-4.2.1-sl6.13c-20261108(fb5b5693, checkpoint on #1120): one commit on the SL7.3 branch. This PR carries it as two commits with Enrique Saurez (@esaurez) as their author, rebased ontofeature/nvx-refactor. The runtime adapter's launcher comes first, so that each commit builds. The second commit changes the program. Its main changes to the first implementation are these:start's launch is factored intobind_announcer_socketandlaunch(program, …), so that its tests run a script in place of/sbin/nvx-ingress. Those tests live inguest::ingress::tests, beside their subject, instead ofguest::sys::spawn::tests.init.rsedit that guest: retain restored ingress as an init helper #1439's use ofPROGRAMneeds.SIGCHLDreset and its test.The case matrix
SL5.1a's case matrix,
doc/acceptance-case-matrix.md, gives each test of the runtime adapter a fate. The first commit adds a row for the three tests that it adds to the adapter'sworker::tests: they retire with the adapter, and the row points to the tests ofnvx-ingress start's own launch,nvx-rs/src/guest/ingress/tests.rs. The summary's count of the adapter's other tests becomes 169, 160 of them retired. The matrix names none of the announcer tests that this PR retires or moves, andeach_class_of_failure_ends_the_clone_with_its_own_statuskeeps its name and its row.Not in this PR
As the issue says: waiting for the announcer's first scan or announcement, retries beyond the existing descending search, changes to
inherit, the announcements, gateway parsing or test mode, a general guest process wrapper or a private copy of the port search, and any change to nvx-init's ownership of its own announcer.Size
Measured against
feature/nvx-refactor3c3dfce1: 52 core lines (estimate 80, stop 160) in 4 counted files (estimate 3):guest/ingress/mod.rsguest/sys/spawn.rsguest/sys/mod.rsguest/init.rsThese don't count:
guest/mod.rs, which only hidesingress, andguest/sys/socket.rs, whose only changes are to docs;guest/ingress/announcer.rs;tests/.Tests of the area
guest::ingress::tests, innvx-rs/src/guest/ingress/tests.rs:decimal_files_hold_one_plain_number;an_announcer_runs_its_program_with_its_socket_in_a_session_of_its_own,an_announcer_starts_with_every_signal_s_default_disposition_and_none_blockedandan_announcer_does_not_start_without_its_program_when_its_caller_ignores_sigchld;an_announcer_whose_program_does_not_run_does_not_start, fromguest::ingress::announcer::tests.guest::ingress::announcer::testsretire withAnnouncer:an_announcer_runs_its_program_with_its_socket_until_it_is_stopped,an_announcer_that_ends_polls_readable_and_keeps_its_status,a_dropped_announcer_endsandstart_errors_name_their_cause. Their cases that still apply move, as "Changes to existing tests" below says.guest::ingressare kept unchanged:address(3),collect(10),diag(2),encode(3),sender(7),table(11) andtest_mode(1).guest_tools:ingress_test_mode_prints_the_conformance_vector_from_prebuilt_binaries,ingress_test_mode_preserves_udp_settling_between_snapshots,ingress_rejects_bad_invocations_and_test_snapshotsandingress_inherits_only_an_ipv4_datagram_socket_bound_to_a_privileged_source_port;ingress_start_fails_when_the_announcer_does_not_start.guest::init::tests::restoreis kept unchanged. Its tests still replace the restored announcer's program throughtests::restore::announcer_program.worker::testsaddsannouncer_launch_keeps_the_socket_and_monitors_its_owned_child,announcer_drop_stops_and_reaps_the_child_that_it_ownsandannouncer_failed_exec_reports_the_cause_and_leaves_no_child, and keeps its PID 1 tests;worker::activation::tests::each_class_of_failure_ends_the_clone_with_its_own_statusand theguest_sessionfake'sapplyare rewritten;Validation
feature/nvx-refactorhas noscripts/local_gates.py, so the checks below ran from this branch's own action definitions (check-nvx-rs), with the pinned toolchain (1.95.0; MSRV 1.89). They ran on tree9c014588, the previous head2928e3c2on7bc238eb, unless a check names another. The Linux hosts held that tree as this branch's patch applied to the base, whichgit write-treeconfirmed.This head,
797e0ac0, is that branch rebased onto3c3dfce1(#1490, #1495 and #1488) without conflicts.git range-diffshows only one content change: the case matrix's new row and count, which are docs. CI validates the rebased code. On this head, these pass: a check of every pointer of the case matrix (everynvx-rs/…::test, scenario, Python test class and path that it names exists), and of its rows against the adapter's sources (169 tests, each named once; counts 169, 0, 9 and 160), together withcheck_markdown_links.py,check_test_layout.pyandcheck_test_changes.py. At3c3dfce1, the same check finds the adapter's 166 tests listed; at this head before the new row, it finds the three new tests without a row.Windows (local):
cargo fmt --all --check, for nvx-rs and the runtime adapter-D warnings: the Lint step's five runs and-p nvx --lib --no-default-featurescheck_test_layout.py,public_api.py(both snapshots) andcheck_test_changes.pyLinux, on
nvx-kvm-test(linux-kvm, virtual machine, Azure Linux 3, kernel 6.6):cargo fmt --all --check-D warnings: the Lint step's five runs,-p nvx --lib --no-default-features, and the musl guest run ofcheck-guest-binariescargo doc --all-featureswith-D warningscargo +1.89 check --all-targets --all-featurescargo check --all-targets --all-features --target aarch64-apple-darwinpublic_api.pyandcheck_test_layout.pyguest::ingressunit tests, GNU--all-featuresand musl--features guestguest_toolsingresscases, GNU and muslguest::init::tests::restore, muslcheck-guest-binariesEvery failure is pre-existing on that host. The whole musl guest suite fails the same 26 tests, by name, that it failed on that host's Linux 6.6 at the earlier base
8b775211, and at this branch's earlier head on it. They are inguest::entry,guest::exec,guest::init::tests::execandguest::managed_agent::dispatch, and none of them checks the announcer or nvx-init's restore. The newSIGCHLDtest fails without the reset, with the standard library's panic, and passes with it, on the GNU and musl targets.MicroVMs, on
nvx-mshv-test(linux-mshv, virtual machine). OpenVMM, the kernel and the Alpine initramfs were built from this change on3340bbd7(treeb8214e28). The later base7bc238ebadds only host sandbox code, which neither the guest nor these scenarios run.python3 scripts/nvx.py test-microvm --backend mshv --scenario untiered-network-policy --scenario private-network-ingresspassed both scenarios:untiered-network-policy(13.5 s): the restores whose policies publish the guest's listeners, host loopback and private-network ingress, reportannouncer=running, which the guest's restore repair started withnvx-ingress start. The host reaches the guest's server through the port that each publishes (NVX-UNTIERED-NETWORK-INBOUND2 and 1). The deny-all and DNS-egress restores reportannouncer=none.private-network-ingress(30.3 s).Before this rebase, the previous head (
a2b1ba84, on8b775211) also passed these:nvx-mshv-test, with an initramfs built from it:untiered-network-policy,private-network-ingress,host-loopback-policy,platform-network-policyandnetwork-snapshot, and the runtime adapter'svm_clonescenario of the clones of every network policy,one_template_serves_the_clones_of_every_network_policy_at_its_guest_s_address.nvx-kvm-test: the runtime adapter's protocol-only, host-only and guest-only configurations.Since then,
git range-diffshows that the rebases onto3340bbd7,7bc238eband3c3dfce1changed neither commit's code. The only content changes are theSIGCHLDreset and its test, and the case matrix's row. The rest of CI's matrix is left to CI, which runs now that this pull request is Ready: the KVM, MSHV and WHP microVM suites, the guest artifact builds and the benchmarks.Changes to existing tests
python3 scripts/check_test_changes.py --base origin/feature/nvx-refactorlists 15 changes to existing tests, hence thetests-modifiedlabel. It also finds 2 relocated unchanged and 9 added.Modified:
guest_session'sapplyhelper. It isimpl RootOperations for FakeRootintests/runtime-adapter/tests/guest_session.rs. The fake's injected announce failure is now the adapter's ownAnnounceFailure { error: io::Error::other(problem), teardown: None }, instead ofStartError::Spawn(io::Error::other(problem)), sinceStartErroris deleted. The worker classifies both asACTIVATION_NETWORK, so the tests that inject the failure expect the same status. The helper's doc comment changes to match.worker::activation::tests. They dropnvx::guest::ingress::StartError.an_announcer_whose_program_does_not_run_does_not_start. It moves fromguest::ingress::announcer::teststoguest::ingress::tests. It now runslaunchwith a missing program, instead ofAnnouncer::spawn. It checks the whole message,<path> did not start: No such file or directory (os error 2), instead ofStartError::Launchwith the exec stage andENOENT, since the standard library reports theerrnobut no stage.ingress_start_fails_when_the_announcer_does_not_start(nvx-rs/tests/guest_tools.rs). The prefix that it accepts for a failed exec dropsthe exec launch stage failed:, for the same reason. The bind and port prefixes, and exit status 1, don't change.each_class_of_failure_ends_the_clone_with_its_own_status(worker::activation::tests). ItsAnnounceFailurecase carries anio::Errorof kindAddrInUse, instead ofStartError::NoPrivilegedPort, since that is now the field's type. It still expectsACTIVATION_NETWORK.Removed:
guest::ingress::announcer::testsgoes with the deletedannouncer.rs: themod testsdeclaration inannouncer.rs, the module's inner attributes and imports, and its helpersPATIENCE,programandended.GATEWAYandsocketmove unchanged toguest::ingress::tests, the 2 relocated unchanged. The newannouncerhelper takes the place ofprogram, and the tests no longer needended, which polled anAnnouncer's pidfd, orPATIENCE.an_announcer_runs_its_program_with_its_socket_until_it_is_stopped. Its checks of the program's arguments and of the socket as standard input move toan_announcer_runs_its_program_with_its_socket_in_a_session_of_its_own, which also checks the session, its process group and the missing controlling terminal. Its check ofstopretires withAnnouncer::stop, sincestartleaves the announcer to init. The adapter'sannouncer_launch_keeps_the_socket_and_monitors_its_owned_childchecks the adapter's own stop.an_announcer_that_ends_polls_readable_and_keeps_its_statusretires withAnnouncer::pidfdandAnnouncer::try_wait. Nothing in nvx holds a started announcer any more.a_dropped_announcer_endsretires withAnnouncer'sDrop. The adapter'sannouncer_drop_stops_and_reaps_the_child_that_it_ownschecks the drop of its own launcher.start_errors_name_their_causeretires withStartError.bind_announcer_socketkeeps its socket, bind and port messages, whichingress_start_fails_when_the_announcer_does_not_startchecks through the program, and every spawn failure readsdid not start, as item 3 says.Added:
guest::ingress::tests: the testsan_announcer_runs_its_program_with_its_socket_in_a_session_of_its_own,an_announcer_starts_with_every_signal_s_default_disposition_and_none_blockedandan_announcer_does_not_start_without_its_program_when_its_caller_ignores_sigchld, and the helpersannouncerandlaunch_and_wait.worker::tests: the testsannouncer_launch_keeps_the_socket_and_monitors_its_owned_child,announcer_drop_stops_and_reaps_the_child_that_it_ownsandannouncer_failed_exec_reports_the_cause_and_leaves_no_child, and the helperannouncement_command.The
openvmmgitlink doesn't move.