Repository navigation
The shared boots run as guest rows, each member judged by its own exit - #1271
Conversation
edb3321 to
bf8f66e
Compare
Review of #1271 at
|
|
Round 2 is at
Negative controls: five mutations, each red, with the restored tree green: https://github.com/ToyOSOrg/evidence/tree/458f382bf9f2f94865a62605bea01d8ccfc3772e/pr-1271/round-2 |
Round 2 review of #1271 at
|
|
Round 3 is at
B3 is open. Run 43102627714 at |
53f7390 to
a263741
Compare
The `testcases` boot owed on metal for #1252 now names the four shared-boot members whose rebased forms have only been compiled: #1261's `poll_belongs_to_its_handle`, which connects through its connector where it opened a one-entry namespace, and `messages_are_whole`, `moved_rights` and `mutual_kill`. No guest row runs them until #1271's shared-boot row lands. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Both metal benches are down, and the shared boots' members (every discovered Rust test binary, the C corpus and `LAST_MEMBERS` on `testcases`, `ACTUATOR_TESTS` on `shared-debug`) ran on nothing else since the shared block left the guest suite. Two machine tests, `testcases_members_exit_0` and `shared_debug_members_exit_0`, run those boots on QEMU x86-64's q35. Each takes its boot from `shared_metal`, the one membership the metal profile reads, batches it with `metal::batches` and stages it with `metal::stage`, which `metal::build` now calls too: the derived config, its job list in the bench's order, the C corpus's `ccheck` links and every file the members reach. The kernel and parameters are the `SharedBoot`'s own. The guest runs the list to its `reboot`, which `-no-reboot` makes QEMU's exit, and each member is judged by the runner's own `===TEST_END` line for it, read only under the runner's head without `pid=`, so a job's line or a longer name's end does not answer for it. A kernel death anywhere on the console reds the row. The runner's list bound is the bench's times `HOST_SCALE_CAP`: under QEMU the harness's ceiling, paid for the host the boot measured, ends a list that does not end itself. An emulated `testcases` list ended 116 s into its boot in development, past the bench's 102 s. `kernel_of` takes the test kernel named beside actuators, which `shared-debug` declares. A filter naming a shared member is still refused, and now says a shared boot runs whole under its row. Metal's boots, members and judges are unchanged; the rows riding those boots on the T14 stay off the guest rows. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
It made 6,000 empty files in `/tmp` so that their names alone would exceed a 64 KiB listing reply. On a 4 GiB guest the memory volume's pager serves about 3,468 objects, so the member was refused its 3,465th file and panicked with every file it had made left behind. On a shared boot that left `/tmp` full for the rest of the list: every later member that writes `/tmp` failed with it, seven Rust members and seven corpus cases. It now makes 640 files of 200-byte names. The names alone are 128,000 bytes, nearly twice a 64 KiB reply, which a const assertion holds, and its 641 objects are under the 1,024 any pager serves, whatever the machine's memory. A refused create removes what it made before it fails. The cap itself is recorded in `issues/tmp-holds-one-file-per-megabyte-of-ram-whatever-the-files-hold.md`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The MEMORY role's pager is sized as DATA's is, capacity/16 objects, and its anonymous objects are never dropped to make room, so the object count caps `/tmp`'s files outright: 3,468 on a 4 GiB guest, one per 1,126,096 bytes of memory, empty files included. Found by the shared boot's guest row, where `readdir_bound` was refused its 3,465th empty file. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`compile_c_tests` and `check_not_run` replaced the process-wide panic hook for the whole corpus compile and caught each case's panic. Now that the shared guest rows compile the corpus inside the twelve-wide suite, every other lane's panic lost its location line meanwhile. `compile_c`, `compile_own_c` and `link_toyos` return the refusal they used to panic with, word for word, so `NOT_RUN`'s quoted stages compare as before, and the hook, the `catch_unwind`s and `panic_message` go. A clang that cannot be run at all still panics: no case is at fault for it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…typed Any successful exit of a `-no-reboot` QEMU was taken as the list's `reboot`, yet a reset, a power-off and a triple fault all exit with status 0, so a silent reset after the last member read green. `judge_shared` now counts the end only where the kernel's own record says `Rebooting.` (`bootlog::REBOOTING`) and QMP's `SHUTDOWN` event names `guest-reset`, as `power::ended` holds. The row opens `QmpShutdown` as soon as the boot is up, since QMP delivers no event from before its client connected. The row's verdict over what the boot left is a function of its own, and the check stages the cases: a silent reset after the last member, a `Rebooting.` a program says, a power-off, a stop QMP never named and a wait that never saw QEMU exit are each red. A member is `Passed`, `Failed` or `Unreached` rather than a sentinel message, and the member check stages a `===TEST_END` under the kernel's and another program's head, so the speaker filter's source half is held as its `pid=` half is. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… rows The /tmp cap lets one client take every file other clients need, which is `severity: [security]` by the tracker's definition. Its owner is the process-memory track, its formula sentence matches the arithmetic, and its exit names the cheapest proof: a host module test of the file server over its `Pager` trait's fake. The T14 track says the guest rows stage the same members in the same order, not the same job lists: they leave out the bench rows' jobs. The frozen nightly's record says the unfiltered suite now carries both shared rows and an in-suite build of every guest binary and corpus case, whose TCG cost resumption measures. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… holds A clang that cannot be run panics in a corpus compile worker, and the join's `expect` replaced that payload with `a compile thread: Any`; the join now resumes the worker's own panic, so the row's reason carries it. `check_not_run` no longer makes the C sysroot first: that call existed to run before a panic hook went in, and its first `compile_c` makes the same call on the same thread. `link_toyos`' one-line refusal is one line of the corpus compile's list and of `NOT_RUN`'s report; nothing cuts it to its first line any more. `await_end` answers `Ok` for any exit 0, which a reset, a power-off and a triple fault all are under `-no-reboot`; whether it was the list's reboot is its caller's to judge. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…to main's #1273 made /tmp hold its files by what each costs and left two follow-ups for this branch. `testcases_members_exit_0` judges `tmp_empty_files` on the same 4 GiB guest as the dedicated x86-64 row `tmp_holds_empty_files_by_what_each_costs` did, so that row and its function go. Its `DRIVEN_AND_SHARED` entry stays, now naming only the AArch64 row that still drives the binary. `issues/tmp-holds-one-file-per-megabyte-of-ram-whatever-the-files-hold.md` goes: #1273 lifted its count, and what is open of it, one client filling the server and denying the others, is `issues/one-client-can-fill-the-tmp-servers-memory-and-deny-every-other-client.md`. `readdir_bound`'s comment no longer counts its files against a pager's object count, which a memory volume no longer keeps. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
a263741 to
ba2aacb
Compare
|
Orchestrator: landing under the benches-down rule. Review r2 closed B1/B2; B4/S7–S9 fixed. Guest runs: triage 43102627714 at bf8f66e and landing 43112734198 at a263741 — both rows green on KVM both times (testcases 236/236, shared-debug 9/9). Head ba2aacb adds only #1273's follow-ups (the dedicated x86 /tmp row dropped in favour of the shared member; the superseded record deleted) and the registry rebase. From here the T14's shared members run as x86-64 guest rows. |
Main 3c5c555 (#1271) makes the testcases list a guest row, `testcases_members_exit_0`, which judges each member by its own exit; pagerprobe and the two served-file members this branch adds are members of that list. No file is changed on both sides. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The `testcases` boot owed on metal for #1252 now names the four shared-boot members whose rebased forms have only been compiled: #1261's `poll_belongs_to_its_handle`, which connects through its connector where it opened a one-entry namespace, and `messages_are_whole`, `moved_rights` and `mutual_kill`. No guest row runs them until #1271's shared-boot row lands. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… and std's word for too big is E2BIG's #1271 made the testcases shared boot a guest row (testcases_members_exit_0), which runs every Rust member and the C corpus on QEMU, so the records' "no guest row runs the corpus" and "the member runs only on metal" were false. The full-table record now owes metal only the testcases-watchdog boot, which no guest row runs. The record of the stream state's TCP half owes stream_state_is_one's run at main to that guest row, since what it holds is no bench's. std answers Failure::TooBig ArgumentListTooLong, std's own kind for E2BIG, which libc answers, rather than InvalidInput. The MAX_ARGS test's doc says its names table is MAX_NAMES bytes, MAX_NAMES's doc keeps only its capacity, and the record of a dropped empty argument names startup::bytes as the writer that skips it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… and std's word for too big is E2BIG's #1271 made the testcases shared boot a guest row (testcases_members_exit_0), which runs every Rust member and the C corpus on QEMU, so the records' "no guest row runs the corpus" and "the member runs only on metal" were false. The full-table record now owes metal only the testcases-watchdog boot, which no guest row runs. The record of the stream state's TCP half owes stream_state_is_one's run at main to that guest row, since what it holds is no bench's. std answers Failure::TooBig ArgumentListTooLong, std's own kind for E2BIG, which libc answers, rather than InvalidInput. The MAX_ARGS test's doc says its names table is MAX_NAMES bytes, MAX_NAMES's doc keeps only its capacity, and the record of a dropped empty argument names startup::bytes as the writer that skips it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Problem
Both metal benches are down indefinitely, and the T14's two shared boots were the only place their members ran: every discovered Rust test binary, the C corpus and
LAST_MEMBERSontestcases, andACTUATOR_TESTSonshared-debug. That is about 93 Rust binaries, 143 corpus cases and 9 actuator members, and several open PRs' central tests are among them. The QEMU shared block left the guest suite on 2026-10-01.What this does
Two machine tests run those boots on QEMU x86-64:
testcases_members_exit_0: the shipping kernel, 236 members.shared_debug_members_exit_0: the test kernel armed withSELFTEST_PARAMS, 9 members.The two rows are dispatchable like any other
MACHINE_TESTSrow. The filtermembers_exit_0takes both. An unfiltered run includes them, so nightly's KVM and TCG lanes do too.shared_metal, batches it withmetal::batchesand stages it withmetal::stage, whichmetal::buildnow calls too. The two paths therefore stage the same members in the same order, with the samecchecklinks, corpus expectations and reachable binaries; the guest rows leave out the bench rows' own jobs on both boots, and their list bound is the bench's ×8. The guest boots theSharedBoot's own kernel build and parameters. No second list exists.reboot, which-no-rebootturns into QEMU's exit. The row then reads, for each member, the runner's own===TEST_END <job> exit=N===line. Only the runner's head withoutpid=counts, so a job's line in the runner's ring and a longer name's end are not taken for it. A red row names every failing member, with its own window of the console. Members the list never reached are collapsed into one line. The boot counts as ended only by its list's reboot: the kernel's ownRebooting.record, and QMP'sSHUTDOWNnamingguest-reset, aspower::endedholds. Under-no-reboot, a reset, a power-off and a triple fault all exit with status 0. A kernel death anywhere on the console also reds the row.HOST_SCALE_CAP. Under QEMU, the harness's own ceiling, scaled for the host this boot measured, ends a list that does not end itself. In local development under TCG,testcasesended 116 s into its boot. The bench's bound for it is 102 s.buildis split at a function boundary, and the code moves unchanged. TheMETALrows that ridetestcasesandshared-debugstay off the guest rows: each is judged on a bench readback of hardware facts.kernel_ofnow accepts the test kernel named beside actuators, whichshared-debugdeclares. Any other build named with parameters is still refused.compile_c,compile_own_c,link_toyos) returns its refusal instead of panicking. The process-wide panic-hook swap and thecatch_unwinds are gone, so the shared rows' in-suite corpus compile no longer hides other lanes' panic locations.Where they run. QEMU x86-64 q35 (
Profile::Headless,qemu::SUITE_ARCH): KVM on the guest runner, and TCG on hosts that have no KVM. AArch64 builds no member, by the owner's ruling. No metal machine is added or dropped.Triage of the first guest run
Guest-rows run 43102627714 at
bf8f66e5eon the guest runner, under KVM: green.testcases_members_exit_0PASS, 236 members exited 0.shared_debug_members_exit_0PASS, 9 members exited 0. The run reported "liveness ceilings paid at 1.87x" and other host work at 0.04 CPUs, so the host was quiet. No member is red, and none is marked metal-only. The triage needs no code. That head predates the end check (judge_shared); the landing run below exercises it.Timing, for the liveness bounds only, since QEMU's clock is a hang ceiling and not evidence of speed:
testcasesrow reported 274 s, almost all of it before its guest started: the corpus compile, and 142.6 s waiting for the artifact-staging lock held by the other row's image build.shared-debug's took 3.4 s.testcasesis 102.2 s, which the host ceiling paid at 1.87x on this runner (about 191 s), and the in-guest ×8 bound is 817.6 s. The KVM list used about 7 % of the host ceiling. The ×8 bound only guards emulated guests, where a development TCG run ended 116 s into its boot. On KVM the host's ceiling is the one that would stop a stuck list.Earlier dispatches: 43098179083 ended
startup_failurein the GitHub Actions outage. 43100012498, 43108299085 and 43112666542 were cancelled while queued, for later heads.A member fix and a record
readdir_boundmade 6,000 empty files in/tmpso that their names alone would exceed a 64 KiB listing reply. On a 4 GiB guest,/tmp's pager serves 3,468 objects: (953,443 managed pages / 8 − 8,192) / 2, then / 16. Anonymous objects are never dropped to make room. The member was refused its 3,465th file and panicked with every file it had made left behind. Every later member that writes/tmpfailed behind it: 7 Rust members and 7 corpus cases./tmpfile per 1,126,096 bytes of RAM, empty files included; evidence and arithmetic). A pager's objects are charged as they are made, and /tmp holds its files by that #1273 lifted the count, so the record is deleted atba2aacbf3. What remains open of it, one client filling the server and denying the others, isissues/one-client-can-fill-the-tmp-servers-memory-and-deny-every-other-client.mdon main. As A pager's objects are charged as they are made, and /tmp holds its files by that #1273 asked, this branch drops the dedicated x86-64 rowtmp_holds_empty_files_by_what_each_costs:testcases_members_exit_0judgestmp_empty_fileson the same 4 GiB guest, and the member'sDRIVEN_AND_SHAREDentry stays for its AArch64 row.Checks
Head:
ba2aacbf3, rebased onto maind1cefbaf9. The rows use #1254's(name, fn)registration,run_machine_testis gone, and #1273's follow-ups are made. At that head:cargo test --test toyos-checks: 55 passed, includingsuite_split(98 shared binaries on the shipping kernel, 9 on the actuator one, 20 driven elsewhere and declared).cargo test -p toyos-metal: 81 passed.cargo clippy -p toyos-build -p toyos-metal --all-targetswith the adopted lints and-D warnings: clean.sourcegate: 9 passed.--listshows both rows andtmp_empty_filesas a member, and notmp_holds_empty_files_by_what_each_costs.The evidence below was taken before these rebases, at the heads it names.
cargo run -- --ci hostatedb33219fon a macOS host. It still coversbf8f66e5e: what changed since is a guest binary, which no host suite builds, and an issue record, whichsourcegate's tests pass atbf8f66e5e. Result: exit 1, 1 of 114 steps red. The red step is the build system'scargo test --lib, with 386 passed and 1 failed:the_caller_s_environment_reaches_neither_the_build_nor_the_key. That isissues/the-llvm-environment-test-breaks-git-on-macos.md, red on every macOS host, and its filebuild/llvm.rsis not touched here. Every other step is green, including the harness's own checks and clippy. Log.d0b51ab9are-ran what its changes can affect.cargo test --test toyos-checks: 47 passed.cargo clippy -p toyos-build --all-targetswith the adopted lints and-D warnings: clean.cargo test --lib -- sourcegate: 10 passed. The rest of the--ci hostrun above is untouched by round 2, which changes onlytests/andissues/.a_shared_member_is_judged_by_its_own_endanda_shared_boot_ends_by_its_lists_reboot, each with negative controls. Five mutations each red a check: the speaker filter's source half dropped, itspid=half dropped, the kernel'sRebooting.not required,guest-resetnot required, andRebooting.accepted from any speaker. The restored tree is green (round 2 logs and patches; round 1's single control is here).Owed on metal
Nothing new. This PR changes no metal boot, member or judge. The
build/stagesplit was verified by inspection only, because staging is suspended while the benches are down.Unresolved
a26374102: green. On the guest runner under KVM:testcases_members_exit_0PASS, 237 members exited 0;shared_debug_members_exit_0PASS, 9 members exited 0. Each verdict reads "…, and the list's reboot ended the boot", so the end check (the kernel'sRebooting.and QMP'sguest-reset) held on a real console. The host was quiet: ceilings paid at 1.83x, other work 0.04 CPUs. From thetestcasesimage's build to its verdict took 13.5 s. The hold branch that kepta26374102fetchable is deleted.ba2aacbf3differs from that head only by main's commits since818809583, harness registration, records and a comment inreaddir_bound.a26374102predates A pager's objects are charged as they are made, and /tmp holds its files by that #1273, so the run judges neithertmp_empty_filesas atestcasesmember nor A pager's objects are charged as they are made, and /tmp holds its files by that #1273's pager changes under the shared boots; A pager's objects are charged as they are made, and /tmp holds its files by that #1273's own row judged the member green on KVM, in guest-rows run 43123313540 at12aa41f8c.issues/the-nightly-is-frozen-so-nothing-runs-the-guest-matrix.md.🤖 Generated with Claude Code