diff options
-rw-r--r-- | man/systemd-system.conf.xml | 9 | ||||
-rw-r--r-- | src/core/dbus-manager.c | 1 | ||||
-rw-r--r-- | src/core/main.c | 21 | ||||
-rw-r--r-- | src/core/manager.h | 1 | ||||
-rw-r--r-- | src/core/system.conf.in | 1 | ||||
-rw-r--r-- | test/fuzz/fuzz-unit-file/directives.service | 1 |
6 files changed, 27 insertions, 7 deletions
diff --git a/man/systemd-system.conf.xml b/man/systemd-system.conf.xml index 5b80479a0a..4dd4bf0ca8 100644 --- a/man/systemd-system.conf.xml +++ b/man/systemd-system.conf.xml @@ -128,6 +128,7 @@ <varlistentry> <term><varname>RuntimeWatchdogSec=</varname></term> <term><varname>ShutdownWatchdogSec=</varname></term> + <term><varname>KExecWatchdogSec=</varname></term> <listitem><para>Configure the hardware watchdog at runtime and at reboot. Takes a timeout value in seconds (or in other time units if suffixed with <literal>ms</literal>, <literal>min</literal>, <literal>h</literal>, @@ -149,7 +150,13 @@ phase of system shutdown, configure <varname>JobTimeoutSec=</varname> and <varname>JobTimeoutAction=</varname> in the <literal>[Unit]</literal> section of the <filename>shutdown.target</filename> unit. By default <varname>RuntimeWatchdogSec=</varname> defaults to 0 (off), and <varname>ShutdownWatchdogSec=</varname> to - 10min. These settings have no effect if a hardware watchdog is not available.</para></listitem> + 10min. <varname>KExecWatchdogSec=</varname> may be used to additionally enable the watchdog when kexec + is being executed rather than when rebooting. Note that if the kernel does not reset the watchdog on kexec (depending + on the specific hardware and/or driver), in this case the watchdog might not get disabled after kexec succeeds + and thus the system might get rebooted, unless <varname>RuntimeWatchdogSec=</varname> is also enabled at the same time. + For this reason it is recommended to enable <varname>KExecWatchdogSec=</varname> only if + <varname>RuntimeWatchdogSec=</varname> is also enabled. + These settings have no effect if a hardware watchdog is not available.</para></listitem> </varlistentry> <varlistentry> diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c index 9fb3ed516a..e70c1e132a 100644 --- a/src/core/dbus-manager.c +++ b/src/core/dbus-manager.c @@ -2410,6 +2410,7 @@ const sd_bus_vtable bus_manager_vtable[] = { SD_BUS_PROPERTY("DefaultStandardError", "s", bus_property_get_exec_output, offsetof(Manager, default_std_output), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_WRITABLE_PROPERTY("RuntimeWatchdogUSec", "t", bus_property_get_usec, property_set_runtime_watchdog, offsetof(Manager, runtime_watchdog), 0), SD_BUS_WRITABLE_PROPERTY("ShutdownWatchdogUSec", "t", bus_property_get_usec, bus_property_set_usec, offsetof(Manager, shutdown_watchdog), 0), + SD_BUS_WRITABLE_PROPERTY("KExecWatchdogUSec", "t", bus_property_get_usec, bus_property_set_usec, offsetof(Manager, kexec_watchdog), 0), SD_BUS_WRITABLE_PROPERTY("ServiceWatchdogs", "b", bus_property_get_bool, bus_property_set_bool, offsetof(Manager, service_watchdogs), 0), SD_BUS_PROPERTY("ControlGroup", "s", NULL, offsetof(Manager, cgroup_root), 0), SD_BUS_PROPERTY("SystemState", "s", property_get_system_state, 0, 0), diff --git a/src/core/main.c b/src/core/main.c index 8de3d4753d..ccfa22c814 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -122,6 +122,7 @@ static usec_t arg_default_start_limit_interval; static unsigned arg_default_start_limit_burst; static usec_t arg_runtime_watchdog; static usec_t arg_shutdown_watchdog; +static usec_t arg_kexec_watchdog; static char *arg_early_core_pattern; static char *arg_watchdog_device; static char **arg_default_environment; @@ -555,6 +556,7 @@ static int parse_config_file(void) { { "Manager", "JoinControllers", config_parse_warn_compat, DISABLED_CONFIGURATION, NULL }, { "Manager", "RuntimeWatchdogSec", config_parse_sec, 0, &arg_runtime_watchdog }, { "Manager", "ShutdownWatchdogSec", config_parse_sec, 0, &arg_shutdown_watchdog }, + { "Manager", "KExecWatchdogSec", config_parse_sec, 0, &arg_kexec_watchdog }, { "Manager", "WatchdogDevice", config_parse_path, 0, &arg_watchdog_device }, { "Manager", "CapabilityBoundingSet", config_parse_capability_set, 0, &arg_capability_bounding_set }, { "Manager", "NoNewPrivileges", config_parse_bool, 0, &arg_no_new_privs }, @@ -674,6 +676,7 @@ static void set_manager_settings(Manager *m) { m->service_watchdogs = arg_service_watchdogs; m->runtime_watchdog = arg_runtime_watchdog; m->shutdown_watchdog = arg_shutdown_watchdog; + m->kexec_watchdog = arg_kexec_watchdog; m->cad_burst_action = arg_cad_burst_action; manager_set_show_status(m, arg_show_status); @@ -1356,6 +1359,7 @@ static int become_shutdown( _cleanup_strv_free_ char **env_block = NULL; size_t pos = 7; int r; + usec_t watchdog_timer = 0; assert(shutdown_verb); assert(!command_line[pos]); @@ -1396,20 +1400,23 @@ static int become_shutdown( assert(pos < ELEMENTSOF(command_line)); - if (STR_IN_SET(shutdown_verb, "reboot", "kexec") && - arg_shutdown_watchdog > 0 && - arg_shutdown_watchdog != USEC_INFINITY) { + if (streq(shutdown_verb, "reboot")) + watchdog_timer = arg_shutdown_watchdog; + else if (streq(shutdown_verb, "kexec")) + watchdog_timer = arg_kexec_watchdog; + + if (watchdog_timer > 0 && watchdog_timer != USEC_INFINITY) { char *e; - /* If we reboot let's set the shutdown + /* If we reboot or kexec let's set the shutdown * watchdog and tell the shutdown binary to * repeatedly ping it */ - r = watchdog_set_timeout(&arg_shutdown_watchdog); + r = watchdog_set_timeout(&watchdog_timer); watchdog_close(r < 0); /* Tell the binary how often to ping, ignore failure */ - if (asprintf(&e, "WATCHDOG_USEC="USEC_FMT, arg_shutdown_watchdog) > 0) + if (asprintf(&e, "WATCHDOG_USEC="USEC_FMT, watchdog_timer) > 0) (void) strv_consume(&env_block, e); if (arg_watchdog_device && @@ -2100,6 +2107,7 @@ static void reset_arguments(void) { arg_default_start_limit_burst = DEFAULT_START_LIMIT_BURST; arg_runtime_watchdog = 0; arg_shutdown_watchdog = 10 * USEC_PER_MINUTE; + arg_kexec_watchdog = 0; arg_early_core_pattern = NULL; arg_watchdog_device = NULL; @@ -2639,6 +2647,7 @@ finish: if (m) { arg_shutdown_watchdog = m->shutdown_watchdog; + arg_kexec_watchdog = m->kexec_watchdog; m = manager_free(m); } diff --git a/src/core/manager.h b/src/core/manager.h index 9f2b5a0eb0..9600ab5144 100644 --- a/src/core/manager.h +++ b/src/core/manager.h @@ -229,6 +229,7 @@ struct Manager { usec_t runtime_watchdog; usec_t shutdown_watchdog; + usec_t kexec_watchdog; dual_timestamp timestamps[_MANAGER_TIMESTAMP_MAX]; diff --git a/src/core/system.conf.in b/src/core/system.conf.in index 8617ec20aa..af6e5d9f62 100644 --- a/src/core/system.conf.in +++ b/src/core/system.conf.in @@ -27,6 +27,7 @@ #NUMAMask= #RuntimeWatchdogSec=0 #ShutdownWatchdogSec=10min +#KExecWatchdogSec=0 #WatchdogDevice= #CapabilityBoundingSet= #NoNewPrivileges=no diff --git a/test/fuzz/fuzz-unit-file/directives.service b/test/fuzz/fuzz-unit-file/directives.service index 2f59585671..d19610fc55 100644 --- a/test/fuzz/fuzz-unit-file/directives.service +++ b/test/fuzz/fuzz-unit-file/directives.service @@ -703,6 +703,7 @@ LogTarget= RuntimeWatchdogSec= ShowStatus= ShutdownWatchdogSec= +KExecWatchdogSec= SuspendMode= SuspendState= SystemCallArchitectures= |