Skip to content

Main's nightly: the tarball in a TempDir, a join that keeps its answer, three judges that read the whole log - #534

Merged
Japabu merged 9 commits into
mainfrom
wt/toyos-nightlyfix
Sep 27, 2026
Merged

Japabu merged 9 commits into
mainfrom
wt/toyos-nightlyfix

Conversation

@Japabu

@Japabu Japabu commented Sep 26, 2026 •

Copy link
Copy Markdown
Collaborator

Main's nightly is red. This branch fixes five of its reds where each one lives and files the older ones it does not fix. It is merged with origin/main at 5e446e5 (#524).

1. Every guest, tcg and audio lane: the toolchain tarball left in $TMPDIR

2. fpu_isolation: thread_join answered NotFound

3. blockd_survives_its_death: the reissue judge demanded an order the client never promised

  • Cause. Storage stage 3, steps 1–4: toyos-blockring, SYS_DEVICE_DMA_MAP, blockd and partition sessions #525 (7345e3f). The trace judge required the blockd after a kill to rewrite the unflushed writes in the order the device first saw them.
    • The client reissues in first-acknowledged order, and requests in flight together are unordered (toyos-blockring/src/client.rs).
    • Run 36273557690 wrote [282600, 281592] and reissued [281592, 282600].
  • Fix. The judge requires the same writes as a multiset, and the original order among the writes that overlap any one of them. Overlapping writes are never in flight together.
  • Negative control. The client's reissue after a loss compiled out (the mutate-no-reissue-after-loss body), applied as a checked patch and restored. EXIT=1: the blockd after it wrote [281592, 280584] first.
  • Oracle: QEMU's own NVMe trace.
  • Green after: EXIT=0 locally, and green on run 36280285913, guest (2).

4. partition_claim_departure: kernel records that arrive after the end marker

5. exit_wait_storm: the parent's spawn record landed before the start marker

  • Cause. The same two console paths.
    • The harness moves only the lines from the last matching spawn: record in before into the window.
    • When the parent and its first children were spawned before the marker arrived, the judge called a child the parent. It then counted the real parent's exit (code 0) as a child's, and read a child's syscall profile as the parent's.
    • A probe, applied as a checked patch and restored, showed pids 7 (the parent), 8 and 9 in before and the rest in the window.
  • Fix. The judge reads before and the window together, takes the lowest pid as the parent (pids are never reused), and counts as children only the pids above it.
  • Red before: red on run 36278449733 and on run 36280285913, guest (1), red alone as well. Locally, 3 of 4 runs.
  • Green after: 8 of 8, EXIT=0 each. Green at 3f46a01, flaky at e8d7c9c, so it arrived with Program output belongs to logd: each program's pipe, the log served from the boot's first line, and the T14 found by its name #492's two-path console; not bisected.

Gates

  • cargo run -- --ci host: 45 steps, all green, EXIT=0, on the merged tree and again at the head 67a430c.
  • cargo test --lib -- release:: every_host_scratch_is_the_guard left_behind: 7 passed, EXIT=0.
  • fpu_isolation, blockd_survives_its_death and partition_claim_departure each EXIT=0 on the merged tree.
  • -- --nightly thread: 2 passed, EXIT=0.
  • Fast tier (cargo test --test toyos-build) on the pre-merge tree: EXIT=1, 397 passed, 1 failed. The failure is lan_mdns_answer on path must be shorter than SUN_LEN, the macOS dev-host defect filed twice under issues/build/ (a-lane-s-tap-socket-path-…). It is not a Linux nightly red.

Nightly on this branch

Run 36285169430 at 67a430c, the head.

  • Green: host, build, portability-linux, portability-macos, tcg, audio (1), audio (2), guest (2), (4), (6), (8), (11).
  • portability-windows: the declared continue-on-error frontier.
  • Every guest, tcg and audio lane says nothing left in $TMPDIR.
  • fpu_isolation, blockd_survives_its_death, partition_claim_departure and exit_wait_storm are all green.

Run 36280285913 at ccb6b4e, before item 5. Same picture, with exit_wait_storm red in guest (1).

Still red on the head's run, none of them from the named suspects. Each is red on main's run 36278449733 or earlier, or flaky across these runs, and cargo run -- --known-red answers NO for every one:

lane red status
guest (1) quiesce_leaves_the_volume_whole red alone on main's run and on this head's run, green on the first branch run and locally (EXIT=0)
guest (3) quiesce_wakes_on_the_last_exit green on main's run, flaky on the branch runs, green locally; issues/build/quiesce-wakes-on-the-last-exit-lost-its-serial-ready-beside-other-guests.md
guest (5) soundd_log_stall timed out at 392 s; green on main's run and locally (254 s, EXIT=0)
guest (7) usb_transport_break red since #506 (265a0fc). Its usb-port-gone disk makes rootfs::hold_source panic, shown by removing that param as a checked patch. Filed as issues/boot-media/a-disk-whose-port-went-away-panics-the-boot-at-roots-hold.md
guest (7) metal_job_reboot red at e8d7c9c too; issues/build/metal-job-reboot-drained-no-kernel-output-beside-other-guests.md
guest (9) screen_diag_boot red since a landing between 3f46a01 and e8d7c9c; filed as issues/boot-media/screen-diag-boot-leaves-no-i8042-line-on-the-panel.md
guest (10) log_flush_retry red at 3f46a01 and e8d7c9c too; issues/filesystem/log-flush-retry-deadman-arm.md
guest (12) home_budget_refusal_retried red at e8d7c9c too; filed as issues/filesystem/home-budget-refusal-retried-is-red-on-every-nightly.md

On the first branch run, audio (2) reported a gate A wake-lateness regression, and on main's run audio (1) an instrument-broken capture. Both audio lanes are green on the head's run.

Unsure

  • The klogd/logd race in items 4 and 5 applies to any judge that reads kernel records only between the markers. Only these two judges are changed. run_test_paced's move-from-the-last-spawn is left as it is.
  • The quiesce pair, metal_job_reboot and soundd_log_stall alternate between red and green across three runs. Their rates are not measured here.

🤖 Generated with Claude Code

https://claude.ai/code/session_014iqcj4jDKpaiDX8B7CMvmK

Japabu and others added 6 commits September 27, 2026 01:11
#529 (e48604c) made every guest, tcg and audio lane red on anything left
in its private $TMPDIR. `release::install` downloaded the toolchain tarball
to `$TMPDIR/toyos-toolchain.tar.zst` and never removed it, so every such
lane on the nightly (run 36273557690) failed its last step naming
`toyos-toolchain.tar.zst`.

Both release paths now stage in a `toyos_tmpdir::TempDir`, removed on
every way out: the install's tarball, and the publish's TOOLCHAIN,
notes.md and tarball. `src/release.rs` leaves `TEMP_DIR_ALLOWED`, which
closes issues/build/the-release-path-stages-in-tmpdir-outside-the-scratch-guard.md.

This file is one of the trees the toolchain tag hashes, so the tag moves
and the nightly's `build` job publishes the new one.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014iqcj4jDKpaiDX8B7CMvmK
`fpu_isolation` has been red since #513 (46056bf, "One way to wait"):
every `check` child's `thread_join` on its probe thread answered NotFound.

`sys_thread_join`'s wait predicate was `wait_thread_zombie`, which
collects: it takes the zombie out of the table. Before #513,
`completion::wait_until` returned on the `Gone(Closed)` that
`thread_exit` posted without running the predicate again, so the loop's
own collect found the zombie. #513's `watch::wait_until` runs the
predicate after every wake; it collected the zombie and returned, and the
loop's next collect found no such thread. Every joiner that parked before
its thread exited got NotFound. std's and libc's joins drop the answer,
so only `fpu_isolation`, which asserts it, went red.

The predicate now keeps the first answer it collects, and the syscall
returns that answer rather than asking again.

Red before, at fd62f56: `cargo test --test toyos-build -- --nightly
fpu_isolation` EXIT=1, `thread_join failed, left: 18446744073709551614`.
Green after: EXIT=0.

Files issues/kernel/std-and-libc-drop-the-answer-thread-join-gives.md.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014iqcj4jDKpaiDX8B7CMvmK
`blockd_survives_its_death` (from #525, 7345e3f) read QEMU's trace and
required the blockd after a kill to write the acknowledged, unflushed
writes in the order the device first saw them. The client promises less:
`toyos-blockring`'s client reissues in first-acknowledged order, and
requests in flight together are unordered. Two writes that do not overlap
can go out as A then B and be acknowledged B then A.

On the nightly of PR #524 (run 36273557690, guest (2)) the first lifetime
wrote sectors [282600, 281592] and the reissue wrote [281592, 282600]. A
local run of the same test wrote [282600, 281592] both times. The same
writes, reordered only between writes that do not overlap.

The judge now requires the same writes as a multiset. Among the writes
that overlap any one of them, it requires the order they first went out
in. Overlapping writes are never in flight together, so for them the
device's order is the acknowledged order.

Negative control: the client with `lost()`'s reissue compiled out (the
`mutate-no-reissue-after-loss` body), applied as a checked patch and
restored. EXIT=1: "the blockd after it wrote [281592, 280584] first".
Green after: `cargo test --test toyos-build -- --nightly
blockd_survives_its_death` EXIT=0. Before the change it was green alone
6/6 locally, so its red is the CI run's ordering, recorded above.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014iqcj4jDKpaiDX8B7CMvmK
`partition_claim_departure` went red on the nightly of PR #524 (run
36273557690, guest (12)) with `the kernel never said "usb-storage: disk 0
came back on port 3 slot "`. The guest's own lines were all there,
including the flush refusal that follows that record. Beside other
guests it also reds as `silent: 0 flushes were told of the loss, not 1`
(issues/boot-media/partition-claim-departure-told-no-flush-beside-other-guests.md,
filed at #511).

The cause is two console paths. The runner's `===TEST_END===` reaches the
console through `logd`, and the kernel's records through `klogd`
(tests/common/qemu.rs already says so for the start marker). A record the
kernel made before the test ended can arrive after the marker. The window
closes on the marker, so `guest_verdict` judged a kernel log that did not
yet hold it. It is not #525's; the test and its judge predate it.

Reproduced on this host at fd62f56, with 18 CPU spinners on 14 cores
beside the run: 1 red in 6 (`silent: 0 flushes were told of the loss, not
1`). The capture shows the kernel's record of the return and then the
claimant's `refused with Io` and `PASS`, but not the TOLD record the kernel
wrote before answering Io. The harness's re-run alone was green.

`guest_verdict` now takes the shutdown's drain and judges the kernel's
records from the test's start through it. The shutdown runs before the
verdict at all three call sites. With the fix, under the same load: 8 of 8
green (EXIT=0 each). `cargo test --test toyos-build -- --nightly
partition_claim`: 3 passed, EXIT=0.

Closes the departure finding. The gives-up finding stays open: it also
names a global fsync-deadman race this does not touch.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014iqcj4jDKpaiDX8B7CMvmK
#524 landed. Its move of kernel/src/arch/syscall/proc.rs to kernel/src/syscall/proc.rs carries the join fix. release.rs and sourcegate.rs merged clean.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014iqcj4jDKpaiDX8B7CMvmK
issues/build/a-guest-lane-leaves-the-toolchain-tarball-in-its-tmpdir.md
is fixed by 80e657c: the install stages in a `toyos_tmpdir::TempDir`.

issues/kernel/fpu-isolation-s-thread-join-answers-not-found-on-main.md
is fixed by 05839b7: the join keeps the answer its collect gave. The
landing it left unbisected is #513, whose `watch::wait_until` re-runs
the predicate that collects.

Nothing cites either file.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014iqcj4jDKpaiDX8B7CMvmK
@Japabu
Japabu marked this pull request as ready for review September 27, 2026 00:06
Japabu and others added 3 commits September 27, 2026 03:07
…re the marker too

`exit_wait_storm` is red on main's nightly at fd62f56 (run 36278449733,
guest (1), red alone as well): `the kernel accounted children exiting with
[0, 0, 1, 2, 3, 4, 5, 7, …]`. Locally at this branch it also reds as `the
parent made 0 call(s) of syscall 25`.

The judge took the parent to be the first `spawn:` line of the binary in
the test's window. The runner's `===TEST_START===` reaches the console
through `logd` and the kernel's records through `klogd`. The harness moves
only the lines from the *last* matching spawn record in `before` into the
window. When the parent and its first children were spawned before the
marker arrived, the window opened at a child's spawn. The judge then called
that child the parent, counted the real parent's exit (code 0) as a child's,
and read a child's syscall profile as the parent's.

A probe printed every storm spawn line with the half it landed in, applied
as a checked patch and restored. On a red run: pids 7 (the parent), 8 and 9
in `before`, 10 onward in `serial`.

The judge now reads `before` and the window together. It takes the parent
as the lowest pid among the storm's spawn lines, since pids are never
reused and the parent is made first, and it counts as children only the
pids above it.

- Red before, locally: 3 of 4 runs red (one run whose harness re-run was
  red too, and the probe loop's red).
- Green after: `cargo test --test toyos-build -- --nightly exit_wait_storm`
  8 of 8, EXIT=0 each.

This was green on main's nightly at 3f46a01 (run 36111884575) and flaky at
e8d7c9c (run 36228604597). The two-path console came with #492 (b0adc60)
between them; not bisected.

Also files the two older nightly reds this branch does not fix, with what
was measured:
issues/boot-media/a-disk-whose-port-went-away-panics-the-boot-at-roots-hold.md
issues/boot-media/screen-diag-boot-leaves-no-i8042-line-on-the-panel.md

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014iqcj4jDKpaiDX8B7CMvmK
Red on main's nightlies at e8d7c9c and fd62f56 and on #524's, in two shapes; green alone on the dev host. No issue carried it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014iqcj4jDKpaiDX8B7CMvmK
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014iqcj4jDKpaiDX8B7CMvmK
@Japabu Japabu changed the title Main's nightly green again: the tarball in a TempDir, a join that keeps its answer, two storage judges Main's nightly: the tarball in a TempDir, a join that keeps its answer, three judges that read the whole log Sep 27, 2026
@Japabu

Japabu commented Sep 27, 2026

Copy link
Copy Markdown
Collaborator Author

Judged: the thread_join fix keeps the first answer its predicate collects (the predicate consumes the zombie; #513's recheck-after-wake made the second look NotFound) — read and correct; fpu_isolation EXIT=1 → 0. The release staging now goes through TempDir without weakening #529's leftover check; the three judges are fixed at their premises (blockd reissue order, kernel records past the marker, the parent pid). Nightly 36285169430 greens host, build, both portability lanes, tcg, audio and five guest lanes; the eight remaining reds predate or are filed. Landing.

@Japabu
Japabu added this pull request to the merge queue Sep 27, 2026
Merged via the queue into main with commit 1ce7183 Sep 27, 2026
15 of 23 checks passed
Japabu added a commit that referenced this pull request Sep 27, 2026
…-lld switch

The rust submodule moves to fbf6ad143d8, a fork merge of this branch's
209f10ded88 (every ToyOS target links with rust-lld and -Bsymbolic) and
main's 64a2050c484 (#527's stream sinks and clock page); it merged without
conflict and is on toyos-inbox through 56f00d51770.

Every other overlapping file merged hunk by hunk with no textual conflict:
the two sides touch disjoint regions of src/build.rs, src/release.rs,
src/sourcegate.rs, kernel/Cargo.toml, kernel/src/loader/tls.rs,
fpu_isolation.rs and the two issue files. No published SDK crate changes on
this branch, so no version moves; every tracked lockfile resolves --locked.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014iqcj4jDKpaiDX8B7CMvmK
Japabu added a commit that referenced this pull request Sep 27, 2026
…, #531, #534) into the Netstack3 netd

Two conflicts. tests/common/origin.rs: main added `volumes` to the imports
this branch had split to name `segment`'s NEIGHBOUR and NEIGHBOUR_MAC; both
kept. userland/Cargo.lock: main's lock taken whole and re-locked against this
branch's manifests (`cargo metadata`), which adds the mirrored crates and their
dependencies and drops smoltcp and its defmt.

The rust gitlink fast-forwarded to main's fbf6ad143d8; this branch's pin
(7a809b7591f) is its ancestor, and the branch made no fork commit of its own.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014iqcj4jDKpaiDX8B7CMvmK
@Japabu
Japabu deleted the wt/toyos-nightlyfix branch September 28, 2026 09:46
Japabu added a commit that referenced this pull request Oct 2, 2026
…ue stays open

The first round's fix moved `layout::server` from `admit` into
`Service::open`, where nothing but reading holds it: with that move
reverted at 0878aa1 and the round's tests kept, `cargo test -p
toyos-blockring` and blockd's host test both exit 0. The only arm that could
red was a guest run of `blockd_survives_its_death`, which #660 cut.

The order is now a type. `wire::Opened`'s fields are private and
`Opened::over(page, blocks, unique)` returns a server's ends and its answer
together; `layout::server` is the crate's own. blockd can encode no
`MSG_OPENED` before its two cursors are 0, and its `Opening` carries both.
A compile-fail case on `Opened` holds the refusal (E0451), beside a block
that compiles.

The issue is not closed. Its exit asks for the test green across a run of
repeats, and the test and its trace judge left the suite in 520c0d1, so
nothing that runs can meet it. Its body now says what the first round found
(every cited red predates #534's judge, whose comparison passes the cited
trace: run on the two orders, it passes where the comparison before it
fails) and where the test went.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013UDZQ6fSKw14e4w2TKTRfm
Japabu added a commit that referenced this pull request Oct 2, 2026
…test reads a used page

Answers the review of 7a8c3b2 on #643.

The issue `blockd-survives-its-death-reds-on-a-replacement-that-reorders-
acknowledged-writes` is deleted, and not on this branch's type. Its subject
was closed before it was filed: 17bb264 (#534) is the fix for its
signature. That commit's message names run 36273557690 and the pair
[282600, 281592] / [281592, 282600], and its judge holds the replacement to
the same writes as a multiset, in order only among writes that overlap.
`git merge-base --is-ancestor 17bb264 <head>` exits 1 for 8c5be84,
a55d62c and 59bd29f, the three heads the issue cites and was filed at, and
0 for origin/main: every red it records is the verdict of the judge before
#534, which is the exit's second arm, "the verdict is shown wrong about it".
`Opened::over` orders the handshake and bears on neither arm. The exit's last
clause named a test 520c0d1 (#660) deleted, and Stage D of
`the-guest-suite-runs-only-what-no-cheaper-tier-reaches` already owes its
replacement. The slug was cited nowhere else in the tree. Its durable rule is
at its site already: requests in flight at once are unordered
(`toyos-blockring/src/lib.rs`, and `Client::next_request`, which keeps an
overlapping pair apart). What reorders the two writes, QEMU's bottom halves
and NVM Express 1.4 section 6.3, is in 64f5854's message.

What the branch does leave owed is filed: `nothing-reopens-a-blockd-session-
over-a-used-page`. The nightly's `blockd_io: FAIL /AFTER.BIN after the
restart: Io` (run 36753172688, guest 7) was fixed by reading and is
reproduced by nothing, and no tier reopens a session over a used page.

The model is origin/main's again. The last round split its session end into
`ended` and `reopen` and gave `hold_empty` two parameters so that the page
kept a dead session's cursors. The search does not visit the difference: a
state is keyed by its queues, and nothing looks at the page between `notice`
and `reconnect`. With and without the split, `cargo test -p toyos-blockring
--lib -- --nocapture --test-threads 1` prints the same eighteen verdict lines
(end states and flushes given up, per bound). The one test that wanted a used
page walks to `crash`, where main's model already holds one, and ends the
clone's session itself.

That test is named for what it can fail on:
`a_used_page_reads_fresh_once_a_servers_ends_are_made_over_it`. Its old name
stated blockd's order, which it stays green without.

The compile-fail case on `Opened` names no error code. rustdoc reads one only
on a nightly build and the host suites run a stable one, so `E0451` was read
by nothing: `E0308` in its place left the doc-tests green. The block beside
it that compiles is what holds the case, as in `toyos-net-wire`. Filed as
`a-compile-fail-case-names-an-error-code-rustdoc-never-reads`, with the same
mutation run on `toyos_bootmap::DirectMapEnd` (E0603) and
`toyos_transport::Place` (E0080): both doc-test runs exit 0 under E0308.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013UDZQ6fSKw14e4w2TKTRfm
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.

1 participant