Skip to content

fix(appliance): narrate the slow image load, and say so on every console when setup stops (#1028) - #1033

Merged
VijitSingh97 merged 2 commits into
develop-v2from
fix/1028-firstboot-progress
Aug 16, 2026
Merged

fix(appliance): narrate the slow image load, and say so on every console when setup stops (#1028)#1033
VijitSingh97 merged 2 commits into
develop-v2from
fix/1028-firstboot-progress

Conversation

@VijitSingh97

Copy link
Copy Markdown
Collaborator

Closes #1028. Stacked on #1032 (fix/1029-readonly-root-install) — merge that first, then retarget this to develop-v2 with gh api -X PATCH repos/p2pool-starter-stack/pithead/pulls/N -f base=develop-v2 (gh pr edit --base is currently throwing GraphQL 502s).

Two halves of one problem: a first boot that is working and a first boot that has died looked identical on the console, and both looked like "still starting".

The silence

podman load prints nothing a console ever sees, and on USB media the step runs for minutes — 3m47s measured on the HP bench — behind a line promising "a minute or two".

That is not hypothetical. It caused a wrong "it's hung" call twice today: once by me from the issue's console photo, and once by the operator watching a box that was in fact healthy and came up 4m13s after boot.

A rising elapsed count is the whole fix — it is the one thing that separates slow from stuck. Every 30s, so a four-minute load costs eight lines.

The heartbeat is the background job; the load stays in the foreground. Backgrounding the load and polling it with kill -0 looks equivalent and is not: a finished-but-unwaited child is a zombie that still answers, so a fast load would pay a full sleep interval for work already done. Keeping the load in front also leaves its exit status untouched.

The failure

error writes to stderr, which systemd routes to /dev/consoleone device, whichever the kernel cmdline named last. On a box whose monitor is not that device, a fatal failure is invisible, so the newest line on screen stays "preparing the setup page" and a stopped box reads as a slow one for as long as the operator is willing to wait.

That is exactly how a three-minute failure was mistaken for an hour of progress in #1029. The wizard's fatal path now says it through _console, which reaches every physical console, and names the command that explains why.

Verification

Gate Result
New unit tests 4 — slow load narrates with elapsed seconds; fast load stays quiet
Regression guard The fast-load test fails if the zombie race is ever reintroduced
make lint 0 errors (shfmt applied)
tests/stack 2320 passed, 0 failed

The heartbeat interval takes a test seam (PITHEAD_LOAD_HEARTBEAT_SECS) so the slow case runs in seconds rather than minutes — same idiom as the other PITHEAD_* seams.

Related: #1030 covers what interrupted the write, and notes that a volatile journal is why none of this was diagnosable after the fact.

…ole when setup stops (#1028)

Two halves of the same problem: a first boot that is working and a first boot that has died
looked identical on the console, and both looked like "still starting".

The load. `podman load` prints nothing a console ever sees, and on USB media the step runs for
minutes — 3m47s measured on the HP bench — behind a line promising "a minute or two". A working
box was read as hung twice, once from the console photo and once live. A rising elapsed count is
the whole fix: it is the one thing that separates slow from stuck. Every 30s, so a four-minute
load costs eight lines.

The heartbeat is the background job and the load stays in the FOREGROUND. Backgrounding the load
and polling it with `kill -0` looks equivalent and is not: a finished-but-unwaited child is a
zombie that still answers, so a fast load would pay a full sleep interval for work already done.
Keeping the load in front also preserves its exit status untouched.

The failure. `error` writes to stderr, which systemd routes to /dev/console — ONE device,
whichever the kernel cmdline named last. On a box whose monitor is not that device a fatal
failure is invisible, so the newest line on screen stays "preparing the setup page" and a stopped
box reads as a slow one for as long as the operator is willing to wait. That is exactly how a
three-minute failure was mistaken for an hour of progress. The wizard's fatal path now says it
through _console, which reaches every physical console, and names the command that explains why.

Four unit tests, including the fast-load case that fails if the zombie race is reintroduced.
The heartbeat interval takes a test seam so the slow case runs in seconds rather than minutes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@VijitSingh97
VijitSingh97 deleted the branch develop-v2 August 16, 2026 18:01
@VijitSingh97 VijitSingh97 reopened this Aug 16, 2026
@VijitSingh97
VijitSingh97 changed the base branch from fix/1029-readonly-root-install to develop-v2 August 16, 2026 18:02
@VijitSingh97
VijitSingh97 merged commit 497985a into develop-v2 Aug 16, 2026
15 checks passed
@VijitSingh97
VijitSingh97 deleted the fix/1028-firstboot-progress branch August 16, 2026 18:20
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