7.0 KiB
M10 shutdown validation
Development reference and historical context. For current operating instructions, use the user manual. Acceptance applies only to the source and artifacts identified in each record.
Shutdown usage · Implementation ledger
M10 software acceptance passed on 2026-09-21 in isolated ARM virtual machines. The complete shutdown suite, CLI packaging and earlier-milestone regressions passed. Physical Pi timing, flash-controller durability, power rails and battery behavior remain deferred.
Verified shutdown behavior
The ordinary FDS user can request fds poweroff or fds reboot. New cartridge
operations freeze before the daemon stops the desktop, managed programs and
networking. The original DATA filesystem descriptor checks writeback, the
filesystem becomes read-only, a second check catches remount writeback, and normal
unmount completes before native s6 stops the remaining services and halts or
reboots. Dasung remains supervised until that final service stop.
make power-test passed all six cases in out/m10-vm.tituqzh7/:
| Case | Observed result | VM preparation-to-kernel-action time |
|---|---|---|
| Idle | Ordinary-user poweroff; unprivileged internal hook refused | 540.733 ms |
| Active workload | GUI, DHCP and TERM-ignoring descendants stopped; DATA verified; actual reboot | 1835.329 ms |
| Direct native poweroff | Busy DATA blocks the native hook until resolved; cancellation refused | 414.091 ms |
| Active media preview | Shutdown and new confirmation refused; cancellation leaves disk unchanged | 289.099 ms after retry |
| Crashed DATA service | Same insertion stays quarantined across further restarts; no false SAFE | 281.307 ms after removing fixture |
| Attached-device writeback error | Real EIO retained across restarts; SAFE and shutdown refused | 344.777 ms after removing fixture |
These are measurements inside generic QEMU with the Pi kernel, not Pi or physical power-off benchmarks. They do not establish the sub-second idle or 1.5-second normal-DATA hardware targets. The workload deliberately ignores TERM, so the manager must wait its bounded termination deadline and confirm actual exit before proceeding.
Each case records ordered CLOCK_BOOTTIME events and captures the final native
shutdown record. The test waits for the kernel's halt/reboot message and QEMU's
successful exit; closing the emulator does not count as a completed shutdown.
The full command log is out/logs/m10-final-power.log.
DATA integrity and failure handling
The workload writes at least 128 MiB through a rotating 64 MiB file. After reboot,
independent host e2fsck finds a clean filesystem, SHA-256 matches all 64 MiB, and
an ordinary-user marker retains its exact contents. Open writable descriptors
and a shell working directory both block shutdown. Explicit resume enables new
operations but does not recreate stopped jobs.
Before writable activation, a root-private insertion record is created under
/run/fds/data-sessions. A service crash cannot discard the original descriptor's
writeback history and then issue SAFE based on a fresh descriptor. The same
insertion becomes read-only and quarantined; a known error retains its diagnostic.
Records survive service restarts during this boot, not power loss or a different
insertion. The separate DATA regression passed in out/m7-vm.vmhkmyqk/.
The writeback test uses QEMU's blkdebug to return persistent EIO for writes to a
known allocated file block. GPT, manifest and journal metadata remain outside
that injected sector. The device stays attached; Linux reports a real writeback
error and syncfs fails. The daemon refuses eject, keeps the fault after restart,
and blocks shutdown through another restart. No filesystem-cleanliness claim is
made for this deliberately damaged image. Removing the test fixture merely lets
the remaining system shut down; it never turns the failed insertion SAFE.
See QEMU's fault-injection documentation. A one-shot fault is insufficient evidence by itself because the guest may retry it successfully; the acceptance case verifies the actual guest-visible EIO.
Native guard and dependencies
The native shutdown hook remains alive while preparation is blocked, including
when an administrator calls the upstream poweroff directly. A nonzero hook
exit would let native shutdown continue, so watcher failure uses a blocked
signal wait. Normal waiting uses inotify and process/cgroup exit events, with no
sleep-based assumptions. Once native shutdown starts it cannot be cancelled.
fds-power is a static alias of fds. The CLI now directly declares the already
locked libc crate for inotify, identity and signal operations. No new external
crate or target package is introduced. fds-init explicitly depends on
fds-cartridged, since the native hook requires its DATA checks. DHCP and its
privilege-separated children now share a managed cgroup. The final native grace
period is zero after managed exits and DATA verification have completed.
Regression evidence
The development archive passed rootfs rejection checks, native PID 1/service
control and actual poweroff, desktop/network transitions, tooling/static-ELF
checks and make check. Logs are out/logs/m10-final-*.log; desktop evidence is
out/m8-vm.1c20rcpb/, native init is out/m2-vm.5ARJNL/. The final CLI image also passed native init (out/m2-vm.ysuhZ5/), all nine
stage0 cases (out/m4-vm.e3SBsX/), and the ordinary-user console checks
(out/m5-vm.4l796uhp/). Cartridge regression passed in out/m6-vm.p7gfwnj2/, DATA regression in
out/m7-vm.82fqc9wa/, and confirmed media writes in out/m9-vm.5a58kou6/.
The development runtime tested here is out/rootfs-build.WEtGnr/, with
191 packages and 1406 AArch64 ELF files. Its rootfs SHA-256 is
9de03100b998cac2a754fc8e05acbad0bd3f45846dd637ba4c597ea3ba61f5bb.
Its SYSTEM is out/system-build.dd3e74_2/system.img, SHA-256
bef3b01bc8bc68ca673aa6a0ec73892ddaa2901864eed204745749915ee34b18.
The subsequent explicit init-to-cartridge package dependency was verified in the
final CLI build; the development archive already includes that daemon through
its base package. Runtime binaries and service behavior are identical.
The CLI archive has 180 packages and 1394 AArch64 ELF files, and is 499527680 bytes.
Kernel-to-console was 1821.039788 ms versus M9's 1854.858231 ms: −33.818443 ms.
The actual ARM comparison passed without a regression exception; see
out/logs/m10-boot-comparison.log. This is a VM observation, not a Pi target result.
| Artifact | Location | SHA-256 |
|---|---|---|
| CLI rootfs | out/rootfs-build.0AzReg/rootfs-aarch64.tar |
ebfc58171aeee6f737c2a93a0f3a318d4f02eb915edb3b5a3cf0f51848863930 |
| CLI SYSTEM | out/system-build.c7q19iil/system.img |
81dc8083777b497f02a290a15eeb246465689d0deaff97d761aeb882d140b44b |
| FAT32 boot partition | out/boot-build.42abbf_h/boot.fat |
0972b5973d1fefc377ec4c800043fb8e4aa3013140f95218cdebcf38dcd22a49 |