From d076dbb2d7df142dd134c2dab89b70fd779f34e2 Mon Sep 17 00:00:00 2001 From: japabu Date: Mon, 28 Sep 2026 23:57:21 +0200 Subject: [PATCH 1/2] File: a first dial turned away before a line is waited on to its caller's bound This came out of measuring the red of `metaltalk::tests::a_refused_first_dial_is_asked_again_up_to_its_ceiling`: one in 200 full `--lib` runs under load at 9aa473d0, panicking at `src/metaltalk.rs:1326:37`. The test is not changed here. At 9aa473d0 it dialled a listener it had bound and dropped. #566 (e47d1f06) replaced that with a `Refusing` stage before this was measured, so no socket reaches it on main. A standalone probe (bind 127.0.0.1:0, drop, connect_timeout 5 s, 15 s per arm) named the mechanism: - quiet: 72572 dials, all refused. - four threads binding and dropping 127.0.0.1:0 listeners: 87686 dials, all refused, none taken on a binder's port. - eight threads spawning children: 94095 dials, 9 taken. Nothing else in the process held the port, so a child's copy of the listener took them. - no dial timed out in any arm; the slowest refusal was 92 ms. A mutation reinstating the old premise, with a copy of the dropped listener that takes the dial and closes it before a line, fails the test the way the filed red did (build EXIT=0, test EXIT=101, "the dial gave up within 5 s of its 60 and said why", after 5.02 s). The old premise without that copy passes alone (EXIT=0). The wait running out its whole bound is a production path, filed here: `serve` neither redials a first dial closed before a line nor records `unopened`, so `wait_for_connection` waits to its bound, where its doc says it returns once the dial has ended with none. Co-Authored-By: Claude Opus 5.5 --- ...-line-is-waited-on-to-its-callers-bound.md | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 issues/diagnostics/a-first-dial-turned-away-before-a-line-is-waited-on-to-its-callers-bound.md diff --git a/issues/diagnostics/a-first-dial-turned-away-before-a-line-is-waited-on-to-its-callers-bound.md b/issues/diagnostics/a-first-dial-turned-away-before-a-line-is-waited-on-to-its-callers-bound.md new file mode 100644 index 0000000000..b3652fc5b9 --- /dev/null +++ b/issues/diagnostics/a-first-dial-turned-away-before-a-line-is-waited-on-to-its-callers-bound.md @@ -0,0 +1,35 @@ +--- +status: open +kind: tooling +opened: 2026-09-28 +--- + +# A first dial turned away before a line is waited on to its caller's bound + +`src/metaltalk.rs`'s `serve` never asks a first dial again when its +connection closes before a line (`again` is false), and it records no +`unopened` for it. So `Stream::wait_for_connection` still reads the stream as +dialling (`state.unopened.is_none()`) and waits out its whole `by`. Its doc says +it returns "once the dial asked for it ended with none". Through QEMU's +forward that close is the only sign the guest refused, and each caller then +names the wrong thing, late: + +- `metalswap::swap` says "no boot opened the record stream within N s" once + the whole window has passed. +- `tests/common/logstream.rs`'s `reader` says "the stream never opened" once + `CEILING` has passed. +- `converse` waits `FOREVER` and returns only at the metal loop's `give_up`. + +The close itself is recorded in `end`. + +Measured: a mutation of +`a_refused_first_dial_is_asked_again_up_to_its_ceiling` hands its first dial +to a listener that accepts it and closes it before a line. That test's +`wait_connected(5 s)` returned `None` after 5.02 s, and `unopened()` was still +`None`. + +## Exit condition + +A first dial whose connection closes before a line ends `wait_for_connection` +at once, and `unopened` names the close. A host test stages that close +through a listener it owns and accepts on, and fails on the base. From f4a30b07e23123219e59499d789a9598d10b0e5a Mon Sep 17 00:00:00 2001 From: japabu Date: Tue, 29 Sep 2026 00:18:32 +0200 Subject: [PATCH 2/2] File: a compiler fixture's git commit could not create a temporary file The 200-run loop that proved the refused-first-dial test green under load went red once elsewhere. In run 182 of 200 at e3a1cdc8, with the 1-minute load average at 62.82, `compiler::tests::a_missing_primary_record_is_refused_and_builds_nothing` failed because its fixture's `git commit` hit "unable to create temporary file: Invalid argument". It is off this branch's path, so it is filed and not investigated. Co-Authored-By: Claude Opus 5.5 --- ...ommit-could-not-create-a-temporary-file.md | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 issues/build/a-compiler-fixtures-git-commit-could-not-create-a-temporary-file.md diff --git a/issues/build/a-compiler-fixtures-git-commit-could-not-create-a-temporary-file.md b/issues/build/a-compiler-fixtures-git-commit-could-not-create-a-temporary-file.md new file mode 100644 index 0000000000..b242d3a448 --- /dev/null +++ b/issues/build/a-compiler-fixtures-git-commit-could-not-create-a-temporary-file.md @@ -0,0 +1,28 @@ +--- +status: open +kind: tooling +opened: 2026-09-29 +--- + +# A compiler fixture's git commit could not create a temporary file + +`src/compiler.rs`'s `a_missing_primary_record_is_refused_and_builds_nothing` +went red in 1 of 200 full runs of the toyos-build lib test binary at +`e3a1cdc8`. Those runs went beside a `cargo test --workspace --exclude +toyos-build` loop as host load, with the 1-minute load average at 62.82 for +that run. The fixture's own git failed, not the code under test: + + panicked at src/compiler.rs:373:9: + git ["commit", "-qam", "a target"] in $TMPDIR/toyos-tmp-4827-0/compiler-record-29/fork-src: + error: unable to create temporary file: Invalid argument + fatal: failed to write commit object + +The other 199 runs passed. Nothing has measured why git's temporary file in +that repository's object store failed with EINVAL. No host-test counterpart of +`src/redlist.rs` disables the test, so every `cargo test -p toyos-build --lib` +still runs it. + +## Exit condition + +The EINVAL is traced to a cause the test can rule out by construction, and a +loop of 200 loaded runs shows the test green each time.