From: Daan De Meyer Date: Mon, 29 Apr 2024 06:46:58 +0000 (+0200) Subject: core: Add systemd.crash_action= kernel command line argument X-Git-Tag: v256-rc2~165 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7a66f21556512c0bf45b43e6b743cb1079304221;p=thirdparty%2Fsystemd.git core: Add systemd.crash_action= kernel command line argument Required for integration tests to power off on PID 1 crashes. We deprecate systemd.crash_reboot and related options by removing them from the documentation but still parsing them. --- diff --git a/NEWS b/NEWS index 42027a4c8f1..566ee2a9d55 100644 --- a/NEWS +++ b/NEWS @@ -66,6 +66,9 @@ CHANGES WITH 256-rc1: 'D' stanzas. For example, with the combination of 'R /foo' and 'x /foo/bar', /foo/bar will now be excluded from removal. + * systemd.crash_reboot and related settings are deprecated in favor of + systemd.crash_action=. + General Changes and New Features: * Various programs will now attempt to load the main configuration file @@ -251,6 +254,10 @@ CHANGES WITH 256-rc1: that have /usr/bin/ and /usr/sbin/ separate. It's generally recommended to make the latter a symlink to the former these days. + * A new systemd.crash_action= kernel command line option has been added + that configures what to do after the system manager (PID 1) crashes. + This can also be configured through CrashAction= in systemd.conf. + Journal: * systemd-journald can now forward journal entries to a socket diff --git a/man/kernel-command-line.xml b/man/kernel-command-line.xml index 28250a2720b..3dd5449bd06 100644 --- a/man/kernel-command-line.xml +++ b/man/kernel-command-line.xml @@ -54,7 +54,7 @@ systemd.dump_core systemd.crash_chvt systemd.crash_shell - systemd.crash_reboot + systemd.crash_action= systemd.confirm_spawn systemd.service_watchdogs systemd.show_status diff --git a/man/systemd-system.conf.xml b/man/systemd-system.conf.xml index 88f13d05b61..ae5b61b1493 100644 --- a/man/systemd-system.conf.xml +++ b/man/systemd-system.conf.xml @@ -78,7 +78,7 @@ DumpCore=yes CrashChangeVT=no CrashShell=no - CrashReboot=no + CrashAction=freeze ShowStatus=yes DefaultStandardOutput=journal DefaultStandardError=inherit diff --git a/man/systemd.xml b/man/systemd.xml index df0027886c3..66db5bbf250 100644 --- a/man/systemd.xml +++ b/man/systemd.xml @@ -853,16 +853,18 @@ - systemd.crash_reboot + systemd.crash_action= - Takes a boolean argument or enables the option if specified - without an argument. If enabled, the system manager (PID 1) will reboot the - machine automatically when it crashes, after a 10s delay. Otherwise, the - system will hang indefinitely. Defaults to disabled, in order to avoid a - reboot loop. If combined with systemd.crash_shell, the - system is rebooted after the shell exits. + Takes one of freeze, reboot or + poweroff. Defaults to freeze. If set to + freeze, the system will hang indefinitely when the system manager (PID 1) crashes. + If set to reboot, the system manager (PID 1) will reboot the machine automatically + when it crashes, after a 10s delay. If set to poweroff, the system manager (PID 1) + will power off the machine immediately when it crashes. If combined with + systemd.crash_shell, the configured crash action is executed after the shell + exits. - + @@ -1390,12 +1392,13 @@ - + - Automatically reboot the system on crash. This switch has no effect when running as - user instance. See systemd.crash_reboot above. + Specify what to do when the system manager (PID 1) crashes. This switch has no + effect when systemd is running as user instance. See systemd.crash_action= + above. - + diff --git a/src/basic/getopt-defs.h b/src/basic/getopt-defs.h index 3efeb6df80f..9abef6f1566 100644 --- a/src/basic/getopt-defs.h +++ b/src/basic/getopt-defs.h @@ -26,6 +26,7 @@ ARG_CRASH_CHVT, \ ARG_CRASH_SHELL, \ ARG_CRASH_REBOOT, \ + ARG_CRASH_ACTION, \ ARG_CONFIRM_SPAWN, \ ARG_SHOW_STATUS, \ ARG_DESERIALIZE, \ @@ -61,6 +62,7 @@ { "crash-chvt", required_argument, NULL, ARG_CRASH_CHVT }, \ { "crash-shell", optional_argument, NULL, ARG_CRASH_SHELL }, \ { "crash-reboot", optional_argument, NULL, ARG_CRASH_REBOOT }, \ + { "crash-action", required_argument, NULL, ARG_CRASH_ACTION }, \ { "confirm-spawn", optional_argument, NULL, ARG_CONFIRM_SPAWN }, \ { "show-status", optional_argument, NULL, ARG_SHOW_STATUS }, \ { "deserialize", required_argument, NULL, ARG_DESERIALIZE }, \ diff --git a/src/core/crash-handler.c b/src/core/crash-handler.c index f5c31b6b748..4a3fc017fab 100644 --- a/src/core/crash-handler.c +++ b/src/core/crash-handler.c @@ -27,7 +27,13 @@ _noreturn_ void freeze_or_exit_or_reboot(void) { _exit(EXIT_EXCEPTION); } - if (arg_crash_reboot) { + if (arg_crash_action == CRASH_POWEROFF) { + log_notice("Shutting down..."); + (void) reboot(RB_POWER_OFF); + log_struct_errno(LOG_EMERG, errno, + LOG_MESSAGE("Failed to power off: %m"), + "MESSAGE_ID=" SD_MESSAGE_CRASH_FAILED_STR); + } else if (arg_crash_action == CRASH_REBOOT) { log_notice("Rebooting in 10s..."); (void) sleep(10); diff --git a/src/core/main.c b/src/core/main.c index 7362a6a8220..f3a40f65bb8 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -88,6 +88,7 @@ #include "special.h" #include "stat-util.h" #include "stdio-util.h" +#include "string-table.h" #include "strv.h" #include "switch-root.h" #include "sysctl-util.h" @@ -122,7 +123,7 @@ static RuntimeScope arg_runtime_scope; bool arg_dump_core; int arg_crash_chvt; bool arg_crash_shell; -bool arg_crash_reboot; +CrashAction arg_crash_action; static char *arg_confirm_spawn; static ShowStatus arg_show_status; static StatusUnitFormat arg_status_unit_format; @@ -161,6 +162,16 @@ static char **saved_env = NULL; static int parse_configuration(const struct rlimit *saved_rlimit_nofile, const struct rlimit *saved_rlimit_memlock); +static const char* const crash_action_table[_CRASH_ACTION_MAX] = { + [CRASH_FREEZE] = "freeze", + [CRASH_REBOOT] = "reboot", + [CRASH_POWEROFF] = "poweroff", +}; + +DEFINE_STRING_TABLE_LOOKUP(crash_action, CrashAction); + +static DEFINE_CONFIG_PARSE_ENUM_WITH_DEFAULT(config_parse_crash_action, crash_action, CrashAction, CRASH_FREEZE, "Invalid crash action"); + static int manager_find_user_config_paths(char ***ret_files, char ***ret_dirs) { _cleanup_free_ char *base = NULL; _cleanup_strv_free_ char **files = NULL, **dirs = NULL; @@ -279,7 +290,18 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat if (r < 0) log_warning_errno(r, "Failed to parse crash reboot switch %s, ignoring: %m", value); else - arg_crash_reboot = r; + arg_crash_action = r ? CRASH_REBOOT : CRASH_FREEZE; + + } else if (proc_cmdline_key_streq(key, "systemd.crash_action")) { + + if (proc_cmdline_value_missing(key, value)) + return 0; + + r = crash_action_from_string(value); + if (r < 0) + log_warning_errno(r, "Failed to parse crash action switch %s, ignoring: %m", value); + else + arg_crash_action = r; } else if (proc_cmdline_key_streq(key, "systemd.confirm_spawn")) { char *s; @@ -653,6 +675,36 @@ static int config_parse_protect_system_pid1( return 0; } +static int config_parse_crash_reboot( + const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + CrashAction *v = ASSERT_PTR(data); + int r; + + if (isempty(rvalue)) { + *v = CRASH_REBOOT; + return 0; + } + + r = parse_boolean(rvalue); + if (r < 0) { + log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to parse CrashReboot= argument '%s', ignoring: %m", rvalue); + return 0; + } + + *v = r > 0 ? CRASH_REBOOT : CRASH_FREEZE; + return 0; +} + static int parse_config_file(void) { const ConfigTableItem items[] = { { "Manager", "LogLevel", config_parse_level2, 0, NULL }, @@ -664,7 +716,8 @@ static int parse_config_file(void) { { "Manager", "CrashChVT", /* legacy */ config_parse_crash_chvt, 0, &arg_crash_chvt }, { "Manager", "CrashChangeVT", config_parse_crash_chvt, 0, &arg_crash_chvt }, { "Manager", "CrashShell", config_parse_bool, 0, &arg_crash_shell }, - { "Manager", "CrashReboot", config_parse_bool, 0, &arg_crash_reboot }, + { "Manager", "CrashReboot", config_parse_crash_reboot, 0, &arg_crash_action }, + { "Manager", "CrashAction", config_parse_crash_action, 0, &arg_crash_action }, { "Manager", "ShowStatus", config_parse_show_status, 0, &arg_show_status }, { "Manager", "StatusUnitFormat", config_parse_status_unit_format, 0, &arg_status_unit_format }, { "Manager", "CPUAffinity", config_parse_cpu_affinity2, 0, &arg_cpu_affinity }, @@ -980,9 +1033,17 @@ static int parse_argv(int argc, char *argv[]) { break; case ARG_CRASH_REBOOT: - r = parse_boolean_argument("--crash-reboot", optarg, &arg_crash_reboot); + r = parse_boolean_argument("--crash-reboot", optarg, NULL); if (r < 0) return r; + arg_crash_action = r > 0 ? CRASH_REBOOT : CRASH_FREEZE; + break; + + case ARG_CRASH_ACTION: + r = crash_action_from_string(optarg); + if (r < 0) + return log_error_errno(r, "Failed to parse crash action \"%s\": %m", optarg); + arg_crash_action = r; break; case ARG_CONFIRM_SPAWN: @@ -1098,7 +1159,7 @@ static int help(void) { " --unit=UNIT Set default unit\n" " --dump-core[=BOOL] Dump core on crash\n" " --crash-vt=NR Change to specified VT on crash\n" - " --crash-reboot[=BOOL] Reboot on crash\n" + " --crash-action=ACTION Specify what to do on crash\n" " --crash-shell[=BOOL] Run shell on crash\n" " --confirm-spawn[=BOOL] Ask for confirmation when spawning processes\n" " --show-status[=BOOL] Show status updates on the console during boot\n" @@ -2590,7 +2651,7 @@ static void reset_arguments(void) { arg_dump_core = true; arg_crash_chvt = -1; arg_crash_shell = false; - arg_crash_reboot = false; + arg_crash_action = CRASH_FREEZE; arg_confirm_spawn = mfree(arg_confirm_spawn); arg_show_status = _SHOW_STATUS_INVALID; arg_status_unit_format = STATUS_UNIT_FORMAT_DEFAULT; diff --git a/src/core/main.h b/src/core/main.h index b12a1ccfd78..1949a085889 100644 --- a/src/core/main.h +++ b/src/core/main.h @@ -1,9 +1,21 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #pragma once +#include #include +typedef enum CrashAction { + CRASH_FREEZE, + CRASH_REBOOT, + CRASH_POWEROFF, + _CRASH_ACTION_MAX, + _CRASH_ACTION_INVALID = -EINVAL, +} CrashAction; + +const char* crash_action_to_string(CrashAction action); +CrashAction crash_action_from_string(const char *action); + extern bool arg_dump_core; extern int arg_crash_chvt; extern bool arg_crash_shell; -extern bool arg_crash_reboot; +extern CrashAction arg_crash_action; diff --git a/src/core/system.conf.in b/src/core/system.conf.in index 9b89a6aa77d..1c08aa4d22d 100644 --- a/src/core/system.conf.in +++ b/src/core/system.conf.in @@ -26,7 +26,7 @@ #ShowStatus=yes #CrashChangeVT=no #CrashShell=no -#CrashReboot=no +#CrashAction=freeze #CtrlAltDelBurstAction=reboot-force #CPUAffinity= #NUMAPolicy=default diff --git a/test/fuzz/fuzz-unit-file/directives-all.service b/test/fuzz/fuzz-unit-file/directives-all.service index 670e589babe..dbd56ec752f 100644 --- a/test/fuzz/fuzz-unit-file/directives-all.service +++ b/test/fuzz/fuzz-unit-file/directives-all.service @@ -706,6 +706,7 @@ CPUAffinity= CapabilityBoundingSet= CrashChangeVT= CrashReboot= +CrashAction= CrashShell= CtrlAltDelBurstAction= DefaultBlockIOAccounting=