From b95bf9bb1395616314b83439e2d97b3bd8794771 Mon Sep 17 00:00:00 2001 From: andrewthomaslee Date: Fri, 13 Nov 2026 16:07:14 -0600 Subject: [PATCH] Add hostSpec.system.crashDiagnostics: evidence for unexpected crashes A desktop (kamrui-h1) reset itself with a journal that just stopped: no shutdown, no panic, nothing in pstore, only the AMD firmware's "software wrote 0x6 to reset control register 0xCF9" at the next boot. This module makes the next one explain itself: the kernel log tail goes to pstore on every reboot and panic, a hung kernel panics and reboots, systemd feeds the hardware watchdog, journald syncs every 10 s, a sampler logs load/PSI/memory/temperature, and crash-report writes how the previous boot ended at every boot. Co-Authored-By: Claude Opus 5.5 --- documentation/docs/crash-diagnostics.md | 69 +++++++ documentation/flake-module.nix | 1 + .../nixosModules/_crash-diagnostics.sh | 150 ++++++++++++++ .../nixosModules/crash-diagnostics.nix | 195 ++++++++++++++++++ tests/fixtures/nixos.nix | 5 + vm-tests/crash-diagnostics.nix | 60 ++++++ 6 files changed, 480 insertions(+) create mode 100644 documentation/docs/crash-diagnostics.md create mode 100644 flake-parts/nixosModules/_crash-diagnostics.sh create mode 100644 flake-parts/nixosModules/crash-diagnostics.nix create mode 100644 vm-tests/crash-diagnostics.nix diff --git a/documentation/docs/crash-diagnostics.md b/documentation/docs/crash-diagnostics.md new file mode 100644 index 0000000..89104fb --- /dev/null +++ b/documentation/docs/crash-diagnostics.md @@ -0,0 +1,69 @@ +# Crash diagnostics + +`hostSpec.system.crashDiagnostics` makes a machine that crashes, resets +or is killed without a shutdown leave enough evidence to say why. It +was written after a desktop reset itself with a journal that just +stopped: no shutdown, no panic, nothing in pstore, only the AMD +firmware's `software wrote 0x6 to reset control register 0xCF9` at the +next boot. + +```nix +hostSpec.system.crashDiagnostics.enable = true; +``` + +## What it changes + +| Setting | Default | Effect | +|---|---|---| +| `dmesgOnReboot` | `true` | `printk.always_kmsg_dump=1`: the kernel log tail goes to pstore (EFI variables) on every reboot and power-off the kernel performs, not only on a panic. systemd-pstore moves it to `/var/lib/systemd/pstore` at the next boot. | +| `panicOnHang` | `true` | `nmi_watchdog=panic softlockup_panic=1`: a hung kernel panics, so its log reaches pstore. | +| `panicRebootSeconds` | `10` | `kernel.panic`: a panic reboots after 10 s instead of freezing. | +| `panicOnOops` | `false` | `kernel.panic_on_oops`. | +| `watchdogTimeout` | `"60s"` | systemd feeds the hardware watchdog; if it stops for this long, the watchdog resets the machine (AMD firmware then reports a watchdog reset). `null` leaves the watchdog alone. | +| `journalSyncInterval` | `"10s"` | journald `SyncIntervalSec` (5 min by default): less of the journal is lost in a hard reset. | +| `sampler.enable`, `sampler.interval` | `true`, `"30s"` | `crash-sampler` writes load, pressure (PSI), free memory, swap, the hottest sensor and the biggest process to the journal. | +| `keepReports` | `50` | Boot reports kept in `/var/log/crash-diagnostics`. | + +All kernel and journald values are `mkDefault`, so a machine can still +set them itself. + +## Reading the evidence + +At every boot `crash-diagnostics-report.service` writes how the previous +boot ended to `/var/log/crash-diagnostics/