Skip to content

nvx-rs: skip journal loading for GPT lower layers - #807

Merged
Enrique Saurez (esaurez) merged 1 commit into
devfrom
esaurez/a3-gpt-noload-20261023
Oct 23, 2026
Merged

Enrique Saurez (esaurez) merged 1 commit into
devfrom
esaurez/a3-gpt-noload-20261023

Conversation

@esaurez

Copy link
Copy Markdown
Contributor

Part of #621. Refs #622 and #535. Follow-up to #776.

Mount GPT ext4 lower layers with noload,errors=remount-ro, retaining ro,nosuid,nodev. A read-only mount can load and scan an internal journal even when the file system's needs_recovery bit is clear. Suppressing journal loading avoids that path instead of adding a second journal parser to the guest library.

This deliberately changes #776's policy of mounting without noload. The assembly still rejects needs_recovery before any mount, so journal suppression does not admit a layer that explicitly requires recovery. EROFS layers, writable scratches, overlay modes, and teardown order are unchanged.

The adapter's VM scenarios now assert journal suppression for every GPT lower. Two new cases cover an internal cyclic journal: with needs_recovery clear, assembly, reads, copy-up, and teardown complete; with it set, the assembly reports its typed recovery failure before mounting. The same cyclic-journal scenario against the exact base's guest agent timed out during assembly after 60 seconds on WHP; the fixed agent passes.

Validation

  • Windows and Linux: python scripts/nvx.py verify; nvx-rs Clippy (all targets/features and lib/no-default-features), tests (all features, defaults, and lib/no-default-features), no-default-features build, rustdoc with warnings denied, and Rust 1.89 checks. Linux totals: 1,249 all-features tests, 597 default tests, and 184 no-default-features tests. The focused root suite passes all 59 tests.
  • cargo fmt --all --check for nvx-rs, aci_edge_sandboxes, and tests/runtime-adapter; python scripts/check_markdown_links.py. The adapter's protocol-only and host configurations pass Clippy, build, tests, and Rust 1.89 checks on Windows and Linux; its static musl guest configuration passes the same checks on Linux.
  • Linux: the remaining check-nvx-rs gates (bundled-artifact fixture, macOS cross-check, check-guest-binaries, build-guest-binaries, and test-guest-binaries, 34 passed), and all check-aci-edge-sandboxes non-hypervisor gates, including agent bundling, docs, MSRV, and macOS.
  • Real VMs on WHP and MSHV: cargo test --locked --features host --test vm_layered --test vm_restart -- --ignored passes all 21 layered scenarios and 2 restart tests, including the cyclic journal and recovery-required cases.
  • NVX's six unchanged scenarios pass on WHP and MSHV: python scripts/nvx.py test-microvm --backend <whp|mshv> --processors 1, selecting managed-exec-config, sandbox-lifecycle, sandbox-blocks, scratch-snapshot, snapshot-tiers, and managed-lifecycle, with the branch's freshly built Alpine initramfs.
  • All nine stripped guest binaries are byte-identical to the base. The Alpine initramfs is also byte-identical: 8,223,168 bytes compressed, 19,707,392 uncompressed.

The runtime artifacts came from v0.1.0-dev.843c091bb835, with the pinned OpenVMM 79a501b63fcd2f150e94928d0ceba79cd2fe96c4; guest agents were rebuilt from the tested sources. MSHV ran as root with the development-only --cpu-profile host override, since its host cannot present the built-in Genoa profile. KVM and the complete backend matrix are left to CI.

Mount GPT lower layers with noload as well as errors=remount-ro.
Without noload, ext4 can scan a nonempty journal even when its
needs_recovery bit is clear; a cyclic journal can hold assembly there
indefinitely. Keep rejecting the recovery bit before any mount, rather
than allowing noload to admit a recovery-required layer.

Add adapter VM scenarios with a cyclic internal journal, with and
without the recovery bit. Check that the former assembles, serves reads
and copy-up, and tears down, while the latter fails before mounting.
Assert journal suppression in every GPT scenario and document the
deliberate change from #776's journal-loading policy. EROFS lowers and
writable scratches retain their existing mount options.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 30bab0d7-7c3e-4120-9add-6c9cc1dc9e7e
Copilot AI balanced review requested due to automatic review settings October 23, 2026 15:03

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

The focused mount-option change preserves recovery rejection and has targeted unit and VM regression coverage, with no identified blocking issues.

No open issues 🎉

What changed in this PR

This PR updates the guest library’s GPT lower-layer mount policy to prevent hangs while scanning corrupt journals. It preserves rejection of layers that require recovery.

Changes:

  • Adds noload while retaining errors=remount-ro and read-only mount protections.
  • Adds VM regression scenarios for cyclic journals with and without required recovery.
  • Updates unit expectations and documentation; EROFS layers and writable scratches remain unchanged.
File Description
tests/​runtime-adapter/​tests/​vm_layered.rs Adds cyclic-journal scenarios and asserts journal suppression.
tests/​runtime-adapter/​README.md Documents the updated mount policy and VM scenarios.
nvx-rs/​src/​guest/​root/​tests.rs Updates expected mount options and recovery-check commentary.
nvx-rs/​src/​guest/​root.rs Suppresses GPT lower-layer journal loading and documents recovery safeguards.
nvx-rs/​README.md Explains the journal policy and its scope.

Review effort: Balanced

@esaurez
Enrique Saurez (esaurez) marked this pull request as ready for review October 23, 2026 15:06
@esaurez
Enrique Saurez (esaurez) merged commit 978b6ed into dev Oct 23, 2026
78 checks passed
@esaurez
Enrique Saurez (esaurez) deleted the esaurez/a3-gpt-noload-20261023 branch October 23, 2026 15:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants