Repository navigation
nvx-rs: create both guest datagram sockets with UdpSocket::ipv4 - #609
Merged
Pedro Henrique Penna (ppenna) merged 1 commit intoOct 19, 2026
Merged
Conversation
guest::sys::socket creates two close-on-exec IPv4 UDP sockets: the one that connect_datagram connects for nvx-device-io's network benchmark, and the unconnected UdpSocket from which nvx-ingress sends its announcements. connect_datagram spelled out the same socket(AF_INET, SOCK_DGRAM, SOCK_CLOEXEC) call as UdpSocket::ipv4, so the module kept two copies of the socket's family, type, and flags. connect_datagram now takes its socket from UdpSocket::ipv4, connects it, and returns it as the FileDescriptor that the benchmark reads and writes, as before. The module creates every datagram socket in one place, so the two programs cannot drift apart. Behavior is unchanged. Both programs make the same socket and connect system calls, with the same arguments and in the same order, and get the same errno when either fails. A socket whose connect fails still closes when its owner drops. The change is confined to the guest binaries' system layer, which only the guest feature builds. The socket module's tests cover UdpSocket::ipv4, the system layer's connected_datagrams_wait_for_and_receive_echoes covers connect_datagram, and the guest-tool test device_io_measures_a_network_round_trip runs the nvx-device-io binary against a local echo server. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
🟢 Approval recommended
The narrow refactor preserves behavior, existing tests cover both paths, and no unresolved issues remain.
No open issues 🎉
What changed in this PR
Centralizes guest IPv4 UDP socket creation, completing a cleanup identified in earlier refactors.
Changes:
- Reuses
UdpSocket::ipv4inconnect_datagram. - Preserves connection handling and the returned
FileDescriptor.
| File | Description |
|---|---|
nvx-rs/src/guest/sys/socket.rs |
Removes duplicate socket creation in favor of the existing constructor. |
Review effort: Balanced
Pedro Henrique Penna (ppenna)
deleted the
nvx-rs-quality/datagram-socket
branch
October 19, 2026 22:19
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.
Summary
nvx-rs/src/guest/sys/socket.rscreates the guest programs' two close-on-exec IPv4 UDP sockets:connect_datagram, which connects one for the network benchmark ofnvx-device-io;UdpSocket::ipv4, the unconnected socket from whichnvx-ingresssends its announcements.connect_datagramspelled out the samesocket(AF_INET, SOCK_DGRAM, SOCK_CLOEXEC)call asUdpSocket::ipv4, so the module kept two copies of the socket's family, type, and flags. It now takes its socket fromUdpSocket::ipv4, connects it, and returns it as theFileDescriptorthat the benchmark reads and writes, as before. The module creates every datagram socket in one place, so the two programs cannot drift apart.This is the sixth
nvx-rs-quality/pull request. #603, #605, #606, and #607, all merged, and #608, open, had approving Copilot reviews and no other feedback to follow. Nonvx-rs-quality/pull request was closed without merging. Those runs changedprotocol/exec.rs, the managed agent,host/filesystem.rs, and the time tools, so this run looked elsewhere. It surveyed the crate by reading and with a throwaway duplicate-window script, and skipped every file that an open pull request todevchanged when it started; #597, #598, and #608 changenvx-rs, and #585 changesaci_edge_sandboxes. It picked this follow-up of #606, #607, and #608 inguest/sys, which no earlier run touched. Of the candidates that the survey found, it removes the most duplicated code per changed line, and existing tests cover both of its paths.Changes
All changes are in
nvx-rs/src/guest/sys/socket.rs: 1 insertion and 6 deletions.connect_datagramgets its socket fromUdpSocket::ipv4instead of its ownnix::sys::socket::socketcall. Two sites now share that call:connect_datagram, fornvx-device-io network;UdpSocket::ipv4, fornvx-ingress's announcer.No item, signature, or other file changes.
Behavior
socketandconnectsystem calls, with the same arguments and in the same order, and get the sameerrnowhen either fails.connectfails still closes when its owner drops, and a connected socket still becomes the sameFileDescriptor.guestfeature, so the host and--no-default-featuresbuilds do not change.UdpSocket::ipv4;connected_datagrams_wait_for_and_receive_echoesinguest::syscoversconnect_datagram;device_io_measures_a_network_round_tripintests/guest_tools.rsruns thenvx-device-iobinary against a local echo server;private-network-ingressscenario runsnvx-ingressin the guest.Follow-ups
The survey turned these up, and this change leaves them alone.
guest/sys/spawn.rs,SpawnDescriptors::managedand the test-onlySpawnDescriptors::plaindiffer only ininherit_config.plaincould beSelf { inherit_config: false, ..Self::managed(...) }.console_pending.rsandmmio_write.rsmap each failure with a four-line closure that reports it and returnsCommandError::Operation, at seven sites. Reporters that return the error, asingress::usageandmanaged_agent::fataldo, would shorten each to one expression;reseed.rs, which Ship nvx-rs in NVX releases #598 changes, has three more.guest/device_io.rs,run_fileandrun_networkprint their measurement the same way; one helper could serve both.tests/guest_tools.rs,device_iorepeats the spawn and output collection ofrun.cgroup::tests::setupanddispatch::tests::direct_system, which are identical;Instance::runtimeandInstance::launchinhost/instance.rs;reseed.rs,time/mod.rs, andtime_probe/mod.rs;I found no suspected bug in the code that this change touches.
Validation
BASE:
4f5e255b436fecb4950f4aa71319d48e7d18ab43, which wasorigin/devwhen the run started: the merge of nvx-rs: replace the loopback System wrapper with a spawn hook #607. Before this pull request was opened,origin/devhad advanced only by a performance-baseline update, which does not changenvx-rs/src/guest/sys/socket.rs, and no open pull request todevchanged it.TREE:
c000e2dc4132dbd274ac30528f5acb6bb6eb0178, the tree of this commit. Every host applied the patch to BASE and checked thatgit write-treeequals TREE.Release on every host:
v0.1.0-dev.da399442504e. BASE has no release yet, sodownloadtook the one from two first-parent commits earlier. Its OpenVMM,5ab8a84621524f1777b2cb5e65a70dab42c8b453, is the pinned revision.Guest artifacts were rebuilt from TREE on prometheus30, with these steps:
build-guest-binaries --output;test-guest-binaries --binaries, where 34 tests passed;build-initramfswithNVX_GUEST_BINARIES.initramfs.cpio.gz(SHA-2564a4c0597b4bd6ea236a4c57c032d2751bdda504b9fbac01963761c62410a584c), its packages manifest, and its provenance went to the other two hosts, where the SHA-256 digests matched. Building them a second time, after the harness fix below, gave identical digests.Local checks on Windows with Rust 1.95.0:
-D warnings, for all targets and features and for the library without default features, natively and forx86_64-unknown-linux-gnu, which builds theguestmodule, and the guest binaries' musl lint forx86_64-unknown-linux-musl;cargo testwith all features: 314 library tests, 6 fake-OpenVMM tests, 5 CLI tests, and 1 doctest;aarch64-apple-darwin) checks, for bothnvx-rsandaci_edge_sandboxes.test-aci-edge-sandboxestest-microvm, default suitecheck-guest-binaries(319 tests), 600nvx-rstests with all features and 261 with the default ones, 157 and 85aci_edge_sandboxestests, artifact bundling, and agent bundling; the macOS checks ran locallynvx-rstests with all features and 261 with the default ones, 157 and 85aci_edge_sandboxestests, artifact bundling, and agent bundling; the MSRV checks ran locallyOn prometheus32, the first run of the gates failed 5 of the 10 tests in
tests/cli.rs, allinterrupts::tests, in which the CLI ignored Ctrl-C: three ended with 0 instead of 130, and in two, Ctrl-C did not end a write to a full pipe. My harness had caused it. It started the gates as a background job of a non-interactive shell, which ignores SIGINT, and the CLI keeps a SIGINT that it starts with ignored, as Python does; the job's mask wasSigIgn: 0x7. With the harness fixed to restore the default dispositions (SigIgn: 0), every gate and the guest-artifact build ran again and passed. The change does not touch the CLI.On prometheus32, the suite's time-ABI evidence line counted 2 of 58 boot checks over KVM's CPU-time budget. The suite reports that count but never gates on it, and this change does not touch the guest's time code. No host fell back to a host CPU profile.
Left to CI:
test-openvmm-unitandtest-openvmm;smp-lapic,managed-exec-config, andsandbox-lifecycle;