Repository navigation
fix(harness): let boot-args configure logging - #206
Merged
Merged
Conversation
`EnvFilter::try_from_default_env` reads RUST_LOG once, when the subscriber is
built — and that happened before `bootenv::bootstrap()`, which is what
publishes boot-args into the environment. So a `lantern.env.RUST_LOG=...` was
applied long after the filter had been fixed, and boot-args could not configure
logging at all.
That is not academic: it is why diagnosing the guest's TLS failure meant editing
the harness's compiled-in filter default and rebuilding the whole image, twice.
A microVM has no shell and no other channel — boot-args are the only way in.
`preinit_log_filter()` now resolves that one variable first, at the top of main,
silently (there is nothing to log to yet). Everything else stays in
`bootstrap()` after the subscriber exists, so the rest of the bridge's work
remains visible. An explicit RUST_LOG in the environment still wins.
Moving procfs mounting earlier would have cost the "mounted /proc" debug line,
since it now happens before tracing. `ensure_procfs` records the outcome and
`bootstrap` reports it once the subscriber is up, so nothing is lost.
Verified on real KVM with a stock binary (no compiled-in filter override):
spawning with `env: {"RUST_LOG": "info,lantern_harness=debug,rustls=trace"}`
produced rustls trace output in the guest log, and "bootenv: mounted /proc" was
still reported. 155 harness tests pass (2 new for the pure filter extraction),
clippy and rustfmt clean.
Contributor
🔎 Codex cross-audit (agent:audit)Blocking
No other PR-introduced correctness or security issues stood out in this narrow diff. I did not run tests; this was a read-only diff audit. |
Contributor
🔷 Gemini cross-audit (agent:audit-gemini)Audit Report:
|
Flagged by both PR auditors on #206, and they were right. `#[tokio::main]` builds the runtime and only THEN runs the async body, so its worker threads are already alive by the time the body's first statement executes. Every `std::env::set_var` in `bootenv` therefore ran with other threads live — which is unsound, and exactly why `set_var` is `unsafe` in edition 2024. The five SAFETY comments asserting "before any thread is spawned" were not just imprecise, they were false, and had been since the boot-args bridge landed. `preinit_log_filter` inherited the same bug rather than introducing it. `main` is now a plain fn: it does the environment work (log filter, then `bootstrap`) while the process is genuinely single-threaded, then builds the runtime and blocks on `run()`. The SAFETY comments now name the real invariant — before the runtime is built — rather than a thread claim that was easy to break silently, and `main` carries the contract so re-adding the macro is an obvious mistake instead of an invisible one. No behavior change: `new_multi_thread().enable_all()` is what the macro was already doing. Verified on real KVM, A/B on a clean host, same manager binary and image build: - pre-change harness -> 5/5 assertions - post-change harness -> 5/5 assertions backend available · guest live · secret vended over mTLS · tool invoked in-guest · all assertions passed The guest log still shows the boot-args filter taking effect and the deferred "bootenv: mounted /proc" report, so this PR's own feature is intact. 155 harness tests pass, clippy and rustfmt clean.
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.
Item #3 from the remaining list — the last small one.
The problem
EnvFilter::try_from_default_envreadsRUST_LOGonce, when the subscriber is built — and that happened beforebootenv::bootstrap(), which is what publishes boot-args into the environment. So alantern.env.RUST_LOG=...was applied long after the filter had been fixed, and boot-args could not configure logging at all.That isn't academic. It's why diagnosing the guest's TLS failure meant editing the harness's compiled-in filter default and rebuilding the entire image — twice. A microVM has no shell and no other channel; boot-args are the only way in.
The fix
preinit_log_filter()resolves that one variable first, at the top ofmain, silently — there's nothing to log to yet. Everything else stays inbootstrap()after the subscriber exists, so the rest of the bridge's work remains visible in the log. An explicitRUST_LOGin the environment still wins.Observability preserved: moving procfs mounting earlier would have cost the
mounted /procdebug line, since it now happens before tracing.ensure_procfsrecords the outcome andbootstrapreports it once the subscriber is up.Verified on real KVM, stock binary
No compiled-in filter override in the image. Spawning with:
env: { "RUST_LOG": "info,lantern_harness=debug,rustls=trace" }produced rustls trace output in the guest log (8 lines) — previously impossible — and
bootenv: mounted /procwas still reported, confirming nothing was lost to the reordering.155 harness tests pass (2 new, covering the pure filter extraction so the selection is testable without
/procor env mutation), clippy and rustfmt clean.