1{ config, lib, pkgs, ... }:
2
3with lib;
4
5let
6 crashdump = config.boot.crashDump;
7
8 kernelParams = concatStringsSep " " crashdump.kernelParams;
9
10in
11###### interface
12{
13 options = {
14 boot = {
15 crashDump = {
16 enable = mkOption {
17 type = types.bool;
18 default = false;
19 description = ''
20 If enabled, NixOS will set up a kernel that will
21 boot on crash, and leave the user in systemd rescue
22 to be able to save the crashed kernel dump at
23 /proc/vmcore.
24 It also activates the NMI watchdog.
25 '';
26 };
27 reservedMemory = mkOption {
28 default = "128M";
29 description = ''
30 The amount of memory reserved for the crashdump kernel.
31 If you choose a too high value, dmesg will mention
32 "crashkernel reservation failed".
33 '';
34 };
35 kernelParams = mkOption {
36 type = types.listOf types.str;
37 default = [ "1" "boot.shell_on_fail" ];
38 description = ''
39 Parameters that will be passed to the kernel kexec-ed on crash.
40 '';
41 };
42 };
43 };
44 };
45
46###### implementation
47
48 config = mkIf crashdump.enable {
49 boot = {
50 postBootCommands = ''
51 echo "loading crashdump kernel...";
52 ${pkgs.kexectools}/sbin/kexec -p /run/current-system/kernel \
53 --initrd=/run/current-system/initrd \
54 --reset-vga --console-vga \
55 --command-line="systemConfig=$(readlink -f /run/current-system) init=$(readlink -f /run/current-system/init) irqpoll maxcpus=1 reset_devices ${kernelParams}"
56 '';
57 kernelParams = [
58 "crashkernel=${crashdump.reservedMemory}"
59 "nmi_watchdog=panic"
60 "softlockup_panic=1"
61 "idle=poll"
62 ];
63 kernelPatches = [ {
64 name = "crashdump-config";
65 patch = null;
66 extraConfig = ''
67 CRASH_DUMP y
68 DEBUG_INFO y
69 PROC_VMCORE y
70 LOCKUP_DETECTOR y
71 HARDLOCKUP_DETECTOR y
72 '';
73 } ];
74 };
75 };
76}