Skip to content

QEMU/RouterOS: post-clean() relaunch leaves www nonresponsive on linux-arm64 (7.21.5) #79

Description

@mobileskyfi

Status 2026-07-31 — the symptom is fixed; the mechanism is not explained. B9 of #110 bisected this cleanly to #111 (the console-reader sentinel framing). What remains, and all this issue now tracks, is why a host-side console-reader defect wedged a guest service. Demoted to P3 research: nothing is failing, but an unexplained fix is a fix that can come back.

What was happening

start-stop.test.tsclean() resets disk to factory defaults reached a healthy post-reset RouterOS 7.21.5 guest on linux-arm64, but REST never became ready during the 480 s boot envelope.

The #101/#105/#107 forensics localized it precisely:

  • QEMU stays alive and the serial console answers quickly;
  • DHCP has 10.0.2.15, uptime reaches 8+ minutes, no firewall filter rules;
  • ssh, API, API-SSL and WinBox are served;
  • HTTPS/443 cleanly refuses, proving the guest TCP stack can answer;
  • only HTTP/80 black-holes;
  • conntrack proves the forwarded SYNs reach RouterOS and receive no reply;
  • all 96 REST probes time out and zero HTTP requests complete.

A guest-side, service-specific www failure after clean() — not a generic boot, DHCP, slirp, hostfwd, or firewall failure.

The bisect (B9 of #110)

Holding RouterOS 7.21.5 (pinned by version, not channel), arm64, TCG and the test constant, and varying only the system emulator, QEMU 8.2.2 → 11.0.2 moved the failing test by ~1 second (81.9/83.4/75.1 s vs 82.5 s). The QEMU/virtio hypothesis below is dead: the "every observed failure ran 8.2.2" correlation was confounded by code state, because every observed failure also ran pre-#111 code.

The baseline did not reproduce on current code, so B9 bisected code state instead:

ref code state clean() test
9ce1932 pre-#111, pre-#112 fail 543.0 s / fail 544.5 s
2808143 #111 in, #112 out pass 79.9 s / pass 79.8 s
HEAD both in pass ×3

Old code 4/4 fail, new code 7/7 pass, on current runner images. Both 9ce1932 failures reproduce this issue byte-identically — 96 probes [probe-timeout=96], BOOT_TIMEOUT at 478 s. So it was deterministic all along, and #111 fixed it. #112 was right to disclaim it: 2808143 has #111 but not #112 and already passes.

Full result: #79 (comment)

The open question

Why does correcting a host-side console reader fix a guest-side www black hole?

Until that is answered, #111 is a fix by coincidence as far as this issue is concerned, and any future change to console reply framing could reintroduce this without anyone connecting the two.

Hypothesis A — the clean()/provisioning sequence silently mis-executed

Pre-#111, waitForFinalPrompt could end a read on a prompt redraw and hand back a truncated or empty payload for a large reply. The test provisions over the serial console before the clean(). If a command in that sequence was believed to have run — or its reply was parsed into a wrong branch — the guest could be left with www disabled, bound elsewhere, or otherwise not serving, while every other service is untouched.

This fits the evidence best. It is the only hypothesis on the table that explains why exactly one service failed while ssh/API/WinBox stayed up, HTTPS refused cleanly, and the guest was otherwise healthy for 8+ minutes.

Hypothesis B — serial chardev backpressure

Raised in the B9 comment: consoleExec sessions persist across calls (console.ts:290) and the serial chardev is a server socket, so a client that connects and stops draining blocks QEMU's chardev write and can stall the guest. That would explain a SYN-accepted-but-never-answered signature and the empty console reply forensic.

It does not fit the selective failure. A stalled guest does not keep serving ssh, API, API-SSL and WinBox, and does not cleanly RST on 443. Backpressure is a real hazard worth knowing about — it is reachable from any future code that attaches to serial and stops reading — but as an explanation for this wedge it is contradicted by the host-side port probes, which do not depend on the console at all.

The experiment that discriminates them

Cheap, and the repro is known-good: reproduce the wedge on 9ce1932 (4/4 today), then query the wedged guest over ssh, not serial — ssh is unaffected by the console-reader defect and was demonstrably being served throughout.

# on a wedged pre-#111 guest
/ip/service/print detail        # is www disabled / bound to a different address?
/log/print where topics~"web"
/system/resource/print
  • www disabled, misbound, or absent → Hypothesis A, and the follow-up is which command in the provisioning/clean() sequence mis-executed under a truncated reply.
  • www enabled, listening, on the right address, and still not answering → A is out; look harder at B or at a RouterOS www state bug after factory reset, and note that the console reader would then be affecting the guest through a path nobody has identified.

Everything else stays constant: same ref, same 7.21.5, arm64, TCG, same test.

Corrections to earlier hypotheses (kept so they are not re-derived)

Done-when

  • The mechanism connecting the console-reader defect to the www black hole is identified, or the discriminating experiment above returns a documented negative and this issue closes as "symptom fixed, mechanism not reproducible on current code".
  • The durable RouterOS/QEMU fact — including a negative — is recorded in the governing lab/design/instruction doc, not only in this issue.
  • If Hypothesis B survives at all, serial-chardev backpressure is written down where the next person attaching to serial will see it (qemu.instructions.md), independent of whether it caused this.

No regression test is owed here: #111 shipped the anchor test that keeps the reader honest, and B9's bisect is the regression evidence for this symptom.

Tracked in Wave 2 of #110 (B9, done). Correlated with #69 but not merged — see #69's own mechanism boundary. Historical evidence remains in the comments.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3research / investigation — needs grounding firstarea:ciCI workflows, publish, verification matrixarea:qemuQEMU/CHR boot, virtio, acceleration, channelsbugSomething isn't workingresearchproduces a repro / REPORT.md / grounding doc

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions