Records the measured effect of the region-based allocator (2.2x on a cold ls, 6 s off the boot), the two pre-existing UEFI blockers found while verifying it, and the three confounds that each produced a confident wrong answer about guest speed in one session. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
3.6 KiB
| name | description | metadata | ||||||
|---|---|---|---|---|---|---|---|---|
| schos-bootcheck-trust | bootcheck silently stopped running and five of seven modes asserted nothing; how to tell a real pass from a script that died |
|
A green run is only green if you counted the checks. On 2026-08-09 the bootcheck suite was reported passing seven times when it had not executed at all, and separately when five of its seven modes asserted nothing whatsoever.
Why: bootcheck.ps1 had [string]$Qemu = (Find-Qemu) as a param default.
PowerShell binds parameter defaults before any function in the script body is
defined, so it died on its first line with "Find-Qemu is not recognized" —
text containing neither FAIL nor Exception, which were the two words being
grepped for. Empty output was read as success. Resolve after the param block:
if (-not $Qemu) { $Qemu = Find-Qemu }.
And: an earlier index-based edit (s[:a] + inner + s[c:]) that removed the
obsolete -SchFS block also deleted the Expect blocks for -Tty, -Usb,
-Sock, -Ps and -Evdev. Those modes still booted, still printed, and still
exited 0 — asserting nothing. It happened before git init, so no commit ever
had them; they were reconstructed from failure text quoted earlier in the
transcript.
How to check a run is real:
grep -c '\[ok\]' # must be non-zero, and roughly what you expect
grep -c 'boot check passed'
Counting FAIL alone cannot distinguish "passed" from "never ran". Expected
counts as of 2026-08-09: base 23, Tty 47, Ps 28, Sock 60, Fb 32, Usb 27,
Evdev 25 — Tty and Sock include [ok] lines printed by the guest programs
themselves.
Never pipe a long bootcheck through head. It closes the pipe, kills the
script partway, and looks like a hang. Redirect to a file and grep the file.
Why: the general lesson is that absence of failure output is not evidence of success. Both of these produced clean-looking runs while testing nothing.
How to apply: after any change to the harness itself, verify the check count, not just the absence of FAIL.
The extended suite is timing-fragile on the Fedora laptop
Wait-Prompt waits a fixed 20 s; measured on this machine with the guest's
own /proc/uptime, a cold ls /bin | wc -l takes 23 s and took 51 s
before the e820 work. When it overruns, the script sleeps 2 s and types anyway,
so the next command lands in a busy shell and the transcript interleaves — and
the check that fails is then some later one whose output is no longer
adjacent to its command. yes writes through a pipe failed this way while
y/y were plainly correct in the transcript. Treat a single FAIL in
-Fb -Tty -Usb -Sock -Evdev -Ps as suspect until the transcript is read.
Leaked QEMU made this worse and is now fixed (commit 4e0478c): the
finally cannot run when the script is killed, so QEMU outlived it and, under
TCG, taxed every later run. Each run now records its pid and reaps the previous
one's orphan.
Measuring anything about guest speed
Do not use host wall clock, and do not compare runs made minutes apart. Three confounds each produced a confident wrong answer in one session:
- Stray QEMU pinning a core (see above).
build/schfs.imgages — it accumulates writes across boots. Delete andmake build/schfs.imgbefore every timed boot.- Ordering / host drift — alternate the variants and run each twice.
Time it from inside: cat /proc/uptime either side of the command. The guest's
tick does not care what the host is doing. See schunix-verify-by-driving-shell.