Orderly shutdown: init's stop cascade into ring-3 S5 (M21.3)

The capstone. init becomes a real supervisor: it spawns its boot
services supervised against one endpoint that also carries its signals, a
re-arming heartbeat timer, and the power events it subscribes to. On the
power button (or a terminate signal — same path) it logs the shutdown,
runs the M17 stop sequence over its children in reverse spawn order
(vfs last), then asks the power service for S5.

The acpi service honors a shutdown request from a power subscriber — init
is the one subscriber, a soft gate that stands in for 'only the system
supervisor may power off' and, unlike a PID-1 check, survives the test
harness where the kernel's idle tasks take the early ids. The power
service is mechanism (write S5); deciding when to shut down and stopping
everything else first is init's policy — the microkernel split applied to
poweroff.

The orderly-shutdown scenario injects a real QMP power-button event and
watches the whole chain compose: button pressed -> init shutting down ->
entering S5 -> QEMU powers off. That single scenario proves the M17
lifecycle and the M21 event side compose into a clean shutdown. Suite
60/60.
This commit is contained in:
Daniel Samson
2026-07-13 05:56:58 +01:00
parent 767a2a9a7c
commit a785efa4a3
5 changed files with 164 additions and 24 deletions
+9 -8
View File
@@ -92,14 +92,15 @@ auto-merge to main when the branch is green; keep the branch; push everything.
Host unit test with hand-encoded AML proves the queue; aml.zig joined the
`zig build test` loop. QEMU raises no GPEs — suite is regression net,
59/59).
- [ ] **M21.3** — orderly shutdown: init keeps child ids (spawnSupervised +
exit endpoint), binds signals, subscribes to `.power`; on `power_button`
logs `init: shutting down`, runs `stop(child, 2000, endpoint)` in
reverse spawn order, then sends `shutdown` to `.power`; the acpi service
(sender PID 1 only) logs `power: entering S5` and writes SLP_TYP|SLP_EN
from ring 3. Scenario `orderly-shutdown`: boot via init, `qmp_after
system_powerdown`, ordered regex button→shutting-down→entering-S5, pass
on QEMU exit. Docs + memory updated.
- [x] **M21.3** — orderly shutdown (init supervises its children on one
endpoint that also carries signals, power events, and a re-arming
heartbeat timer; on `power_button` or a `terminate` signal it logs
`init: shutting down`, runs `stop(child, 2000, endpoint)` in reverse
order, then requests `.power` shutdown; the acpi service honors shutdown
from a subscriber — init is the one subscriber, a soft gate that survives
testing where PID 1 isn't init — and writes SLP_TYP|SLP_EN from ring 3.
`orderly-shutdown` scenario proves button → shutting-down → S5 → QEMU
exit; suite 60/60).
- [ ] **merge** `feat/power-events` → main, push, keep the branch — **loop
ends here**.