Skip to content

A boot's sockets are a TempDir under /tmp, reclaimed like all scratch; disable partition_claim_departure and i8042_mouse - #560

Merged
Japabu merged 10 commits into
mainfrom
wt/toyos-pcdred
Sep 28, 2026
Merged

Japabu merged 10 commits into
mainfrom
wt/toyos-pcdred

Conversation

@Japabu

@Japabu Japabu commented Sep 27, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

This PR fixes one harness defect and disables two tests.

1. A boot's Unix sockets live in a toyos_tmpdir directory under /tmp (fixes lan_mdns_answer)

  • What failed. On the dev host, lan_mdns_answer failed with connect to QEMU's /private/var/folders/.../T/toyos-tmp-55923-0/tests-0/lane-2/tap-out-0.sock: path must be shorter than SUN_LEN. A macOS $TMPDIR plus the lane path can fill all 104 bytes of Darwin's sockaddr_un.sun_path. The QMP socket had the same shape (lane::dir()/qmp-{seq}.sock).
  • toyos_tmpdir gains a second base. TempDir::short(label) is TempDir::new under SHORT_BASE (/tmp) whatever $TMPDIR is. It runs the same Root::make, owner lock, GLOBAL lock and State::sweep, over a State of its own. So a SIGKILLed run's socket directory is reclaimed by the next process's first short directory, exactly as its lane scratch is.
  • A boot's Sockets holds one such directory, boot-<n>, with qmp.sock, tap-in.sock and tap-out.sock in it. QemuInstance owns it, so the directory goes after drop has reaped QEMU, and on any unwind out of a boot. The worst case, /private/tmp/toyos-tmp-4194304-99/boot-99999/tap-out.sock, is 57 bytes (wc -c).
  • The segment is opened through the boot. BootOptions::segment is a bool, and a test opens the segment with QemuInstance::segment().
  • profile_argv names its sockets under /nonexistent, like its other paths, and builds no live directory for an argv no boot runs.
  • The CI jobs see /tmp. --ci host and --ci guest read toyos_tmpdir::gone_roots("/tmp") before their steps. Their last step now also reds on a /tmp root whose process died while the steps ran.
  • Two issues close. issues/build/a-lane-s-tap-socket-path-is-past-sun-len-on-the-dev-host.md and issues/build/a-lane-s-tap-socket-path-outgrows-sun-len-on-the-dev-host.md are deleted, because this is their defect. Their exit also needs lan_mdns_answer green on the dev host. main's c4fc16ea rewrote the second issue after this branch first deleted it; the merge below resolves that modify/delete conflict by deleting it again, having met the exit condition main's rewrite added.

2. partition_claim_departure is disabled

Nightly run 36336701867, job guest (5), ran one wide. guest_verdict refused with the guest exited 0 having said 0 of its 1 refusals: and an empty stdout. The test was green when re-run alone. --known-red answered NO.

The issue is issues/boot-media/partition-claim-departure-exits-clean-with-none-of-its-refusals-said.md. Its exit condition requires that refusal (tests/common/partclaim.rs) to carry the kernel window, as the refusal for a non-zero exit already does, so the next sighting is not blind.

3. i8042_mouse is disabled; mechanism not known

The orchestrator's Fast-tier run on 06b926b1 failed with 872 pointer events reached userland out of 876 packets injected, FAIL i8042_mouse (17s). The issue is issues/hardware/i8042-mouse-ends-four-packets-short-with-a-clean-exit.md. It records what was measured:

  • The run ended with no error from run_test_paced: no STALLED.
  • It ended mid-burst, 872 of BURST's 1000 packets in.
  • The shortfall equals MOUSE_LEAD.
  • It took 17 s, under the guest's 60 s RUN_CEILING.
  • None of the guest's stdout, the kernel's serial window or the exit code is in the message. The Metal boot writes no uart-*.log.

The tree offers two paths to this shape:

  • A misframed packet meets the guest's own end rule. This was measured on the host by feeding the burst's bytes through toyos_ps2::MouseDecoder. A gap longer than PACKET_GAP_NS between a −1 packet's head 0x18 and its dx 0xFF yields a buttons=0x07 event and then a buttons=0x00 one. That is the right-button press and release the guest exits 0 on.
  • A non-zero exit, which i8042_mouse never reads.

Neither path is established. The exit condition requires the shortfall refusal to carry result.stdout and result.exit_code.

Merge

Merged origin/main (1ec6daa9). Its only conflict was modify/delete on issues/build/a-lane-s-tap-socket-path-outgrows-sun-len-on-the-dev-host.md, which c4fc16ea rewrote with the same evidence and the exit condition "fits sun_path … wherever the scratch directory is, and lan_mdns_answer is green on the dev host". Resolved by deleting the file: this branch meets that condition (lan_mdns_answer EXIT=0, below). The rest merged automatically.

The /tmp leftover check's scope

src/ci.rs's left_behind names every root under /tmp whose process died during the job's steps that a snapshot taken before them did not name. /tmp is shared by every worktree on the host by design — it is what lets a SIGKILLed run's socket directory be reclaimed by the next process to touch the base, whichever worktree that is — so the check cannot yet tell its own job's dead root from one another worktree's harness left on the same host in the same window. Filed as issues/build/the-tmp-leftover-check-can-name-another-worktrees-killed-run.md, with this mechanism as evidence and an exit condition; on the hosted runners the gate uses, each job has its own host, so the check is exact there.

Gates

At f31742b7 (the merge above, plus the review-r3 fixes below it).

  • cargo test --lib: EXIT=0
  • cargo test -p toyos-tmpdir: EXIT=0
  • cargo run -- --clippy: EXIT=0
  • cargo test --test toyos-build --no-run: EXIT=0

Red arms

Host mutations, each applied as a checked patch, built, run, and restored:

  • The short State starts with swept: true. cargo test -p toyos-tmpdir --test reclaim gives EXIT=101: a_killed_process_is_reclaimed_and_a_live_one_is_never_touched fails with a killed process's root outlived the next process's sweep, in its /tmp arm.
  • TempDir::short takes std::env::temp_dir() as its base. Same command, EXIT=101: the same test's /tmp arm now fails its own starts_with(canonicalize("/tmp")) assertion, …/toyos-tmp-…/reclaim-0/toyos-tmp-…-0 is not under /private/tmp — a_socket_in_a_short_directory_fits_whatever_tmpdir_is folded into that assertion, so one mutation now covers both claims.
  • left_behind reads no /tmp roots. cargo test --lib ci::tests gives EXIT=101: the_job_names_a_short_root_a_step_left_when_it_died fails with a dead step's root is a red: "every test took its scratch with it".

The guest red arm for the SUN_LEN fix is the recorded failure quoted above. The old construction is only over 104 bytes under a five-digit pid, so no deterministic guest mutation exists.

Guest arms

Measured by the orchestrator at 6697367d (this branch's head before the merge above; the merge touches nothing these depend on):

  • cargo test --test toyos-build -- lan_mdns_answer: EXIT=0.
  • cargo test --test toyos-build -- --nightly iommu_virtio_platform: EXIT=0.
  • No new /tmp entries across both runs.
  • The killed-run check: EXIT=0. The SIGKILLed harness's /private/tmp/toyos-tmp-<pid>-0 was left, the next suite exited 0, and then it was gone.

Oracle

  • Darwin's sockaddr_un.sun_path of 104 bytes (<sys/un.h>), as enforced by the kernel's own refusal that Rust's UnixStream::connect reports as path must be shorter than SUN_LEN.
  • For the reclaim, the host kernel: the /tmp arm SIGKILLs a real process holding a short directory, and the kernel's release of its flock is what the next process's sweep reads.

🤖 Generated with Claude Code

…fusals, beside other guests

Nightly run 36336701867, job guest (5), on PR #541's head 1c0f0c7, whose diff
touches none of the partition-claim code: the departure role's guest_verdict
failed with an empty stdout capture and exit 0, re-ran green alone immediately
after. Same "reds beside other guests, green alone, no rate" shape already on
record for partition_claim_gives_up, but a different failure signature (a
guest_verdict stdout miss, not a kernel-log count mismatch), so it is filed
separately and cross-linked rather than folded in.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Japabu
Japabu marked this pull request as ready for review September 27, 2026 21:05
…oss under host contention

lan_mdns_answer: QEMU's chardev refused the tap sockets' path once a macOS
$TMPDIR plus this harness's own lane path had already spent every byte of
Darwin's 104-byte sockaddr_un.sun_path, leaving nothing for a filename
(orchestrator's Fast-tier run on PR #537's head 06b926b, a diff that touches
neither). tests/common/segment.rs now names its sockets under /tmp directly,
via the new toyos_build::socketpath, whose length never depends on $TMPDIR;
open() unlinks both once connected, since /tmp is not this run's lane.

i8042_mouse: a third sighting of the identical shape already tracked in
issues/build/parallel-tests-red-under-other-suites.md's own entry for this
test (872/876 packets, never more than the pacing's 12-of-16-byte bound
outstanding) — inside the bound the first fix installed, so not that
mechanism. Extended that entry with today's evidence and filed
issues/hardware/i8042-mouse-loses-a-packet-under-host-contention.md for the
redlist row, naming the plausible mechanism this tree's own qemu.rs already
documents for the keyboard path: QEMU's PS/2 queue silently drops what a
guest a starved host has not scheduled has not drained, which MOUSE_LEAD does
not guard against the way the keyboard's own pacing against the guest's echo
does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Japabu Japabu changed the title Disable partition_claim_departure: red beside other guests, green alone Disable three flaky reds, fix one: partition_claim_departure, lan_mdns_answer (SUN_LEN), i8042_mouse Sep 27, 2026
@Japabu

Japabu commented Sep 27, 2026

Copy link
Copy Markdown
Collaborator Author

Review r1 — PR #560 at 9371464a

Gate: CI run 36351460291 at 9371464a: host success (--ci host success, --ci gate-stage success). The guest measurement of the fix (lan_mdns_answer on macOS) is still owed: the orchestrator's run.

Growth: git diff --shortstat origin/main...HEAD gives 7 files, +252 −4. Production: +38 (src/socketpath.rs lines 1–29, src/lib.rs +1, src/redlist.rs +8). Harness: tests/common/segment.rs +11 −4. Host tests: +28 (src/socketpath.rs lines 30–58). Issues: +174.

BLOCKER

  • tests/common/qemu.rs:3157 — the QMP socket is still lane::dir()/qmp-{seq}.sock. It is the same $TMPDIR-depth path this branch moves the tap off. On this host's standard $TMPDIR shape it is 100 bytes at lane-2/seq 0 (wc -c). BOOT_SEQ counts every boot in the process, so lane-10/qmp-1000.sock reaches 104 bytes, and Rust's connect refuses 104 exactly as it refused tap-out-0.sock. — Route it through socketpath::short("qmp", seq) so every harness socket goes through one function. Run iommu_virtio_platform (QMP) on macOS after the move.
  • tests/common/segment.rs:73-76 with tests/common/origin.rs:650-656 — the unlink only happens on the success path. mdns() returns at await_marker(..)? before tap.open(), and QemuInstance::drop SIGKILLs QEMU (qemu.rs:3795), which therefore never unlinks. Both /tmp names then outlive the run. They sit outside its toyos_tmpdir root, and CI's "nothing left in $TMPDIR" check cannot see them. — Remove them where the QMP socket is removed (QemuInstance::drop, qemu.rs:3819), and delete the unlink in open().
  • issues/hardware/i8042-mouse-loses-a-packet-under-host-contention.md:35-49,58-61 — the tree refutes the named mechanism, and the branch rests on it without measuring. Send it back to measure.
    • The mouse already paces against the guest's own report: arrived counts the guest's mev buttons= lines (tests/toyos.rs:10976,10987). A starved guest therefore holds at most 12 bytes however long it is starved.
    • A dropped byte makes the host wait at tests/toyos.rs:10992 and end in the STALLED error. It never produces this shortfall message.
    • The shortfall message needs a run that ended cleanly mid-burst. That is what happened here: 876 injected, against 1004 (BURST + 4) needed to finish. The guest's fixed 60 s RUN_CEILING does exactly that with exit 0 (tests/toyos-rust-tests/src/bin/i8042_mouse.rs:22,34,58), while the host's own ceiling is widened by budget_smp (qemu.rs:3625). The shortfall of 4 equals MOUSE_LEAD, the number of packets in flight when the guest stopped reading.
    • Measure from the failing Fast-tier log: the FAIL line's duration, and whether stdout ends in mev done seen=872.
    • Then re-file with the measured mechanism and a fix-shaped exit. For example: a guest ceiling cannot end the run as a clean exit, and a run that ends before the right-button release is refused as a stall.
    • The exit condition currently says "most likely by pacing the mouse injection against the guest's own report". The test already does that, so that clause goes.

NOTE

  • src/socketpath.rs:37-49 — the_lane_path_a_typical_macos_tmpdir_produced_did_not_fit asserts the length of a string literal, and no code change can turn it red. Delete it.
    • The mutation that matters is reverting segment.rs:39-42 to lane::dir().join(..). It turns no host test red.
    • Its only red arm is a macOS guest run with a five-digit pid: the old tap-out-0.sock path is 104 bytes under toyos-tmp-NNNNN-0 and 103 bytes under four digits (wc -c). That is the recorded 06b926b1 failure, which is accepted as the red arm for harness code.
  • Collision question: live runs cannot collide (pid), and taps within one run cannot either (SEQ). A stale name another user left in sticky /tmp makes segment.rs:43-44's ignored remove_file fail and QEMU's bind refuse. That is loud, which is acceptable. Unlinking after connect is safe on Darwin and Linux, because a connected AF_UNIX stream does not depend on its name. The point is moot once removal moves to drop.
  • tests/common/segment.rs:36 — Tap::in_lane no longer uses the lane. Rename it.
  • tests/common/partclaim.rs:470-474 — guest_verdict's "exited 0 having said" refusal prints only result.stdout and drops the kernel window. The nightly's serial-guest-4 artifact holds no departure boot: no file in it contains usb-reset-moves (rg over the downloaded artifact). So the next sighting will be as blind as this one. The issue's exit condition should require that refusal to carry the kernel window.
  • issues/hardware/i8042-mouse-loses-a-packet-under-host-contention.md:68 — the owner line "The i8042/input path." names no holder. Its siblings say who holds them.
  • Test schedule: scratchpad/testvalue/bucket_nightly.txt puts all three tests in the nightly bucket, and i8042_mouse is Tier::Fast (tests/toyos.rs:1329). This does not conflict with disabling them; the tier move belongs to the schedule's branch.

REMOVE

  • src/socketpath.rs:4-12 — the quoted failure and the $TMPDIR anatomy are investigation; the commit message carries them.
  • src/socketpath.rs:33-37 — the doc of the test that goes.
  • tests/common/segment.rs:31-35 — restates the socketpath module doc.
  • tests/common/segment.rs:73-74 — goes with the unlink.
  • tests/common/lane.rs:65 — "and socket": false once sockets leave the lane.
  • issues/boot-media/partition-claim-departure-exits-clean-with-none-of-its-refusals-said.md:7 — "beside other guests, green alone". The job log says --- parallel, 1 wide --- (--jobs 1), and the harness says "it was alone both times".
  • same file :52-58 — "shares with 23 other parallel tasks …": false for the same reason.
  • same file :47-52 — "the narrower reading … lost the guest's captured output": unsupported, as the file itself says.
  • same file :62 and :78 — the "reds beside other guests" shape and the parenthetical: false.
  • issues/build/parallel-tests-red-under-other-suites.md:53-75 — duplicates the new file, carries the refuted mechanism, and is an existing issue this branch does not own (issues/README.md, "Filing one").
  • PR body — "each beside other guests" (false for CLAUDE.md: soundd drives both cards, and three retired ABI numbers #1 by its own log), "reproduces the exact failing path's length against the old construction" (it measures a literal), and the i8042 mechanism paragraph.

SEND BACK

Japabu and others added 2 commits September 27, 2026 23:56
…ays what is known

The QMP socket was still `lane::dir()/qmp-{seq}.sock`, the same
`$TMPDIR`-depth path the tap moved off: 100 bytes at lane-2/seq 0 on the dev
host, and `lane-10/qmp-1000.sock` reaches the 104 Darwin's connect refuses.
It now comes from `socketpath::short("qmp", seq)`, as both tap sockets do.

`socketpath::short` returns a `Socket` that removes its name when dropped.
The `QemuInstance` holds the QMP socket and the `Tap`, so both names go once
QEMU is reaped. They also go on every early return and every unwind out of the
boot, including `mdns()` returning at `await_marker` before it ever opened the
tap. The unlink in `Tap::open` and the QMP `remove_file` in `drop` are gone.
`BootOptions::segment` is now a flag, and the test opens the segment through
`QemuInstance::segment`. `Tap::in_lane` becomes `Tap::of_boot(seq)`, keyed to
the boot's own sequence number. `profile_argv` builds the tap it is asked for
instead of dropping it.

The host test that asserted a literal's length is deleted. The remaining
tests pin that `short` lives under `/tmp` and fits, and that a dropped
`Socket` removes its name.

The i8042 issue's starvation mechanism is refuted: the mouse already paces
against the guest's own report. The file is renamed for what was measured:
872 of 876 in 17 s, a clean end, and a shortfall equal to `MOUSE_LEAD`. It
names the two paths the tree offers. One is a >5 ms decoder gap inside a -1
packet producing a right-button press and release, measured on the host
through `MouseDecoder`. The other is a non-zero exit this test never reads.
Neither is established, so the file says "mechanism not known".

The partition-claim issue loses its false "beside other guests" and
"23 other parallel tasks" claims (the job ran one wide). It also loses the
unsupported lost-output reading. Its exit now requires `guest_verdict`'s
exit-0 refusal to carry the kernel window. This branch's edit to
`parallel-tests-red-under-other-suites.md` is reverted to main's text.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Japabu and others added 3 commits September 28, 2026 00:01
`qemu_command` took eight arguments once the tap joined the QMP socket, which
clippy refuses. `Sockets` holds both of a boot's `/tmp` names. `QemuInstance`
drops it after QEMU is reaped, `qemu_command` reads it, and `profile_argv`
builds one with the tap it is asked for and, as before, no QMP socket.

`issues/build/a-lane-s-tap-socket-path-is-past-sun-len-on-the-dev-host.md`
and `...-outgrows-sun-len-on-the-dev-host.md` are this defect. Their exit is
"fits sun_path on every host, lan_mdns_answer green on the dev host". The
first half is `socketpath::short`. The second half is the orchestrator's run
of `lan_mdns_answer` on this head.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The `fire` closure only turned `Option<&PathBuf>` into `Option<&Path>`, which
`Sockets::qmp` now returns.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The names moved out of the swept lane directory. A SIGKILLed run now leaves
them, which is this branch's compromise, recorded with its exit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Japabu Japabu changed the title Disable three flaky reds, fix one: partition_claim_departure, lan_mdns_answer (SUN_LEN), i8042_mouse Every harness socket is a /tmp name its boot holds; disable partition_claim_departure and i8042_mouse Sep 27, 2026
@Japabu

Japabu commented Sep 27, 2026

Copy link
Copy Markdown
Collaborator Author

Review r2: PR #560 at 811da1d5

Gate: CI host at 811da1d5 is QUEUED (run 36353991674). The last green run is at 9371464a (run 36351460291).

Guest arms: 560 lan_mdns_answer EXIT=0 at 79955442. The two later commits change run_test_paced's step call and add an issue file; neither touches the mdns path. scratchpad/orch-runs/summary.txt has no 560r2 line yet for lan_mdns_answer, iommu_virtio_platform or the /tmp leftover check. That alone would be NOT READY FOR REVIEW. The BLOCKER below is structural and does not depend on those results, so it is reported now.

Growth: 13 files, +311 −110.

  • Production src/: +79 −4. socketpath.rs is 67, of which 23 are tests. redlist.rs +8, lib.rs +1, qemu.rs doc +3 −4.
  • Harness tests/common/: +68 −56.
  • Issues: +164 −50.

Round 1 BLOCKERs

  • QMP socket at lane depth: CLOSED in code. tests/common/qemu.rs:3159 names it through socketpath::short("qmp", seq). Its guest arm, iommu_virtio_platform, is still owed.
  • Unlink only on the success path: CLOSED. The name is removed by Socket's Drop. pcdred-r2/m1-no-drop.log gives EXIT=101 with a_dropped_socket_takes_its_name_with_it red, and lib.log gives EXIT=0 with it restored.
  • i8042 issue resting on a refuted mechanism: CLOSED.
    • The file now carries only measured facts and says "mechanism not known".
    • The 17 s duration against the 60 s RUN_CEILING refutes the round-1 ceiling reading.
    • The decoder gap is measured in pcdred-r2/gap_probe.log (EXIT=0).
    • Its claims check against tests/toyos.rs:10934-11050 and run_test_paced.

BLOCKER

  • src/socketpath.rs (whole file) — Socket is a sibling of toyos_tmpdir::TempDir ("gone when its holder is, on every way out") without TempDir's reclaim of a killed process. It moves every harness socket out of the tree that sweep reclaims, so a SIGKILLed run now leaves /tmp litter that main reclaims. That is a regression under the cleanup rule, not a compromise to file.
    • Fix in toyos-tmpdir: it also makes roots under /tmp, using the same Root::make, owner lock, GLOBAL lock and State::sweep over a second base, for example TempDir::short(label) backed by a second State.
    • Fix in the harness: a boot's Sockets holds one such directory, with qmp.sock, tap-in.sock and tap-out.sock inside it. The worst case, /private/tmp/toyos-tmp-4294967-99/boot-99999/tap-out.sock, is 57 bytes (wc -c).
    • Delete: src/socketpath.rs, Socket, the pid-reuse unlink in short, the seq in the socket names, and issues/build/a-killed-runs-socket-names-outlive-it-in-tmp.md.
    • profile_argv (tests/common/qemu.rs:4340) passes /nonexistent as the socket directory, as it does for its other paths. It stops building live Sockets for an argv no boot runs.
    • Test: toyos-tmpdir/tests/reclaim.rs gains a /tmp arm of a_killed_process_is_reclaimed_and_a_live_one_is_never_touched. A holder takes a short directory and is SIGKILLed, and the next holder's first short directory removes it. The arm must be red under the mutation that starts the short State with swept: true.
    • Refused alternative: a sweep over /tmp's toyos-<label>-<pid>-* names. A bare socket name has no owner lock, so its liveness would have to be the pid, which the module forbids ("Liveness is the lock and never the pid"). Probing a live name by connecting would take QEMU's single chardev client.

NOTE

  • src/ci.rs:508 — left_behind reads only the job's $TMPDIR, so a /tmp root escapes the guest job's check, before the fix and after it. Extend the check with the fix, or record the gap.
  • issues/hardware/i8042-mouse-ends-four-packets-short-with-a-clean-exit.md, exit condition — require the shortfall refusal (tests/toyos.rs:11043) to carry result.stdout and result.exit_code. The partition-claim exit now requires the same of its refusal, and this file says the missing capture is why neither path can be told apart.
  • same file :25 — exit=<n> is only one of the TEST_END tails that return no error: run_test_paced also accepts a bare or unparsable tail. The conclusion stands.
  • wt/toyos-netstack3 and wt/toyos-tcp carry their own short lane socket names and a-lane-socket-path-can-pass-macos-sun-len.md. That sibling scheme lands unless the orchestrator routes them through whatever replaces socketpath.
  • Socket's Drop at this head is sound:
    • The fields drop after QemuInstance::drop's child.wait(), so the names go after the reap.
    • wait_for_ready's panics kill QEMU (without a reap) before Files unwinds. Unlinking a name under a dying QEMU is harmless.
    • A second panic is avoided through thread::panicking().
    • The TempDir fix inherits the same ordering.

REMOVE

  • issues/boot-media/partition-claim-departure-exits-clean-with-none-of-its-refusals-said.md:50-54 — "a demultiplexer for concurrent guests' console lines … consistent with what was seen" is false, because the job ran one wide.
  • same file :65-67 — "Both may yet share one root cause in how this harness handles concurrent guests under load" is speculation, false for the same reason.
  • issues/build/a-killed-runs-socket-names-outlive-it-in-tmp.md — goes with the fix.
  • PR body, "Guest arms, run by the orchestrator" — states expectations ("should give"), not measurements. Main's record carries the runs or nothing.
  • PR body, "Unsure" — the first bullet goes with the fix. The second is orchestration, not main's record.

SEND BACK

…cratch

`sun_path` is 104 bytes on Darwin and `$TMPDIR`'s depth is the host's, so a
harness socket under the lane's directory can pass it. The previous fix named
each socket under `/tmp` by hand (`src/socketpath.rs`), outside the tree
`toyos_tmpdir` sweeps, so a SIGKILLed run left its names behind.

toyos-tmpdir makes roots under a second base, `/tmp`: `TempDir::short` runs
the same `Root::make`, owner lock, `GLOBAL` lock and sweep over its own
`State`. A boot's `Sockets` holds one such directory with `qmp.sock`,
`tap-in.sock` and `tap-out.sock` in it; the worst case,
`/private/tmp/toyos-tmp-4194304-99/boot-99999/tap-out.sock`, is 57 bytes.
`profile_argv` names its sockets under `/nonexistent`, like its other paths.

`src/socketpath.rs` goes, with its pid-reuse unlink, the boot sequence in the
names, and the issue that recorded the gap.

`--ci host` and `--ci guest` also red on a `/tmp` root whose process died while
their steps ran: `toyos_tmpdir::gone_roots` read before the steps and after.

The partition-claim issue loses two speculative passages; the i8042 issue's
exit condition requires its shortfall refusal to carry the guest's stdout and
exit code, and its TEST_END reading names every tail that returns no error.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Japabu Japabu changed the title Every harness socket is a /tmp name its boot holds; disable partition_claim_departure and i8042_mouse A boot's sockets are a TempDir under /tmp, reclaimed like all scratch; disable partition_claim_departure and i8042_mouse Sep 27, 2026
@Japabu

Japabu commented Sep 28, 2026

Copy link
Copy Markdown
Collaborator Author

Review r3: PR #560 at 6697367d

Gate. CI host is SUCCESS at 6697367d (run 36355166532; its headSha matches).

Guest arms at 6697367d. The orchestrator ran these (summary.txt, lines "560r3"):

  • lan_mdns_answer: EXIT=0.
  • iommu_virtio_platform --nightly: EXIT=0, PASS iommu_virtio_platform (7s) (g-iommu2.log). The first try without --nightly ran no test.
  • The /tmp listing before and after both runs: empty.
  • Killed run (killed-run2.log, EXIT=0):
    • Harness 62464 was SIGKILLed while it held /private/tmp/toyos-tmp-62464-0/boot-0, and the root was left.
    • The next suite exited 0, and the root was then gone.

Growth. 14 files, +408 −165.

  • Production +197 −97:
    • toyos-tmpdir/src +91 −30
    • src/ci.rs outside its tests +32 −12
    • tests/common +62 −50
    • redlist +8
    • src/qemu.rs +3 −4
    • Cargo.toml +1 −1
  • Tests +74 −18.
  • Issues +137 −50.

The production growth is the /tmp base and its reclaim. Accepted.

Round 2 BLOCKER

  • socketpath::Socket was a sibling of TempDir without its killed-run reclaim. CLOSED.
    • TempDir::short goes through Root::make, the owner flock, GLOBAL and State::sweep, over a State of its own (toyos-tmpdir/src/lib.rs:74-108, :193-211).
    • Deleted: socketpath.rs, Socket, the pid-reuse unlink, the seq'd names and the killed-run issue.
    • Sockets holds one boot-<n> directory with the three socket names in it (tests/common/qemu.rs:4800-4821).
    • profile_argv passes /nonexistent.
    • Negative control: the short State started with swept: true gives EXIT=101, red at reclaim.rs:158 in the /tmp arm (m1-short-swept.log). Restored, tmpdir.log gives EXIT=0.
    • Independent oracle: the killed run above. It is a real SIGKILL, and the host kernel's flock release is what the sweep reads.
  • One mechanism: yes.
    • No second reclaim path. gone_under is the sweep's own listing, and gone_roots shares it.
    • When $TMPDIR is /tmp, the two bases are one directory. flock locks each open file description on its own, so each State's sweep sees the other's root as live.
    • A boot that asks for neither socket still makes an empty boot-<n>. That is cheaper than an Option threaded through qemu_command. Accepted.

BLOCKER

None.

NOTE

  • Merge conflict. git merge-tree --write-tree origin/main HEAD (main at 1ec6daa9) gives a modify/delete CONFLICT on issues/build/a-lane-s-tap-socket-path-outgrows-sun-len-on-the-dev-host.md, which c4fc16ea rewrote.
    • Merge origin/main and resolve by deleting the file.
    • Main's hunks restate the evidence and add the exit condition "fits sun_path … wherever the scratch directory is, and lan_mdns_answer is green on the dev host". This PR meets it: lan_mdns_answer EXIT=0 at 6697367d.
    • The rest merges automatically. Re-run the host gates on the merged head.
  • src/ci.rs:529: the /tmp check can red on another worktree's run. It names every gone root made after before. On a host shared by worktrees, that includes another worktree's harness killed during the job.
    • The PR body's "Unsure" records this, which is neither legal outcome for a compromise.
    • File it in issues/build/ with an owner, this mechanism as evidence, and an exit condition, or make the check exact.
    • On the hosted runners the gate uses, the check is exact.
  • toyos-tmpdir/tests/reclaim.rs:170-183: deletion candidate. a_socket_in_a_short_directory_fits_whatever_tmpdir_is can fold into reclaimed's /tmp arm as one assertion: the short holder's root starts with canonicalize("/tmp"), under a $TMPDIR that is not /tmp.
    • The m2 mutation reds that assertion too.
    • The 104-byte d… directory and the length assertion then go. The worst-case length is in the PR body, measured by wc -c.
  • Sibling branches. wt/toyos-netstack3 and wt/toyos-tcp still carry their own lane socket names and a-lane-socket-path-can-pass-macos-sun-len.md. wt/toyos-netstack3 also carries both SUN_LEN issues this PR deletes. Both branches route through Sockets when they next merge main.

REMOVE

  • src/ci.rs:505-506: "a toyos_tmpdir::TempDir::short of a step that died, which only some later process's sweep would take". It is false on a shared host (NOTE above).
  • issues/boot-media/partition-claim-departure-exits-clean-with-none-of-its-refusals-said.md:66-67: "a QMP hook racing the marker it is keyed on, or something else —". It is the speculation left over from the paragraph round 3 deleted.
  • PR body, Gates: "origin/main had nothing to merge". It is false once the merge above lands.
  • PR body: "Guest arms are run by the orchestrator: …". It is a plan, not a record. The four measurements at 6697367d listed under Guest arms above (command, EXIT, log) are the record. Without them, the "fixes lan_mdns_answer" heading has no measurement in the body.
  • PR body: "Unsure". It moves to issues/ with the second NOTE.

Named changes: the merge and its resolution, the issues/ record of the shared-host red, the guest measurements in the body, and the REMOVEs.

LAND AFTER NAMED CHANGES

Japabu and others added 2 commits September 28, 2026 07:40
Resolves the modify/delete conflict on
issues/build/a-lane-s-tap-socket-path-outgrows-sun-len-on-the-dev-host.md
by deleting it: main's rewrite of the issue restates the same evidence and
adds the exit condition "fits sun_path ... wherever the scratch directory
is, and lan_mdns_answer is green on the dev host", which this branch's fix
already meets (lan_mdns_answer EXIT=0 at 6697367).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W6rME2DoqwjcYFStYHHY4j
…le the shared-host /tmp check as an issue, and cut two REMOVEs

`a_socket_in_a_short_directory_fits_whatever_tmpdir_is` duplicated the base
check `reclaimed`'s own /tmp arm can make directly, so it folds into one
`starts_with(canonicalize("/tmp"))` assertion there; the worst-case socket
path length (57 bytes, measured by `wc -c`) goes in the PR body instead of a
104-byte fixture.

`src/ci.rs`'s /tmp leftover check has no way to tell its own job's dead root
from another worktree's harness killed on the same host in the same window
(the reclaim mechanism deliberately shares /tmp's lock across every worktree
on the host), so it is filed rather than fixed: a Sunday-morning "a few
lines" fix would need per-job pid tracking this tree has nowhere to hang.

Cuts the two REMOVEs: `src/ci.rs`'s doc comment claiming this check is a
refusal "only some later process's sweep would take" (false on a shared
host), and the partition-claim issue's speculation about which mechanism is
at fault.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W6rME2DoqwjcYFStYHHY4j
@Japabu
Japabu enabled auto-merge September 28, 2026 05:51
@Japabu
Japabu added this pull request to the merge queue Sep 28, 2026
Merged via the queue into main with commit 6ef7427 Sep 28, 2026
1 check passed
Japabu added a commit that referenced this pull request Sep 28, 2026
- rust: the fork's 62fa74d7a50 merges main's pin 1b236638a90 (#541) into
  this branch's fee9fa6f7bb; the two share no file, and the merge over main's
  pin is this branch's six std files alone.
- issues/build/a-lane-s-tap-socket-path-outgrows-sun-len-on-the-dev-host.md:
  deleted as #560 deleted it. This branch's hunk was the two path lengths
  PR #536's lanes hit and an A/B on $TMPDIR's length; #560's short TempDir
  under /tmp is the fix for both lengths, so nothing of it is owed.
- issues/build/swap-crash-rolls-back-redial-turned-away-once-on-mains-nightly.md:
  deleted as #565 deleted it, folding it into
  a-swaps-redial-races-a-hard-dial-ceiling-against-an-unbounded-guest-gap.md.
  This branch's hunks: the status moved to expected-red and the known-red
  line (both carried by #565's redlist rows for swap_crash_rolls_back and
  lan_swap); the mechanism, a probation-long gap against a ceiling of 64
  refusals and not a time (carried by the folded issue's "What the code
  shows"); and the #536 sightings, added there as a seventh bullet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W6rME2DoqwjcYFStYHHY4j
@Japabu
Japabu deleted the wt/toyos-pcdred branch September 28, 2026 09:46
Japabu added a commit that referenced this pull request Sep 28, 2026
Takes #560, #541, #565, #563, #569 and #570. `src/ci.rs` and
`tests/toyos.rs` merge without conflict; `rust` takes main's pin, 1b236638,
since this branch carries no fork commit.

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