Skip to content

guest: delete the process modules and cgroups (SL6.11b) - #1542

Merged
Pedro Henrique Penna (ppenna) merged 2 commits into
feature/nvx-refactorfrom
agents/slim-sl6-11b-process-modules
Nov 12, 2026
Merged

Pedro Henrique Penna (ppenna) merged 2 commits into
feature/nvx-refactorfrom
agents/slim-sl6-11b-process-modules

Conversation

@ppenna

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

Copy link
Copy Markdown
Contributor

Leaving code only. This PR changes only code that this effort removes from NVX: the guest process modules (guest::{exec, spawn, process, cgroup, entry}), the layered root's bootstrap, and the per-execution OS support that only they used, with the edits that remove references to them. Nothing that stays changes, and no later PR uses what it changes, so the size limits for kept code don't apply.

The second commit is #1123's follow-up K1, which the group issue gives this PR once guest::sys::entry's per-execution parts leave: it drops CONFIG_MAGIC_SYSRQ from the guest kernel and names the kernel features' current consumers and validators. It changes kept code, within the limits for kept code (43 core lines in 1 counted file).

Part of #1123 (SL6.11b, "The process modules and cgroups are gone"). Parent #1087, umbrella #1076.

What and why

SL7.8b (#1534) and SL7.8c (#1536) deleted the old layered init, the managed agent's sandbox mode and the one-shot container helpers, the last users of the guest process modules: guest::exec ran a layered root's executions, which guest::spawn started, guest::entry entered into their namespaces, view and identity, guest::cgroup placed and guest::process collected, and guest::root's bootstrap moved the init's processes into the cgroups that held them. nvx-init runs its workloads as plain processes through sys::spawn, without per-execution containment, so nothing calls them any more. Two commits: b4e4937c does SL6.11b's Scope, and 9830b1e1 does follow-up K1.

The process modules and cgroups (b4e4937c)

  • The modules: guest::{exec, spawn, process, cgroup, entry}, with their submodules and tests, and guest::root::{bootstrap, Bootstrap, BootstrapStep, Resources}, with root::Error::Bootstrap.
  • The per-execution entry of sys::entry: EntryChild, its clone3 start in new mount, PID and UTS namespaces, its view of /proc, /sys and /dev with the procfs entries that it masked or made read-only, its move into the root, its umask and its working directory's resolution beneath the root, and the CloneArgs and OpenHow structures. sys::entry keeps a layered root's runtime file systems and the workload identity, which nvx-init and Root use.
  • The spawn child's per-execution stages, with their ChildSpec setters: the root, the working directory's credentials check, inherited descriptors, the cgroup placement, the session, the barrier and the entry. The child keeps the path of nvx-init's workloads, unchanged. LaunchStage, whose numbers the child's launch report carries and which guest::spawn held, moves into sys::spawn as a crate-private enum of the 10 stages that the child still takes, each with its number (1, 4, 13 to 16, 18 to 21), which nvx-init's launch report and the managed agent decode; from_code, which only guest::spawn used, goes.
  • The signal helpers that only exec used: process_group_of, WaitTarget and wait_named, and the sys re-exports of signal_process_group and signal_through_pidfd, which sys::process keeps for kill_process_group and kill_through_pidfd.
  • Every cgroup helper: guest::cgroup, and root::kernel's Kernel::write, which only the bootstrap's cgroup and sysctl writes called.
  • fd's per-execution support: shut_down_sending, take_pipe_end, open_at and create_socket_pair, which only guest::exec's pipes and sockets used. Its per-execution memfd and seals already left with guest: run direct workloads on the init exec core #1310.
  • Crate-private code that the warning-denied builds then flag as unused: root::bind_runtime_file, whose retained variant bind_runtime_file_retained takes its rustdoc, and guest::mappings' bind_with re-export. guest::account's items, which only guest::entry re-exported, become crate-private.
  • Public API: nvx-rs/public-api/linux.txt drops the five modules (299 lines), with guest::entry's account re-exports, and the hidden guest::root::{bootstrap, Bootstrap, BootstrapStep, Resources} and root::Error::Bootstrap; windows.txt doesn't change, as the guest is Linux-only.
  • Docs: the rustdoc of guest, guest::root, sys and the kept OS modules, the crate's guest summary in lib.rs, nvx-rs/README.md, whose module table and sections drop the five modules and whose root row and section drop the bootstrap, and doc/guest-agent-guidelines.md no longer describe them. scripts/test-layout-allowlist.json is tightened (check_test_layout.py --tighten): the deleted modules' test hooks go, and sys/spawn.rs's count falls from 7 to 5.
  • The case matrix: the deleted modules' 8 doc tests become retired Docs rows (guest::cgroup line 36, guest::entry 90, guest::exec 79 and Execution::adopt 619, guest::process 12 and 39, guest::spawn 41, LaunchStage::from_code 201), and the kept doc tests of guest/mod.rs, guest/root.rs and lib.rs move to lines 34, 126 and 53, with the summary's counts.

What stays: Root::switch, with its move of the root and its change of root (Kernel::enter_root, through sys::spawn::enter_root), the rooted open's EAGAIN retry (sys::rooted), nvx-init's spawn child, the workload identity and runtime file systems of sys::entry, and every OS helper with a kept caller.

Follow-up K1: the kernel's magic SysRq and the features' consumers (9830b1e1)

The decision is on #1123 (#1123 (comment)).

  • Magic SysRq leaves the guest kernel. The diagnostics feature kept CONFIG_MAGIC_SYSRQ for the per-execution entry, which made /proc/sysrq-trigger read-only for user ID 0 and leaves in the first commit, and its only validator was the deleted adapter's vm_layered test. Nothing that stays reads or writes /proc/sysrq-trigger or kernel.sysrq, and nvx-init and the managed agent refuse user ID 0 and drop every capability, so their workloads couldn't write the trigger anyway. It had a live side effect: the hvc console took ^O on the kernel console, where an nvx-rs run shell reads, as a SysRq prefix, so ^O never reached bash, vim or nano there, and ^O c, b or o crashed, rebooted or powered off the guest.
  • The configuration is regenerated with nvx.py kernel-config in the Docker build's image: kernel/config-microvm has # CONFIG_MAGIC_SYSRQ is not set in place of CONFIG_MAGIC_SYSRQ=y, CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x1 and # CONFIG_MAGIC_SYSRQ_SERIAL is not set, and kernel/config-microvm.derived drops CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE. The configuration sets 767 symbols, 174 by the inventory's 25 features and 593 derived, 52 of them with a prompt (from 769, 175, 594 and 53). vmlinux shrinks from 21,594,072 to 21,581,680 bytes.
  • The features name what uses them now: processors and memory-hotplug name nvx::guest::snapshot::capture, whose restore repair replaced the clone repair, and the snapshot helper, and are validated by the restore-processors, platform-restore-processors and restore-memory scenarios rather than the adapter's clone tests; virtio-console, block-storage, sandbox-filesystems and host-filesystem name nvx-init, nvx::guest::root and nvx::guest::activation rather than nvx-init-agent and nvx::guest::clone, and block-storage is validated by the sandbox-gpt-layer and snapshot-tiers scenarios rather than the adapter's GPT tests; linux-abi and diagnostics no longer name the adapter, and diagnostics' only consumer is CI's logs, validated by build-kernel's configuration checks.
  • sandbox-isolation keeps its settings (decision 2, follow-up K2): its rationale now says that no NVX component uses them since SL7.8b, SL7.8c and SL6.11b, that only root programs in a guest, such as an nvx-rs run shell, can use them, and that NAMESPACES also stays for NET_NS. It no longer names nvx-init-agent, nvx-container-launch, nvx::guest::cgroup, nvx::guest::entry or nvx-snapshot, whose freezer path nothing reaches; build-kernel's sandbox group validates it. nvx-container-enter was never named in the file.
  • doc/build.md lists magic SysRq among what the inventory removed, drops "serial sysrq", which no longer appears, from the platform options, updates the configuration's counts, and rewrites the cgroup row and the Sandbox group's purpose, which described the old sandbox, to match decision 2.
  • Tests: no test names CONFIG_MAGIC_SYSRQ or the diagnostics feature; test_kernel_config.py's checks of the checked-in configuration and the inventory pass with the regenerated files.
  • CI will build both kernels again, since the inventory and the configuration are kernel inputs, and builds them on ubuntu-26.04 for the first time.

Deliberately left

Size

Measured as #1076 defines them, against feature/nvx-refactor, 22163771:

Core lines Counted files
Estimate (#1123) 0 7
Measured, the deletion (b4e4937c) 55 10
Measured, K1 (9830b1e1) 43 1
Measured, total 98 11
  • Core lines (55): 45 in guest/sys/spawn.rs, of which 29 are LaunchStage and its code, moved from guest::spawn with the stages that stay, and the rest its imports and the child's conditions without the deleted stages; 7 in guest/sys/mod.rs, the re-export lists without the deleted items, as rustfmt wraps them; and 1 each in guest/sys/entry.rs and guest/sys/fd.rs (imports) and guest/mappings.rs (the re-export without bind_with). guest/account.rs's 6 lines only make items crate-private, so they don't count.
  • Counted files (10): guest/mod.rs, guest/mappings.rs, guest/root.rs, guest/root/kernel.rs, guest/view.rs and guest/sys/{entry,fd,mod,process,spawn}.rs, in nvx-rs/src/. Not counted: guest/account.rs (crate-private only), lib.rs, guest/activation.rs and guest/time/api.rs (rustdoc only), the 12 deleted files, tests, docs, the allowlist and the generated API snapshot. - K1 (43 core lines, 1 counted file): scripts/nvx_tools/kernel_features.py, whose rationales, consumers and validations change, and whose diagnostics feature drops CONFIG_MAGIC_SYSRQ=y. The regenerated kernel/config-microvm and config-microvm.derived are generated files, and doc/build.md is docs.

Old tests of the area

  • Retired, with the code that they tested: 125 tests and the 8 doc tests above.
    • guest::exec::tests::a_stalled_sink_stalls_only_its_own_execution_and_loses_nothing, which failed on GitHub's ubuntu-26.04 runners until tests: keep the Linux tests true with Ubuntu 26.04's coreutils #1535, leaves with guest::exec.
    • guest::root::tests' 6 bootstrap tests and guest::sys::spawn::tests' a_child_enters_its_root_or_reports_why_not, the_check_s_credentials_keep_the_parent_s_supplementary_groups and an_entry_leads_a_session_and_keeps_its_barrier_from_the_program test the deleted bootstrap and child stages.
guest::cgroup::tests, 17 tests

layouts_keep_the_agent_out_of_the_workload_subtree, executions_run_in_the_workload_cgroup_or_in_one_child_of_it, preparation_creates_the_cgroup_and_enables_its_controllers_together, invalid_resources_change_nothing, an_execution_s_own_cgroup_is_new_and_takes_its_controllers_from_the_workload, a_failed_preparation_leaves_no_cgroup_of_the_execution_s_own, an_empty_resource_value_reaches_its_file_as_a_newline, occupancy_is_the_scope_s_canonical_process_count, a_kill_reaches_the_scope_s_cgroup_alone, settlement_collects_statuses_between_its_checks_until_the_deadline, processes_are_placed_in_the_execution_s_cgroup, a_handle_reaches_its_own_cgroups_alone_once_another_takes_a_path, only_an_empty_cgroup_of_the_execution_s_own_is_removed, cgroup_operations_leave_an_unrelated_child_s_status, descendants_that_hold_pipes_are_found_and_settled, a_removal_leaves_a_cgroup_prepared_at_its_path_by_a_concurrent_one, a_failed_preparation_removes_its_own_cgroup_alone

guest::entry::tests, 22 tests

the_allowlist_holds_the_thirteen_capabilities, capability_sets_add_remove_and_list_their_members, every_capability_outside_the_allowlist_is_refused, only_user_id_zero_may_hold_capabilities, published_listeners_refuse_binding_and_raw_sockets, invalid_roots_ids_groups_and_hostnames_are_refused, existing_accounts_are_read_below_the_root, account_databases_are_bounded_regular_files_reached_through_no_link, an_entry_needs_a_root_directory, runtime_binds_need_a_mount_root_unless_there_are_none, runtime_binds_are_made_in_order_and_removed_in_reverse, a_failed_runtime_bind_removes_the_binds_before_it, a_failed_runtime_bind_names_the_binds_before_it_that_stay, a_runtime_bind_that_stays_is_reported, device_sets_select_their_nodes, each_entry_stage_reports_its_own_failure_and_runs_nothing, a_denied_umask_fails_the_proc_stage_and_runs_nothing, an_entered_program_leads_a_session_without_a_terminal_or_the_callers_descriptors, an_entered_program_ignores_and_blocks_no_signal_of_its_caller_s, an_entry_needs_a_placement_and_neither_a_root_nor_a_check, privileged_entries_see_their_own_view_and_identity, privileged_runtime_binds_are_removed_before_a_teardown

guest::exec::tests, 44 tests

a_program_s_launch_output_and_status_are_reported, a_failed_launch_stage_is_reported_and_the_execution_still_ends, an_execution_without_output_ends_through_its_descriptors_alone, concurrent_executions_progress_independently, a_stalled_sink_stalls_only_its_own_execution_and_loses_nothing, cancellation_ends_a_stalled_program_and_the_caller_discards_the_rest, stdin_eof_follows_every_byte_that_a_write_took, a_program_that_closes_its_input_ends_the_writes_without_sigpipe, concurrent_writers_meet_closed_inputs_without_sigpipe, a_timeout_ends_the_program, a_timeout_whose_signals_the_kernel_refuses_fires_once, a_disconnection_discards_the_output_and_ends_the_execution, causes_count_only_while_the_program_runs, an_observed_status_ends_the_execution, a_caller_that_reaps_is_the_program_s_only_collector, ending_the_program_ends_the_process_group_that_it_leads, a_status_that_another_collector_took_first_is_left_to_it, a_start_after_another_collector_took_the_status_ends_nothing_by_id, the_program_s_end_closes_its_input_for_a_descendant_that_reads_it, dropping_an_unfinished_execution_ends_its_program, an_unrelated_child_s_status_is_left_alone, both_streams_take_turns_while_each_has_output, the_cgroup_is_killed_once_another_collector_took_the_status_with_the_output_held, the_cgroup_is_killed_once_the_program_ends_with_its_output_held, a_failed_kill_is_reported, a_kill_never_reaches_a_cgroup_that_took_the_path_later, a_failed_start_ends_the_program_and_its_cgroup_even_without_descriptors, a_failed_start_ends_a_program_that_joined_another_process_group, the_program_s_ends_block_and_the_execution_s_do_not, an_adopted_program_s_launch_comes_at_once_then_its_output_and_status, an_adopted_program_reads_its_input_to_its_end, an_adopted_program_that_a_nonblocking_pidfd_names_runs_as_any_other, an_adopted_program_that_its_id_names_is_cancelled_with_its_process_group, an_adopted_program_whose_status_was_observed_has_ended_and_its_output_is_read, adopting_a_program_whose_status_another_collector_took_ends_nothing_by_id, a_failed_adoption_ends_the_program_and_its_cgroup_without_descriptors, adopted_ends_are_pipe_ends_that_go_the_way_of_their_streams, a_program_that_handles_a_signal_ends_with_its_own_status_and_all_of_its_output, a_program_that_ignores_a_signal_runs_until_the_caller_terminates_it, a_signal_reaches_the_process_group_that_the_program_leads_if_the_options_say_so, a_signal_reaches_each_process_once, a_signal_reaches_nothing_once_a_collector_took_the_program_s_status, a_failed_group_lookup_is_an_error_that_sends_no_second_signal, a_kill_and_a_signal_that_the_kernel_refuses_are_errors_that_end_nothing

guest::process::tests, 9 tests

a_named_child_s_status_is_collected_and_no_other, a_pidfd_polls_readable_once_its_child_ends, a_child_named_by_the_caller_s_pidfd_is_waited_for_through_it, a_child_that_reports_its_end_with_no_signal_is_waited_for, an_observed_status_belongs_to_its_child_alone, stops_and_continuations_do_not_end_an_observed_child, a_traced_child_s_stop_does_not_end_it, a_child_whose_status_another_collector_took_is_echild, ids_that_no_process_can_have_are_refused

guest::root::bootstrap::tests, 2 tests

kernel_threads_are_known_by_their_flags, membership_lists_are_decimal_lines

guest::root::tests, 6 tests

bootstrap_moves_every_process_but_kernel_threads_and_applies_the_resources, bootstrap_mounts_the_hierarchy_unless_the_parent_is_a_cgroup, bootstrap_names_the_failed_step_and_keeps_the_earlier_changes, bootstrap_accepts_a_missing_sysctl_only_without_user_namespaces, bootstrap_fails_while_a_process_keeps_returning_to_the_parent, bootstrap_succeeds_when_the_last_pass_empties_the_parent

guest::spawn::tests, 22 tests

a_program_runs_with_its_arguments_environment_and_streams, a_program_without_an_environment_inherits_its_parent_s, inherited_descriptors_stay_open_at_their_numbers_and_others_close, the_working_directory_and_physical_pwd_follow_the_command, a_program_named_without_a_slash_is_searched_for_in_the_command_s_path, a_search_skips_a_path_longer_than_path_max, a_search_refuses_a_name_longer_than_name_max, a_search_s_memory_is_bounded_whatever_its_name_and_path, launch_stage_failures_are_reported_and_run_nothing, a_child_joins_its_cgroup_and_enters_its_checked_directory, invalid_commands_fail_to_spawn, short_and_unknown_reports_are_protocol_errors, launch_stages_keep_their_numbers, launch_stages_are_in_their_order, a_child_waits_at_its_barrier_until_released, a_dropped_barrier_cancels_the_launch, a_dropped_barrier_cancels_its_launch_while_another_child_waits_at_its_own, another_childs_pipes_hang_up_while_a_child_waits_at_its_barrier, releasing_the_barrier_of_an_ended_child_fails, a_new_session_has_no_controlling_terminal, a_program_keeps_its_caller_s_ignored_and_blocked_signals_unless_its_command_resets_them, a_child_whose_report_has_no_reader_still_exits_with_the_launch_failure_status

guest::sys::spawn::tests, 3 tests

a_child_enters_its_root_or_reports_why_not, the_check_s_credentials_keep_the_parent_s_supplementary_groups, an_entry_leads_a_session_and_keeps_its_barrier_from_the_program

  • Rewritten (10 tests, which keep what their names say without a deleted item):
    • guest::sys::spawn::tests: invalid_specs_are_refused_before_forking, stream_sources_below_the_standard_streams_are_raised_and_kept_from_the_program and the_launch_descriptors_are_close_on_exec lose their cases of the credentials check, inherited descriptors and the cgroup placement.
    • guest::sys::entry::tests::the_kernel_structures_have_their_uapi_sizes loses CloneArgs and OpenHow.
    • guest::sys::port::tests::transactions::a_thread_that_may_hold_the_permission_spawns_no_command spawns through sys::spawn's ChildSpec and PreparedChild rather than guest::spawn::Command, with the same refusals and the same empty launch report.
    • guest::sys::signal::tests::a_write_takes_back_its_own_sigpipe_beside_one_pending_for_the_process and guest::init::tests::exec::a_stolen_or_auto_reaped_status_is_reported_once_and_never_reclassified_by_an_ending wait with sys::wait rather than guest::process::Child::wait and wait_named, for the same statuses.
    • guest::init::tests::exec::privileged_capture_sweep_kills_setsid_escapees_and_spares_both_helpers reads process groups with getpgid rather than process_group_of.
    • guest::sys::process::tests::a_real_time_signal_goes_through_a_pidfd_and_to_a_process_group drops its check of process_group_of; its signals to the group still succeed.
    • guest::managed_agent::dispatch::tests::runtime::privileged_layered_runtime_stops_before_attach_on_pending_sigterm, with the helpers termination, prelaunch_termination and backpressured_termination, signals through sys::tests' re-export of signal_through_pidfd: only the path changes.
  • Modified: scripts/test_nvx_tools.py's NvxRsTests.test_readme_gives_each_module_a_short_row_and_a_section expects more than 30 rows in nvx-rs/README.md's module table rather than 40: the table keeps 39 of its 44 rows. The floor only shows that the test reads the module table, and SL6.13b will leave 36.
  • Kept: every other test of nvx-init, the managed agent, guest::root and the kept OS modules.

Test changes

python scripts/check_test_changes.py --base origin/feature/nvx-refactor lists 268 changes to existing tests, hence tests-modified:

  • Removed: the 125 tests retired above; the 6 deleted test modules, with their inner attributes and imports; 96 helpers that only the retired tests used, among them root::kernel::tests' fake writes and process moves (pin, writes, move_process, write), root::tests' bootstrap fixtures (Process, hierarchy, bootstrap_in, interface_files), sys::entry::tests' Simulation, sys::fd::tests' set_descriptor_limit, sys::process::tests' spawn_child_without_exit_signal, spawn_traced_child and continue_traced, and sys::spawn::tests' CAP_SYS_CHROOT; and the 10 test hooks of deleted code (ExecutionCgroup::{prepare, remove}, Entry::prepare, guest::exec's leads_its_group and signal_through_pidfd, EntryChild with clone_flags and stage, and PreparedChild::{take_credentials, restore_credentials}).
  • Modified: the 10 tests rewritten above and the README test above; the helpers Operation, Call and State of root::kernel::tests, which lose the write; the three runtime helpers above (paths only); and the imports of root::tests and sys::tests, whose re-exports follow the deleted helpers.

Validation

local_gates.py --files (from dev) selects test-changes, markdown-links, test-layout, every step of check-nvx-rs and nvx-cli (validate-nvx), on both systems; its runtime-adapter gates no longer exist on this branch. I ran them from this branch's action definitions, at the heads that the tables give. The branch moved with its stack, with rerere off each time:

The README floor. test_readme_gives_each_module_a_short_row_and_a_section required more than 40 rows in nvx-rs/README.md's module table. This PR's runs of validate-nvx's unittest list, at 004d770e and 543248e7, sat on 321bd2b5, where the table had 46 rows and this PR left 41. SL6.4 then removed 2 (nvx::host::artifacts and nvx::host::seal), so from the restack onto bf2c816e on the table kept 39, and after that restack I had rerun only the Rust gates and the K1 smoke run, not the Python tests. The deletion commit now lowers the floor to 30 (see Old tests of the area), and the list passes again on the final head.

On the final head, 9830b1e1, on 22163771:

Check Windows nvx-mshv-test nvx-kvm-test
cargo fmt --all --check, and cargo clippy --locked with -D warnings for --all-targets --all-features, --lib, --lib --no-default-features, and serde, cli and testing alone, and on Linux --all-targets --no-default-features --features guest passed passed passed
cargo test --locked --all-features passed: lib 1064, 18 ignored passed: lib 1773, 60 ignored lib 1743 passed, 30 failed, all of them failures of the base on kernel 6.6: the 25 below, and SL4.4b's 5 new managed_agent::dispatch::tests::streams tests, which fail at 22163771 too, as their 19 siblings do ("the isolated test process failed")
cargo test --locked, --lib --no-default-features, cargo doc with -D warnings, cargo +1.89 check (MSRV) passed: lib 686, 10 ignored; 190 passed passed
python3 scripts/public_api.py, cargo check --target aarch64-apple-darwin public API passed passed passed
nvx.py check-guest-binaries (musl lint and tests), build-guest-binaries, test-guest-binaries Linux only passed: 856, 33 ignored 852 passed, 4 failed: the base's 4 guest::init::tests::exec failures on kernel 6.6
scripts/test_nvx_tools.py passed: 536, 44 skipped passed: 536, 14 skipped passed: 536, 14 skipped
validate-nvx's unittest list, test_adversarial.py, nvx.py's --help commands passed: 1803, 73 skipped; 84; all --help passed: 1803, 38 skipped (unittest list) not run
nvx.py verify, check_test_layout.py, check_markdown_links.py, SL5.2's check_matrix.py, check_test_changes.py passed; 268 changes

Windows, this workstation (Rust 1.95.0), on 004d770e (the deletion before the second restack):

Check Result
cargo fmt --all --check passed
cargo clippy --locked with -D warnings: --all-targets --all-features, --lib, --lib --no-default-features, and serde, cli and testing alone passed
cargo test --locked --all-features passed: lib 1052 passed, 15 ignored, and every integration and doc test
cargo test --locked passed: lib 733 passed, 7 ignored
cargo build --locked --lib --no-default-features, cargo test --locked --lib --no-default-features passed: 190
RUSTDOCFLAGS=-D warnings cargo doc --locked --no-deps --all-features passed
cargo +1.89 check --locked --all-targets --all-features (MSRV) passed
validate-nvx's unittest list, test_adversarial.py and nvx.py's --help commands passed: 1803 tests, 73 skipped; test_adversarial.py 84, 11 skipped
python scripts/nvx.py verify, check_test_layout.py, check_markdown_links.py passed
SL5.2's check_matrix.py <worktree> 99d2022085f passed
check_test_changes.py 267 changes then, 268 with the README test

Linux, nvx-mshv-test (Azure Linux 3, kernel 6.18, MSHV, virtual machine) and nvx-kvm-test (Azure Linux 3, kernel 6.6, KVM, virtual machine), each in a worktree of this branch with its own target directory, every signal at its default disposition, on 004d770e:

Check MSHV KVM
cargo fmt, and cargo clippy with -D warnings for every feature set above and --no-default-features --features guest --all-targets passed passed
cargo test --locked --all-features passed: lib 1748, 57 ignored lib 1723 passed, 25 failed: the base's failures on kernel 6.6 (4 in guest::init::tests::exec, 19 in managed_agent::dispatch::tests, 2 in managed_agent::tests::loopback), none new
cargo test --locked, --lib --no-default-features, cargo doc with -D warnings passed passed
python3 scripts/public_api.py (both snapshots) passed passed
cargo +1.89 check (MSRV), cargo check --target aarch64-apple-darwin passed passed
nvx.py check-guest-binaries (musl lint and tests) passed: 847, 33 ignored, and 16 doc tests 843 passed, 4 failed: the base's 4 guest::init::tests::exec failures on kernel 6.6, none new
nvx.py build-guest-binaries, test-guest-binaries passed passed

The base, 00341544 (SL7.8b's head) measured on the same hosts, failed the same KVM tests plus three that this PR deletes (guest::entry::tests::runtime_binds_need_a_mount_root_unless_there_are_none and two guest::exec tests); MSHV passed everything there too.

microVM scenarios on both backends, with the Alpine, Ubuntu and Azure Linux initramfses built from this branch on nvx-kvm-test (SHA-256 22c52f69…, af1610af… and 73ca3879…, identical before and after the restack, and copied to nvx-mshv-test with their digests checked), and CI run 43185976865's kernel, Ubuntu distro layer, scratch template and OpenVMM (692ac2a9…, 86c6685a…, 1d0d8c89… and 75fb488d…, checked by SHA-256), whose inputs match this branch's:

Scenarios KVM MSHV
Alpine, 1 vCPU: guest-boot, guest-identity, console-exit, lifecycle, managed-lifecycle, workload-identity, console-snapshot, network-snapshot, filesystem-snapshot passed passed
Public sandbox, nvx-init's layered roots, uppers, views, exports, mappings and restore activation: managed-exec-config, sandbox-lifecycle, sandbox-proxy-only, sandbox-ram-upper, sandbox-gpt-layer, vm-lifecycle, untiered-network-policy, snapshot-core, snapshot-tiers passed passed
Restore: restore-processors, 1 and 2 vCPUs and untargeted passed passed
Ubuntu: guest-boot, guest-identity, console-exit, lifecycle, virtio-net, filesystem-snapshot passed passed
Azure Linux: guest-boot, guest-identity, console-exit, virtio-net, network-snapshot, workload-identity, managed-lifecycle passed passed

No OpenVMM process was left. These scenarios ran on CI's kernel, before K1.

K1, on 543248e7 (K1 before the second restack, the same tree for the kernel's inputs) unless a row says otherwise:

Check Result
nvx.py kernel-config (in the Docker build's image, on nvx-kvm-test) regenerated the two files above
nvx.py kernel-config --check, nvx.py check-kernel-config, nvx.py verify passed: "767 symbols set: 174 by the inventory's 25 features, 593 derived, 52 of them with a prompt"
test_kernel_config.py, test_kconfig.py (Linux and Windows) passed: 34, 1 skipped
docker build --target kernel-artifacts and --target kernel-debug-artifacts, as CI builds them, with build-kernel's required-group checks and its inventory check ("kernel configuration matches its inventory (188 settings, 593 derived symbols)", exact toolchain) passed: vmlinux 8b133efd… (config 60f480bf…) and vmlinux-debug 16f57573…, both with # CONFIG_MAGIC_SYSRQ is not set
ruff check, ruff format --check, compileall, pyright for Linux and Windows passed, 0 errors
validate-nvx's unittest list passed: 1803 tests, 73 skipped
check_markdown_links.py passed

The K1 kernel, with this branch's Alpine image and CI's distro layer, scratch template and OpenVMM, booted on all three backends: guest-boot, console-exit, sandbox-lifecycle, snapshot-core (named snapshot restores) and restore-processors (1 and 2 vCPUs and untargeted) passed on KVM (nvx-kvm-test), MSHV (nvx-mshv-test) and WHP (nvx-whp-test, a Windows WHP virtual machine, with CI's Windows OpenVMM 7abd8c8d…), and no OpenVMM process was left.

On MSHV, typing a, ^O, h, b and Enter into read -r line in an nvx-rs run shell:

Kernel /proc/sysrq-trigger, kernel.sysrq Console The line that the shell read
CI's, 692ac2a9… present, 1 sysrq: HELP : loglevel(0-9) reboot(b) crash(c) … 61 62: ^O and h never reached it
K1's, 8b133efd… absent nothing 61 0f 68 62: ^O and h reached it

CI, run 43268333520 on 9830b1e1: both kernels built on ubuntu-26.04 for the first time (runner image 20261101.186.1), from the Docker build rather than a cache, with "kernel configuration matches its inventory (188 settings, 593 derived symbols)"; its vmlinux.config is the one built above (60f480bf…, # CONFIG_MAGIC_SYSRQ is not set). Every job passed on the first attempt but nvx-rs / windows-latest, where tests/cli/exec_lock.rs::exec_processes_contend_but_other_sandboxes_and_stop_proceed's nvx-rs sandbox stop --timeout 0.1 failed with error[still-running]: cannot confirm exit of VM process 7540: a host CLI test with the fake OpenVMM on Windows, whose build this PR doesn't change (it changes only Linux guest code, docs, scripts and the kernel's configuration), and which passed on the base's push run (43263930955), on this workstation at 9830b1e1, and on the rerun of the failed jobs, with which the run completed green.

@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 268 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 helper fn termination in guest::managed_agent::dispatch::tests::runtime (only the paths that it names changed) nvx-rs/src/guest/managed_agent/dispatch/tests/runtime.rs:136 nvx-rs/src/guest/managed_agent/dispatch/tests/runtime.rs:136
modified helper fn prelaunch_termination in guest::managed_agent::dispatch::tests::runtime (only the paths that it names changed) nvx-rs/src/guest/managed_agent/dispatch/tests/runtime.rs:211 nvx-rs/src/guest/managed_agent/dispatch/tests/runtime.rs:211
modified helper fn backpressured_termination in guest::managed_agent::dispatch::tests::runtime (only the paths that it names changed) nvx-rs/src/guest/managed_agent/dispatch/tests/runtime.rs:574 nvx-rs/src/guest/managed_agent/dispatch/tests/runtime.rs:575
modified helper enum Operation in guest::root::kernel::tests nvx-rs/src/guest/root/kernel/tests.rs:29 nvx-rs/src/guest/root/kernel/tests.rs:29
modified helper enum Call in guest::root::kernel::tests nvx-rs/src/guest/root/kernel/tests.rs:74 nvx-rs/src/guest/root/kernel/tests.rs:72
modified helper struct State in guest::root::kernel::tests nvx-rs/src/guest/root/kernel/tests.rs:165 nvx-rs/src/guest/root/kernel/tests.rs:161
modified imports the imports of guest::root::tests nvx-rs/src/guest/root/tests.rs:5 nvx-rs/src/guest/root/tests.rs:4
modified imports the imports of guest::sys::tests nvx-rs/src/guest/sys/tests.rs:3 nvx-rs/src/guest/sys/tests.rs:3
modified test fn a_stolen_or_auto_reaped_status_is_reported_once_and_never_reclassified_by_an_ending in guest::init::tests::exec nvx-rs/src/guest/init/tests/exec.rs:729 nvx-rs/src/guest/init/tests/exec.rs:729
modified test fn privileged_capture_sweep_kills_setsid_escapees_and_spares_both_helpers in guest::init::tests::exec nvx-rs/src/guest/init/tests/exec.rs:1190 nvx-rs/src/guest/init/tests/exec.rs:1190
modified test fn privileged_layered_runtime_stops_before_attach_on_pending_sigterm in guest::managed_agent::dispatch::tests::runtime (only the paths that it names changed) nvx-rs/src/guest/managed_agent/dispatch/tests/runtime.rs:641 nvx-rs/src/guest/managed_agent/dispatch/tests/runtime.rs:642
modified test fn the_kernel_structures_have_their_uapi_sizes in guest::sys::entry::tests nvx-rs/src/guest/sys/entry/tests.rs:57 nvx-rs/src/guest/sys/entry/tests.rs:49
modified test fn a_thread_that_may_hold_the_permission_spawns_no_command in guest::sys::port::tests::transactions nvx-rs/src/guest/sys/port/tests.rs:157 nvx-rs/src/guest/sys/port/tests.rs:157
modified test fn a_real_time_signal_goes_through_a_pidfd_and_to_a_process_group in guest::sys::process::tests nvx-rs/src/guest/sys/process/tests.rs:387 nvx-rs/src/guest/sys/process/tests.rs:326
modified test fn a_write_takes_back_its_own_sigpipe_beside_one_pending_for_the_process in guest::sys::signal::tests nvx-rs/src/guest/sys/signal/tests.rs:112 nvx-rs/src/guest/sys/signal/tests.rs:112
modified test fn invalid_specs_are_refused_before_forking in guest::sys::spawn::tests nvx-rs/src/guest/sys/spawn/tests.rs:154 nvx-rs/src/guest/sys/spawn/tests.rs:151
modified test fn stream_sources_below_the_standard_streams_are_raised_and_kept_from_the_program in guest::sys::spawn::tests nvx-rs/src/guest/sys/spawn/tests.rs:173 nvx-rs/src/guest/sys/spawn/tests.rs:166
modified test fn the_launch_descriptors_are_close_on_exec in guest::sys::spawn::tests nvx-rs/src/guest/sys/spawn/tests.rs:377 nvx-rs/src/guest/sys/spawn/tests.rs:321
modified test def NvxRsTests.test_readme_gives_each_module_a_short_row_and_a_section in scripts/test_nvx_tools.py scripts/test_nvx_tools.py:2381 scripts/test_nvx_tools.py:2381
removed attributes the inner attributes of guest::cgroup::tests nvx-rs/src/guest/cgroup/tests.rs:1
removed attributes the inner attributes of guest::entry::tests nvx-rs/src/guest/entry/tests.rs:1
removed attributes the inner attributes of guest::exec::tests nvx-rs/src/guest/exec/tests.rs:1
removed attributes the inner attributes of guest::process::tests nvx-rs/src/guest/process/tests.rs:1
removed attributes the inner attributes of guest::root::bootstrap::tests nvx-rs/src/guest/root/bootstrap/tests.rs:1
removed attributes the inner attributes of guest::spawn::tests nvx-rs/src/guest/spawn/tests.rs:1
removed helper macro thread_local in guest::cgroup::tests nvx-rs/src/guest/cgroup/tests.rs:13
removed helper fn pause in guest::cgroup::tests nvx-rs/src/guest/cgroup/tests.rs:21
removed helper fn shell in guest::cgroup::tests nvx-rs/src/guest/cgroup/tests.rs:28
removed helper fn error in guest::cgroup::tests nvx-rs/src/guest/cgroup/tests.rs:40
removed helper fn hierarchy in guest::cgroup::tests nvx-rs/src/guest/cgroup/tests.rs:48
removed helper fn fake_execution in guest::cgroup::tests nvx-rs/src/guest/cgroup/tests.rs:68
removed helper struct RealWorkload in guest::cgroup::tests nvx-rs/src/guest/cgroup/tests.rs:476
removed helper impl RealWorkload in guest::cgroup::tests nvx-rs/src/guest/cgroup/tests.rs:478
removed helper fn new in guest::cgroup::tests, impl RealWorkload`` nvx-rs/src/guest/cgroup/tests.rs:484
removed helper impl Drop for RealWorkload in guest::cgroup::tests nvx-rs/src/guest/cgroup/tests.rs:519
removed helper fn drop in guest::cgroup::tests, impl Drop for RealWorkload`` nvx-rs/src/guest/cgroup/tests.rs:521
removed helper fn readable in guest::cgroup::tests nvx-rs/src/guest/cgroup/tests.rs:542
removed helper fn race in guest::cgroup::tests nvx-rs/src/guest/cgroup/tests.rs:655
removed helper fn finish in guest::cgroup::tests nvx-rs/src/guest/cgroup/tests.rs:680
removed helper fn entry in guest::entry::tests nvx-rs/src/guest/entry/tests.rs:26
removed helper fn root_with in guest::entry::tests nvx-rs/src/guest/entry/tests.rs:31
removed helper fn account_error in guest::entry::tests nvx-rs/src/guest/entry/tests.rs:45
removed helper struct RuntimeFixture in guest::entry::tests nvx-rs/src/guest/entry/tests.rs:413
removed helper impl RuntimeFixture in guest::entry::tests nvx-rs/src/guest/entry/tests.rs:424
removed helper fn new in guest::entry::tests, impl RuntimeFixture`` nvx-rs/src/guest/entry/tests.rs:425
removed helper fn entry in guest::entry::tests, impl RuntimeFixture`` nvx-rs/src/guest/entry/tests.rs:447
removed helper fn points in guest::entry::tests, impl RuntimeFixture`` nvx-rs/src/guest/entry/tests.rs:458
removed helper fn removals in guest::entry::tests, impl RuntimeFixture`` nvx-rs/src/guest/entry/tests.rs:463
removed helper fn simulated in guest::entry::tests nvx-rs/src/guest/entry/tests.rs:646
removed helper fn shell in guest::entry::tests nvx-rs/src/guest/entry/tests.rs:663

... and 218 more, which the job's summary lists.

Relocated unchanged: 0; added: 0. Compared the merge base 22163771b231 with 9830b1e190c6.

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

There are no active review issues for the removal of obsolete guest process and cgroup infrastructure.

No open issues 🎉

What changed in this PR

This PR advances NVX’s library-slimming workstream by removing obsolete guest process and cgroup infrastructure after its callers were deleted. It preserves nvx-init’s plain-process execution path and the retained root-switching mechanisms.

Changes:

  • Deletes the old guest execution, spawn, process, entry, cgroup, and bootstrap APIs and their unused OS support.
  • Retires obsolete tests and adapts retained tests to use the private OS helpers directly.
  • Updates documentation, the Linux public API snapshot, and test inventories to reflect the removals.
File Description
scripts/​test-layout-allowlist.json Removes obsolete test hooks and tightens spawn allowances.
nvx-rs/​src/​lib.rs Removes deleted modules from the crate documentation.
nvx-rs/​src/​guest/​view.rs Removes the deleted entry import and documentation reference.
nvx-rs/​src/​guest/​time/​api.rs Updates spawn-safety documentation without the removed API.
nvx-rs/​src/​guest/​sys/​tests.rs Adjusts test-helper exports after deletions.
nvx-rs/​src/​guest/​sys/​spawn/​tests.rs Retires tests and cases for removed child stages.
nvx-rs/​src/​guest/​sys/​signal/​tests.rs Uses the retained wait helper for child status checks.
nvx-rs/​src/​guest/​sys/​process/​tests.rs Removes obsolete process helpers and lookup assertions.
nvx-rs/​src/​guest/​sys/​process.rs Deletes unused named-wait and process-group lookup helpers.
nvx-rs/​src/​guest/​sys/​port/​tests.rs Tests spawn refusal through the private child builder.
nvx-rs/​src/​guest/​sys/​mod.rs Removes obsolete exports and updates OS-layer documentation.
nvx-rs/​src/​guest/​sys/​fd/​tests.rs Deletes the unused descriptor-limit helper.
nvx-rs/​src/​guest/​sys/​fd.rs Removes unused per-execution descriptor and socket helpers.
nvx-rs/​src/​guest/​sys/​entry/​tests.rs Removes entry simulation and deleted structure-size checks.
nvx-rs/​src/​guest/​spawn.rs Deletes the old public spawning API.
nvx-rs/​src/​guest/​root/​tests.rs Retires bootstrap tests and fixtures.
nvx-rs/​src/​guest/​root/​kernel/​tests.rs Removes simulated cgroup writes and process moves.
nvx-rs/​src/​guest/​root/​kernel.rs Removes bootstrap-only control-file writes.
nvx-rs/​src/​guest/​root/​bootstrap/​tests.rs Deletes bootstrap parsing tests.
nvx-rs/​src/​guest/​root/​bootstrap.rs Deletes cgroup bootstrap and resource configuration.
nvx-rs/​src/​guest/​root.rs Removes bootstrap APIs, errors, and an unused bind helper.
nvx-rs/​src/​guest/​process/​tests.rs Deletes tests for the removed child-status API.
nvx-rs/​src/​guest/​process.rs Deletes the public child-status collector.
nvx-rs/​src/​guest/​mod.rs Removes obsolete module declarations and descriptions.
nvx-rs/​src/​guest/​mappings.rs Removes an unused internal bind re-export.
nvx-rs/​src/​guest/​managed_agent/​dispatch/​tests/​runtime.rs Routes test signals through the test-helper export.
nvx-rs/​src/​guest/​init/​tests/​exec.rs Replaces deleted wait and group-lookup helpers.
nvx-rs/​src/​guest/​cgroup.rs Deletes execution cgroup management.
nvx-rs/​src/​guest/​activation.rs Removes a rustdoc reference to the deleted entry check.
nvx-rs/​src/​guest/​account.rs Makes formerly re-exported account items crate-private.
nvx-rs/​README.md Removes obsolete module sections and bootstrap descriptions.
nvx-rs/​public-api/​linux.txt Records removal of guest process and bootstrap APIs.
doc/​guest-agent-guidelines.md Removes the transitional description of old process modules.
doc/​acceptance-case-matrix.md Records retired examples and updates retained example locations.

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 deletion spans guest fork/exec, credential boundaries, and the guest kernel, warranting maintainer confirmation of workload launch, boot, and restore validation while exact-head CI remains unrun.

No open issues 🎉

Review effort: Balanced

Pedro Henrique Penna (ppenna) added a commit that referenced this pull request Nov 12, 2026
SL7.8b (#1534) deleted the old layered init, nvx-init-agent, with the
managed agent's sandbox mode, and SL7.8c (#1536) deleted the Alpine
one-shot container helpers. The build guide still said that the Alpine
initramfs includes "the sandbox PID-1 bootstrap and its container
namespace scripts", that the kernel checks cover what "the sandbox
bootstrap" needs, and that the APK manifest records the tools "used by
the bootstrap". The Ubuntu guest still named "the Alpine control
initramfs and its init agent" as the boot supervisor of the distro
layer, and the cgroups and namespaces "that the sandbox uses". The
project structure still credited the common scripts with shutdown and
the time ABI, which the Rust guest binaries took over.

Say instead what the code does now:

- the Alpine initramfs is the one that nvx-rs sandbox boots, and with
  nvx_sandbox=1 the common /init hands PID 1 to nvx-init (exec
  /sbin/nvx-init in guest/common/init), which initializes the
  sandbox's layered root and serves its managed control session;
- the APK manifest records every package of the image, among them the
  five that AlpineBuildConstants.PACKAGES adds to the minirootfs;
- nvx-init supervises the Ubuntu distro layer, and the kernel provides
  the memory and process-count cgroups and the PID, mount, UTS and
  network namespaces for the guest's programs, without claiming that
  the sandbox uses them;
- the common scripts mount the host share (nvx-hostmount), prepare the
  guest for a snapshot and repair its restores (nvx-snapshot), and
  probe for the tests and benchmarks; the Rust binaries provide PID 1,
  the time ABI's guest side, shutdown and the rest.

The kernel inventory and its checks table keep their text: SL6.11b
(#1542) rewrites them.

Part of #1131 (SL6.10e).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The old layered init, the managed agent's sandbox mode and the one-shot
container helpers are gone, and with them the last users of the guest
process modules: guest::exec ran a layered root's executions, which
guest::spawn started, guest::entry entered into their namespaces, view
and identity, guest::cgroup placed and guest::process collected, and
guest::root's bootstrap moved the init's processes into the cgroups
that held them. nvx-init runs its workloads as plain processes through
sys::spawn, without per-execution containment.

Delete guest::{exec, spawn, process, cgroup, entry}, with their
submodules and tests, and guest::root::{bootstrap, Bootstrap,
BootstrapStep, Resources}, with root::Error::Bootstrap. Delete the OS
support that only they used:

- sys::entry's per-execution entry: EntryChild, its clone3 start in new
  mount, PID and UTS namespaces, its view of /proc, /sys and /dev, with
  the procfs entries that it masked or made read-only, its move into
  the root, its umask, its working directory's resolution beneath the
  root, and the CloneArgs and OpenHow structures. sys::entry keeps a
  layered root's runtime file systems and the workload identity, which
  nvx-init and Root use.
- The spawn child's per-execution stages, with their ChildSpec setters:
  the root, the working directory's credentials check, inherited
  descriptors, the cgroup placement, the session, the barrier and the
  entry. The child keeps the path of nvx-init's workloads. LaunchStage,
  whose numbers the child's launch report carries and which
  guest::spawn held, moves into sys::spawn as a crate-private enum of
  the stages that the child still takes, each with its number.
- The waits and signals that only guest::exec used: process_group_of,
  WaitTarget and wait_named, and the sys re-exports of
  signal_process_group and signal_through_pidfd, which sys::process
  keeps for kill_process_group and kill_through_pidfd.
- The cgroup writes: root::kernel's Kernel::write, which only the
  bootstrap called.
- fd's shut_down_sending, take_pipe_end, open_at and
  create_socket_pair, which only guest::exec's pipes and sockets used.
  fd's per-execution memfd and seals already left with #1310.

Root::switch keeps its move of the root and its change of root, and
the rooted open keeps its EAGAIN retry. What the warning-denied builds
then find unused goes too: root::bind_runtime_file, whose retained
variant bind_runtime_file_retained takes its rustdoc, and
guest::mappings' bind_with re-export. guest::account's items, which
only guest::entry re-exported, become crate-private.

Tests:

- The deleted modules' 125 tests retire: 44 of guest::exec, among them
  a_stalled_sink_stalls_only_its_own_execution_and_loses_nothing, 22
  of guest::entry, 22 of guest::spawn, 17 of guest::cgroup, 9 of
  guest::process and 2 of guest::root::bootstrap; guest::root's 6
  bootstrap tests; and sys::spawn's
  a_child_enters_its_root_or_reports_why_not,
  the_check_s_credentials_keep_the_parent_s_supplementary_groups and
  an_entry_leads_a_session_and_keeps_its_barrier_from_the_program,
  whose stages go. So do the deleted modules' 8 doc tests, and the
  test hooks of their code and of the deleted child stages.
- sys::spawn's invalid_specs_are_refused_before_forking,
  stream_sources_below_the_standard_streams_are_raised_and_kept_from_the_program
  and the_launch_descriptors_are_close_on_exec lose their cases of the
  credentials check, inherited descriptors and cgroup placement.
- sys::entry's the_kernel_structures_have_their_uapi_sizes loses
  CloneArgs and OpenHow, and its Simulation helper goes.
- Tests that used a deleted helper use the kept one:
  a_thread_that_may_hold_the_permission_spawns_no_command spawns
  through sys::spawn;
  a_write_takes_back_its_own_sigpipe_beside_one_pending_for_the_process
  and
  a_stolen_or_auto_reaped_status_is_reported_once_and_never_reclassified_by_an_ending
  wait with sys::wait;
  privileged_capture_sweep_kills_setsid_escapees_and_spares_both_helpers
  reads process groups with getpgid; and the managed agent's runtime
  tests signal through sys::tests' signal_through_pidfd.
  a_real_time_signal_goes_through_a_pidfd_and_to_a_process_group drops
  its check of process_group_of.
- test_nvx_tools.py's
  test_readme_gives_each_module_a_short_row_and_a_section expects more
  than 30 rows in the nvx README's module table rather than 40, since
  the table keeps 39 of its 44; the floor only shows that the test
  reads the module table.
- The helpers that only deleted tests used go: root::kernel's fake
  writes and process moves, root's bootstrap fixtures,
  sys::process's untraced and traced children, sys::fd's
  set_descriptor_limit and sys::spawn's CAP_SYS_CHROOT.

Docs: the rustdoc of guest, guest::root, sys and the kept OS modules,
the crate's guest summary, the nvx README, whose module table and
sections drop the five modules, and the guest-agent guidelines no
longer describe the deleted modules or the root's bootstrap. The case
matrix retires the deleted doc tests and names the kept ones by the
lines to which they move. The test-layout allowlist and the Linux
public API snapshot drop the deleted modules.

Part of #1123 (SL6.11b).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
#1123's follow-up K1. With the old layered init, the one-shot container
helpers, guest::entry and the runtime adapter gone, the kernel feature
inventory named consumers and validators that no longer exist, and kept
CONFIG_MAGIC_SYSRQ for the per-execution entry, which made
/proc/sysrq-trigger read-only for user ID 0 and is gone too.

Nothing that stays uses magic SysRq: no NVX code reads or writes
/proc/sysrq-trigger or kernel.sysrq, and nvx-init and the managed agent
refuse user ID 0 and drop every capability, so their workloads could not
write the trigger anyway. It had a side effect, though: the hvc console
took ^O on the kernel console, where an nvx-rs run shell reads, as a
SysRq prefix, so ^O never reached bash, vim or nano there, and ^O c, b
or o crashed, rebooted or powered off the guest. The diagnostics
feature drops it, and kernel/config-microvm and its derived record,
regenerated with nvx.py kernel-config in the Docker build's image, lose
CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE and CONFIG_MAGIC_SYSRQ_SERIAL with
it: the configuration sets 767 symbols, 174 of them inventory settings
and 593 derived.

The features name what uses them now:

- processors and memory-hotplug: nvx-init's restore repair, in
  nvx::guest::snapshot::capture, which replaced the clone repair, and
  the snapshot helper. The restore-processors,
  platform-restore-processors and restore-memory scenarios validate
  them in place of the adapter's clone tests.
- virtio-console, block-storage, sandbox-filesystems and
  host-filesystem: nvx-init, nvx::guest::root and
  nvx::guest::activation, in place of nvx-init-agent and
  nvx::guest::clone. The sandbox-gpt-layer and snapshot-tiers scenarios
  validate GPT layers in place of the adapter's GPT tests.
- sandbox-isolation keeps its settings, which no NVX component uses
  since SL7.8b, SL7.8c and SL6.11b: its rationale says that only root
  programs in a guest, such as an nvx-rs run shell, can use them, and
  that NAMESPACES also stays for NET_NS. build-kernel's sandbox group
  validates it. Whether they stay is #1123's follow-up K2.
- linux-abi and diagnostics no longer name the runtime adapter; CI's
  logs are diagnostics' only consumer, and build-kernel's configuration
  checks validate it.

doc/build.md lists magic SysRq among what the inventory removed, drops
serial SysRq, which no longer appears, from the platform options, and
updates the configuration's counts, the cgroup row and the Sandbox
group's purpose, which described the old sandbox.

Part of #1123 (SL6.11b, follow-up K1).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

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 were identified for the removal of obsolete guest process and cgroup infrastructure.

No open issues 🎉

Review effort: Balanced

@ppenna
Pedro Henrique Penna (ppenna) merged commit c1198c7 into feature/nvx-refactor Nov 12, 2026
126 of 128 checks passed
@ppenna
Pedro Henrique Penna (ppenna) deleted the agents/slim-sl6-11b-process-modules branch November 12, 2026 17:43
Pedro Henrique Penna (ppenna) added a commit that referenced this pull request Nov 12, 2026
The README still introduced the crate as the NVX mechanics and their
supervision, laid out the split platform, store and supervisor modules,
listed exec among the modules without default features, kept an
uncompiled copy of lib.rs's example, and gave modules that leave the
public API, or leave the crate, rows and long sections of their own.

It now opens with the library's mechanisms and what it leaves to its
users, links the library guide and the guest-agent guidelines, and
names NVX's programs, with NVXC and the code that only they use, as
private users of the library, whose binaries call hidden mains. Its
features come first, and its layout and module table describe the
final public modules: guest::{exec, spawn, process, cgroup, entry} are
gone; guest::{root, view, gpt}, the mapper and the application of an
activation are nvx-init's space, private to the crate, which a short
section under the guest binaries describes and the guidelines detail;
host::platform is private and host::report a module of its own; and
nvx::protocol::maps and nvx::Error gain rows. The table keeps one line
of at most 200 characters for each of its 36 modules, above the floor
of 30 that #1542 set. The module sections keep each module's contracts
and leave the rest to its rustdoc. NVXC is private and speaks version 2
alone, as SL4.4c and SL4.4d make it; library callers tell errors apart
by their kinds alone; and the Example gives way to the guide, whose
links reach compiled code.

The CLI's sections, the table of error codes, the binaries' table and
the tests stay as they were but for one stale sentence on an API
change: other documents link them, SL6.10d owns the CLI reference, and
the slices that change them keep them current. The table of error codes
keeps guest-features-missing, which a unit test of the base reads, until
SL4.4d removes it.

Docs only: 0 core lines, no counted files.

Part of #1130 (SL6.10a).

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
SL7.8b (#1534) deleted the old layered init, nvx-init-agent, with the
managed agent's sandbox mode, and SL7.8c (#1536) deleted the Alpine
one-shot container helpers. The build guide still said that the Alpine
initramfs includes "the sandbox PID-1 bootstrap and its container
namespace scripts", that the kernel checks cover what "the sandbox
bootstrap" needs, and that the APK manifest records the tools "used by
the bootstrap". The Ubuntu guest still named "the Alpine control
initramfs and its init agent" as the boot supervisor of the distro
layer, and the cgroups and namespaces "that the sandbox uses". The
project structure still credited the common scripts with shutdown and
the time ABI, which the Rust guest binaries took over.

Say instead what the code does now:

- the Alpine initramfs is the one that nvx-rs sandbox boots, and with
  nvx_sandbox=1 the common /init hands PID 1 to nvx-init (exec
  /sbin/nvx-init in guest/common/init), which initializes the
  sandbox's layered root and serves its managed control session;
- the APK manifest records every package of the image, among them the
  five that AlpineBuildConstants.PACKAGES adds to the minirootfs;
- nvx-init supervises the Ubuntu distro layer, and the kernel provides
  the memory and process-count cgroups and the PID, mount, UTS and
  network namespaces for the guest's programs, without claiming that
  the sandbox uses them;
- the common scripts mount the host share (nvx-hostmount), prepare the
  guest for a snapshot and repair its restores (nvx-snapshot), and
  probe for the tests and benchmarks; the Rust binaries provide PID 1,
  the time ABI's guest side, shutdown and the rest.

The kernel inventory and its checks table keep the text that SL6.11b
(#1542) gave them.

Part of #1131 (SL6.10e).

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
SL7.8b (#1534) deleted the old layered init, nvx-init-agent, with the
managed agent's sandbox mode, and SL7.8c (#1536) deleted the Alpine
one-shot container helpers. The build guide still said that the Alpine
initramfs includes "the sandbox PID-1 bootstrap and its container
namespace scripts", that the kernel checks cover what "the sandbox
bootstrap" needs, and that the APK manifest records the tools "used by
the bootstrap". The Ubuntu guest still named "the Alpine control
initramfs and its init agent" as the boot supervisor of the distro
layer, and the cgroups and namespaces "that the sandbox uses". The
project structure still credited the common scripts with shutdown and
the time ABI, which the Rust guest binaries took over.

Say instead what the code does now:

- the Alpine initramfs is the one that nvx-rs sandbox boots, and with
  nvx_sandbox=1 the common /init hands PID 1 to nvx-init (exec
  /sbin/nvx-init in guest/common/init), which initializes the
  sandbox's layered root and serves its managed control session;
- the APK manifest records every package of the image, among them the
  five that AlpineBuildConstants.PACKAGES adds to the minirootfs;
- nvx-init supervises the Ubuntu distro layer, and the kernel provides
  the memory and process-count cgroups and the PID, mount, UTS and
  network namespaces for the guest's programs, without claiming that
  the sandbox uses them;
- the common scripts mount the host share (nvx-hostmount), prepare the
  guest for a snapshot and repair its restores (nvx-snapshot), and
  probe for the tests and benchmarks; the Rust binaries provide PID 1,
  the time ABI's guest side, shutdown and the rest.

The kernel inventory and its checks table keep the text that SL6.11b
(#1542) gave them.

Part of #1131 (SL6.10e).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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