From f9ea9c7299b9e5a181a7a99990d14ae069609eb1 Mon Sep 17 00:00:00 2001 From: Matt Layher Date: Wed, 8 Jul 2020 21:43:12 -0400 Subject: [PATCH] nixos/systemd: add options for hardware watchdog management --- nixos/modules/system/boot/systemd.nix | 52 +++++++++++++++++++++++++++ nixos/tests/systemd.nix | 22 ++++++++++++ 2 files changed, 74 insertions(+) diff --git a/nixos/modules/system/boot/systemd.nix b/nixos/modules/system/boot/systemd.nix index a8e51fc0901..020cf38ea3f 100644 --- a/nixos/modules/system/boot/systemd.nix +++ b/nixos/modules/system/boot/systemd.nix @@ -818,6 +818,45 @@ in ''; }; + systemd.watchdog.device = mkOption { + type = types.path; + example = "/dev/watchdog"; + description = '' + The path to a hardware watchdog device which will be managed by systemd. + If not specified, systemd will default to /dev/watchdog. + ''; + }; + + systemd.watchdog.runtimeTime = mkOption { + type = types.str; + example = "30s"; + description = '' + The amount of time which can elapse before a watchdog hardware device + will automatically reboot the system. Valid time units include "ms", + "s", "min", "h", "d", and "w". + ''; + }; + + systemd.watchdog.rebootTime = mkOption { + type = types.str; + example = "10m"; + description = '' + The amount of time which can elapse after a reboot has been triggered + before a watchdog hardware device will automatically reboot the system. + Valid time units include "ms", "s", "min", "h", "d", and "w". + ''; + }; + + systemd.watchdog.kexecTime = mkOption { + type = types.str; + example = "10m"; + description = '' + The amount of time which can elapse when kexec is being executed before + a watchdog hardware device will automatically reboot the system. This + option should only be enabled if reloadTime is also enabled. Valid + time units include "ms", "s", "min", "h", "d", and "w". + ''; + }; }; @@ -889,6 +928,19 @@ in DefaultIPAccounting=yes ''} DefaultLimitCORE=infinity + ${optionalString (config.systemd.watchdog.device != "") '' + WatchdogDevice=${config.systemd.watchdog.device} + ''} + ${optionalString (config.systemd.watchdog.runtimeTime != "") '' + RuntimeWatchdogSec=${config.systemd.watchdog.runtimeTime} + ''} + ${optionalString (config.systemd.watchdog.rebootTime != "") '' + RebootWatchdogSec=${config.systemd.watchdog.rebootTime} + ''} + ${optionalString (config.systemd.watchdog.kexecTime != "") '' + KExecWatchdogSec=${config.systemd.watchdog.kexecTime} + ''} + ${config.systemd.extraConfig} ''; diff --git a/nixos/tests/systemd.nix b/nixos/tests/systemd.nix index ca2e36a443e..ce950be4846 100644 --- a/nixos/tests/systemd.nix +++ b/nixos/tests/systemd.nix @@ -50,6 +50,13 @@ import ./make-test-python.nix ({ pkgs, ... }: { fi ''; }; + + systemd.watchdog = { + device = "/dev/watchdog"; + runtimeTime = "30s"; + rebootTime = "10min"; + kexecTime = "5min"; + }; }; testScript = '' @@ -117,5 +124,20 @@ import ./make-test-python.nix ({ pkgs, ... }: { retcode, output = machine.execute("systemctl status testservice1.service") assert retcode in [0, 3] # https://bugs.freedesktop.org/show_bug.cgi?id=77507 assert "CPU:" in output + + # Test systemd is configured to manage a watchdog + with subtest("systemd manages hardware watchdog"): + machine.wait_for_unit("multi-user.target") + + # It seems that the device's path doesn't appear in 'systemctl show' so + # check it separately. + assert "WatchdogDevice=/dev/watchdog" in machine.succeed( + "cat /etc/systemd/system.conf" + ) + + output = machine.succeed("systemctl show | grep Watchdog") + assert "RuntimeWatchdogUSec=30s" in output + assert "RebootWatchdogUSec=10m" in output + assert "KExecWatchdogUSec=5m" in output ''; })