Skip to content

guest: make the guest's space private to the crate (SL6.13b) - #1548

Merged
Pedro Henrique Penna (ppenna) merged 1 commit into
feature/nvx-refactorfrom
agents/slim-sl6-13b-space-private
Nov 12, 2026
Merged

Pedro Henrique Penna (ppenna) merged 1 commit into
feature/nvx-refactorfrom
agents/slim-sl6-13b-space-private

Conversation

@ppenna

@ppenna Pedro Henrique Penna (ppenna) commented Nov 12, 2026 •

Copy link
Copy Markdown
Contributor

Part of #1127 (SL6.13b, "The guest's space is private"). Umbrella #1076.

Stacked on #1547 (SL6.11d).

What and why

The guest's space, the root that nvx-init assembles and what it mounts in it, is nvx-init's internal reference code, not a library API: the guest-agent guidelines tell another init to build its own. It was public but hidden from the documentation, waiting until nothing outside NVX used it. This PR makes it crate-private where it is, as SL6.13b's Scope says; SL6.11d (#1547), below it, first deleted the space's items that only tests used, so that none becomes dead here. One commit, 451dff46.

Visibility

  • guest::{root, view, gpt} become pub(crate) modules, with their items pub(crate), inside the guest module's gate, all(feature = "guest", target_os = "linux").
  • The mapper, guest::mappings::mapper with its kernel seam, becomes pub(crate). guest::mappings re-exports, crate-privately, only what NVX's programs use: Mapped, Mapper, MappingError, Reserved, SourceRoot, Step, TargetRoot and unbind_with; the re-exports of ApplyError, TeardownError and UnmountFailure, which nothing reads at that path, go. The mapping values (Mapping, Access, Kind, InvalidMapping, MAX_PATH_BYTES) and MappingTable, Refusal and TableError stay public.
  • The activation's application: apply, Applied, RootTemplate, ApplyError, AppliedTeardownError and NetworkError become pub(crate) where they are, in guest::activation::state::apply. guest::activation re-exports apply, Applied, ApplyError and RootTemplate, which nvx-init and the managed agent use at those paths, and no longer AppliedTeardownError and NetworkError, which nothing uses there. activation::state and state::apply become crate-visible, so that the three tests that build a NetworkError import it from its definition. MACHINE_ID_FILE and RESOLVER_FILE stay public.

Nothing moves and no behavior changes: nvx-init and the managed agent keep using the space at its paths, its unit tests stay with their owners, and Paths and window_directories stay where they are. rustfmt rewraps Root::mount_share's signature, which pub(crate) made longer.

Docs and examples

  • activation: Activation's example (guest/activation/state.rs) no longer uses apply, Applied or RootTemplate: its agent applies the record in its own space, Agent::activate, and passes the result to Activation::complete, as examples/guest-workflows.rs does. The module docs of guest::activation, Activation and ActivationAction::Apply describe nvx-init's application of a record as its internal reference code, private to the crate, without the space's names (apply, root::assemble, RootTemplate, Root::mount_export, view::apply, Applied, ApplyError).
  • snapshot's docs and example didn't use the space; they don't change. Its repair still reads root::Paths crate-privately.
  • gpt: guest::gpt's example becomes the compile-only unit test guest::gpt::tests::a_disk_s_steps_compile, as the case matrix said.
  • Wording: the crate's docs (lib.rs), guest's, guest::mappings', the space's own module docs and doc/guest-agent-guidelines.md say that the space is private to the crate, rather than hidden until nothing outside NVX uses it.
  • README: the module table drops nvx::guest::{root, view, gpt}, whose sections move, as #### sections, into a new "nvx-init's space" section of "Guest binaries", which says what the space is and links the guidelines' rules. nvx::guest::activation's section describes nvx-init's application without the space's names, as the rustdoc does, and drops Entry::check, which left with SL6.11b. nvx::guest::mappings' section, the guest binaries' introduction and nvx::protocol::export's section say "private" and stop pointing other inits to the mapper.
  • Case matrix (doc/acceptance-case-matrix.md): guest::gpt's doc test (line 18) names its unit test; Activation's doc test moves to line 54, with a note on its rewrite, guest::activation's to line 151 and guest's to line 33.
  • Public API: nvx-rs/public-api/linux.txt drops the space's 384 hidden lines, and adds none: guest::{root, view, gpt}, the mapper's items at guest::mappings and in guest::mappings::mapper, and the application's items at guest::activation and guest::clone. It still lists MappingTable, Refusal, TableError, the mapping values, and MACHINE_ID_FILE and RESOLVER_FILE. windows.txt doesn't change.

Old tests of the area

python3 scripts/check_test_changes.py --base origin/agents/slim-sl6-11d-space-test-only lists 3 changes to existing tests and 1 addition, so the PR has the tests-modified label:

  • guest::init::boot::tests::a_failed_activation_ends_the_vm_with_the_status_of_its_class, guest::managed_agent::session::tests::a_failed_restored_activation_gives_init_the_status_of_its_class and guest::root::tests::view::actual_resolver_failures_keep_the_network_class_and_root_owned_bind import NetworkError from its definition, guest::activation::state::apply, since guest::activation no longer re-exports it. Only the path changes.
  • Added: guest::gpt::tests::a_disk_s_steps_compile, guest::gpt's former example.
  • The doc tests: guest::gpt's leaves for its unit test, and Activation's is rewritten, as above; the root, view, mapper and activation-apply unit tests run unchanged at their owners.

Size

Measured as #1076 defines them, against SL6.11d's head 1b348b47:

Core lines Counted files
Estimate (#1127) 0 0
Measured 0 0

Every edit of a Rust file outside tests makes items crate-private, with the re-export edits that this forces and rustfmt's rewrap of one signature, or changes rustdoc only, so none counts.

Validation

The runs below ran at 1fdbe71e, on SL6.11d's earlier head d929dde4. The head, 451dff46, is the same commit rebased onto SL6.11d's 1b348b47, whose review fix changes only the rustdoc of MappingTable and the mapper: git range-diff shows no change in this commit. At 451dff46, these passed: on Windows, cargo fmt --all --check, cargo clippy --locked ... -- -D warnings for x86_64-unknown-linux-gnu (--all-targets --all-features, and --lib --no-default-features --features guest) and for x86_64-unknown-linux-musl (--all-targets --no-default-features --features guest), RUSTDOCFLAGS='-D warnings' cargo doc --locked --no-deps --all-features --target x86_64-unknown-linux-gnu, and the case matrix's check; on nvx-kvm-test, cargo clippy --locked --all-targets --all-features -- -D warnings, cargo test --locked --all-features --doc (14 and 1 passed), RUSTDOCFLAGS='-D warnings' cargo doc --locked --no-deps --all-features and python3 scripts/public_api.py.

Windows (local, at 1fdbe71e, Rust 1.95.0):

  • cargo fmt --all --check: passed.
  • cargo clippy --locked ... -- -D warnings, each passed: --all-targets --all-features; --lib; --lib --no-default-features; --lib --no-default-features --features serde; --lib --bins --features cli; --lib --bins --no-default-features --features testing; --all-targets --no-default-features --features guest; and, for the guest's code, --target x86_64-unknown-linux-gnu with --all-targets --all-features, --all-targets --no-default-features --features guest, --lib --bins --features cli, --lib --bins --no-default-features --features testing and --lib --no-default-features, and --target x86_64-unknown-linux-musl --all-targets --no-default-features --features guest.
  • RUSTDOCFLAGS='-D warnings' cargo doc --locked --no-deps --all-features, for Windows and for x86_64-unknown-linux-gnu: passed.
  • python scripts/public_api.py --update: linux.txt drops 384 hidden lines; python scripts/public_api.py then passed.
  • python scripts/check_test_layout.py, python scripts/check_markdown_links.py, and the case matrix's check against its baseline 99d2022085f: passed.
  • The Python unit tests of .github/actions/validate-nvx: 1803 ran, 73 skipped, and 1 failed, test_nvx_tools.NvxRsTests.test_readme_gives_each_module_a_short_row_and_a_section, which guest: delete the process modules and cgroups (SL6.11b) #1542's and guest: delete the space items that only tests use (SL6.11d) #1547's heads fail too: since SL6.11b, the README's module table has fewer than the 41 rows that the test wants (39), and this PR's three fewer rows leave 36.

Linux, nvx-kvm-test (KVM, Azure Linux 3.0, kernel 6.6.159, Rust 1.95.0), the commands of .github/actions/check-nvx-rs at 1fdbe71e, with default signal handling:

  • cargo fmt --all --check and the Clippy matrix, with --all-targets --no-default-features --features guest for the host's target: passed.
  • cargo test --locked --all-features: 1719 passed, 25 failed, 56 ignored in the library's unit tests, which run the root, view, mapper, GPT and activation-apply tests at their owners; every other target passed, the doc tests 14 of 14. The 25 failures are the same names as guest: delete the process modules and cgroups (SL6.11b) #1542's and guest: delete the space items that only tests use (SL6.11d) #1547's heads on this host, whose kernel 6.6 they need a later one for: guest::init::tests::exec (4) and guest::managed_agent::{dispatch::tests, tests::loopback::tests} (21).
  • cargo test --locked, cargo build --locked --lib --no-default-features and cargo test --locked --lib --no-default-features: passed.
  • RUSTDOCFLAGS='-D warnings' cargo doc --locked --no-deps --all-features, cargo +1.89 check --locked --all-targets --all-features (MSRV) and cargo check --locked --all-targets --all-features --target aarch64-apple-darwin: passed.
  • python3 scripts/public_api.py: passed.
  • python3 scripts/nvx.py check-guest-binaries --toolchain 1.95.0: Clippy passed; the musl tests 844 passed, 4 failed, the same 4 guest::init::tests::exec names as guest: delete the process modules and cgroups (SL6.11b) #1542's and guest: delete the space items that only tests use (SL6.11d) #1547's heads on this host.
  • python3 scripts/nvx.py build-guest-binaries and test-guest-binaries: passed (33 of 33).

MicroVM scenarios, nvx-kvm-test (KVM), at 1fdbe71e: the kernel built from this head in CI's Docker image (kernel-artifacts, vmlinux 8b133efd…, identical to #1542's K1 kernel, without CONFIG_MAGIC_SYSRQ), the Alpine, Ubuntu and Azure Linux initramfs images built from this head (build-initramfs), nvx-rs built from this head, and CI run 43242544111's OpenVMM (14dc4116, 75fb488d…), Ubuntu distro layer and sandbox scratch template, checked by SHA-256:

  • The full default suite, test-microvm --backend kvm, unsharded: all 52 scenarios passed, 58 runs with console-exit and smp at 1, 2, 4 and 8 vCPUs. Among them, the guest scenarios, the public sandboxes on EROFS and GPT roots with scratch and RAM uppers (sandbox-lifecycle, sandbox-proxy-only, sandbox-ram-upper, sandbox-gpt-layer, sandbox-blocks, managed-exec-config, vm-lifecycle), exports and mappings (filesystem-*, platform-aggregate-export, platform-filesystem), and the snapshots and restore activations (snapshot-core, snapshot-tiers, snapshot-rollback, scratch-snapshot, restore-*, platform-restore-processors, untiered-network-policy).
  • CI's guest and sandbox steps: the Ubuntu smoke tests (--guest ubuntu --processors 1: guest-boot, guest-identity, console-exit, lifecycle, virtio-net, filesystem-snapshot), the Azure Linux smoke tests (--guest azurelinux --processors 1: guest-boot, guest-identity, console-exit, virtio-net, network-snapshot, workload-identity, managed-lifecycle) and the extended Ubuntu tests on KVM (--guest ubuntu: managed-lifecycle, network-snapshot, smp, workload-identity): all 20 runs passed.

Code review: a review subagent read the whole diff, and found no significant issue.

Not run: the ignored privileged tests, which need root on the host; MSHV and WHP, since only the guest's code changes and it builds for Linux only; the debug kernel's suite. CI doesn't run on a Draft.

Deliberately left

  • guest::clone, the compatibility alias, and CaptureStage::Fence, which SL6.11c left: they don't change.
  • scripts/nvx_tools/kernel_features.py, which names nvx::guest::root and nvx::guest::gpt as consumers of kernel features: the modules keep their paths, and guest: delete the process modules and cgroups (SL6.11b) #1542's K1 owns the file.
  • doc/modules, whose diagrams CI redraws.

@ppenna Pedro Henrique Penna (ppenna) added tests-modified Changes existing tests, test data, or test wiring feat-nvx-refactor labels Nov 12, 2026
@github-actions

github-actions Bot commented Nov 12, 2026 •

Copy link
Copy Markdown
Contributor

This pull request changes existing tests

It modifies or removes 3 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

Change What Before After
modified test fn a_failed_activation_ends_the_vm_with_the_status_of_its_class in guest::init::boot::tests (only the paths that it names changed) nvx-rs/src/guest/init/boot/tests.rs:279 nvx-rs/src/guest/init/boot/tests.rs:279
modified test fn a_failed_restored_activation_gives_init_the_status_of_its_class in guest::managed_agent::session::tests (only the paths that it names changed) nvx-rs/src/guest/managed_agent/session/tests.rs:324 nvx-rs/src/guest/managed_agent/session/tests.rs:324
modified test fn actual_resolver_failures_keep_the_network_class_and_root_owned_bind in guest::root::tests::view nvx-rs/src/guest/root/tests/view.rs:156 nvx-rs/src/guest/root/tests/view.rs:156

Relocated unchanged: 0; added: 1. Compared the merge base f859d5c74d65 with 27b341e134f7.

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.

🟢 Approval recommended

No active review issues block the change to make nvx-init’s guest-space implementation crate-private.

No open issues 🎉

What changed in this PR

This PR implements SL6.13b of #1127, making nvx-init’s guest-space implementation crate-private as part of the library slimming workstream. It preserves public mapping values and contracts while narrowing visibility without changing runtime behavior.

Changes:

  • Makes guest root, view, GPT, mapper, and activation-application APIs crate-private.
  • Updates documentation and activation examples to distinguish public mechanisms from nvx-init’s internal implementation.
  • Adjusts test imports, preserves the GPT example as a compile-only unit test, and removes 384 hidden entries from the Linux API snapshot.
File Description
nvx-rs/​src/​lib.rs Describes the guest space as crate-private.
nvx-rs/​src/​guest/​view.rs Makes view operations and types crate-private.
nvx-rs/​src/​guest/​root/​tests/​view.rs Imports NetworkError from its definition.
nvx-rs/​src/​guest/​root/​share.rs Restricts share types and mounting methods.
nvx-rs/​src/​guest/​root.rs Restricts root assembly, types, and operations.
nvx-rs/​src/​guest/​mod.rs Makes root, view, and GPT modules crate-private.
nvx-rs/​src/​guest/​mappings/​mapper.rs Restricts mapper types and methods.
nvx-rs/​src/​guest/​mappings.rs Narrows mapper visibility while preserving public mapping contracts.
nvx-rs/​src/​guest/​managed_agent/​session/​tests.rs Updates the network-error construction path.
nvx-rs/​src/​guest/​init/​boot/​tests.rs Updates the network-error import.
nvx-rs/​src/​guest/​gpt/​tests.rs Preserves the former example as a compile-only unit test.
nvx-rs/​src/​guest/​gpt.rs Restricts guest disk-reading APIs and removes the migrated example.
nvx-rs/​src/​guest/​activation/​state/​apply.rs Makes activation application and related types crate-private.
nvx-rs/​src/​guest/​activation/​state.rs Narrows re-exports and rewrites the example around agent-owned application.
nvx-rs/​src/​guest/​activation.rs Updates application documentation and crate-private re-exports.
nvx-rs/​README.md Separates private guest-space documentation from the public module overview.
nvx-rs/​public-api/​linux.txt Removes the newly private guest-space API entries.
doc/​guest-agent-guidelines.md States that other inits build or adapt their own space.
doc/​acceptance-case-matrix.md Records the example migration and updated doctest locations.

Review effort: Balanced

@ppenna
Pedro Henrique Penna (ppenna) force-pushed the agents/slim-sl6-11d-space-test-only branch from d929dde to 1b348b4 Compare November 12, 2026 17:28
@ppenna
Pedro Henrique Penna (ppenna) force-pushed the agents/slim-sl6-13b-space-private branch from 1fdbe71 to 451dff4 Compare November 12, 2026 17:30
@ppenna
Pedro Henrique Penna (ppenna) force-pushed the agents/slim-sl6-11d-space-test-only branch from 1b348b4 to fb903d5 Compare November 12, 2026 17:48
@ppenna
Pedro Henrique Penna (ppenna) force-pushed the agents/slim-sl6-13b-space-private branch from 451dff4 to 5f45de3 Compare November 12, 2026 17:48
Base automatically changed from agents/slim-sl6-11d-space-test-only to feature/nvx-refactor November 12, 2026 18:06
The guest's space, the root that nvx-init assembles and what it mounts
in it, is nvx-init's internal reference code, not a library API, and
the guest-agent guidelines tell other inits to build their own. It was
public but hidden from the documentation, waiting until nothing outside
NVX used it. SL6.13b (#1127) makes it private to the crate where it is.

- guest::root, guest::view and guest::gpt become pub(crate) modules,
  and their items pub(crate), within the guest module's gate.
- The mapper, guest::mappings::mapper with its kernel seam, becomes
  pub(crate). guest::mappings re-exports, crate-privately, only the
  items that NVX's programs use: Mapped, Mapper, MappingError,
  Reserved, SourceRoot, Step, TargetRoot and unbind_with. The mapping
  values, Mapping, Access, Kind, InvalidMapping and MAX_PATH_BYTES,
  and MappingTable, Refusal and TableError stay public.
- The activation's application, apply, Applied, RootTemplate,
  ApplyError, AppliedTeardownError and NetworkError, becomes pub(crate)
  where it is. guest::activation re-exports apply, Applied, ApplyError
  and RootTemplate, which nvx-init and the managed agent use at those
  paths; activation::state and state::apply are crate-visible, so that
  the three tests that build a NetworkError import it from its
  definition. MACHINE_ID_FILE and RESOLVER_FILE stay public.

Nothing moves, and no behavior changes: nvx-init and the managed agent
keep using the space at its paths, and its unit tests stay at their
owners. Paths and window_directories stay where they are.

The docs and examples of snapshot and activation no longer use the
space. Activation's example agent applies the record in its own space,
whose result it passes to Activation::complete, and the activation's
module docs describe nvx-init's application, its internal reference
code, without its private names. The GPT module's example becomes the
unit test a_disk_s_steps_compile, and the case matrix names it, with
the doc tests' new lines.

The README's module table drops root, view and gpt, whose sections
move into the guest binaries' new "nvx-init's space" section, and the
crate's, the guest module's, the space's and the guidelines' docs say
that the space is private rather than hidden. The public API snapshot
drops the space's 384 hidden lines, and still lists MappingTable and
the mapping values.

Part of #1127 (SL6.13b).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@ppenna
Pedro Henrique Penna (ppenna) force-pushed the agents/slim-sl6-13b-space-private branch from 5f45de3 to 27b341e Compare November 12, 2026 18:07
@ppenna
Pedro Henrique Penna (ppenna) marked this pull request as ready for review November 12, 2026 18:08
@ppenna
Pedro Henrique Penna (ppenna) merged commit c0cf126 into feature/nvx-refactor Nov 12, 2026
81 of 84 checks passed
@ppenna
Pedro Henrique Penna (ppenna) deleted the agents/slim-sl6-13b-space-private branch November 12, 2026 18:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feat-nvx-refactor tests-modified Changes existing tests, test data, or test wiring

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants