'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
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
<term><varname>systemd.dump_core</varname></term>
<term><varname>systemd.crash_chvt</varname></term>
<term><varname>systemd.crash_shell</varname></term>
- <term><varname>systemd.crash_reboot</varname></term>
+ <term><varname>systemd.crash_action=</varname></term>
<term><varname>systemd.confirm_spawn</varname></term>
<term><varname>systemd.service_watchdogs</varname></term>
<term><varname>systemd.show_status</varname></term>
<term><varname>DumpCore=yes</varname></term>
<term><varname>CrashChangeVT=no</varname></term>
<term><varname>CrashShell=no</varname></term>
- <term><varname>CrashReboot=no</varname></term>
+ <term><varname>CrashAction=freeze</varname></term>
<term><varname>ShowStatus=yes</varname></term>
<term><varname>DefaultStandardOutput=journal</varname></term>
<term><varname>DefaultStandardError=inherit</varname></term>
</varlistentry>
<varlistentry>
- <term><varname>systemd.crash_reboot</varname></term>
+ <term><varname>systemd.crash_action=</varname></term>
- <listitem><para>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 <varname>systemd.crash_shell</varname>, the
- system is rebooted after the shell exits.</para>
+ <listitem><para>Takes one of <literal>freeze</literal>, <literal>reboot</literal> or
+ <literal>poweroff</literal>. Defaults to <literal>freeze</literal>. If set to
+ <literal>freeze</literal>, the system will hang indefinitely when the system manager (PID 1) crashes.
+ If set to <literal>reboot</literal>, the system manager (PID 1) will reboot the machine automatically
+ when it crashes, after a 10s delay. If set to <literal>poweroff</literal>, the system manager (PID 1)
+ will power off the machine immediately when it crashes. If combined with
+ <varname>systemd.crash_shell</varname>, the configured crash action is executed after the shell
+ exits.</para>
- <xi:include href="version-info.xml" xpointer="v227"/></listitem>
+ <xi:include href="version-info.xml" xpointer="v256"/></listitem>
</varlistentry>
<varlistentry>
</varlistentry>
<varlistentry>
- <term><option>--crash-reboot</option></term>
+ <term><option>--crash-action=</option></term>
- <listitem><para>Automatically reboot the system on crash. This switch has no effect when running as
- user instance. See <varname>systemd.crash_reboot</varname> above.</para>
+ <listitem><para>Specify what to do when the system manager (PID 1) crashes. This switch has no
+ effect when systemd is running as user instance. See <varname>systemd.crash_action=</varname>
+ above.</para>
- <xi:include href="version-info.xml" xpointer="v227"/></listitem>
+ <xi:include href="version-info.xml" xpointer="v256"/></listitem>
</varlistentry>
<varlistentry>
ARG_CRASH_CHVT, \
ARG_CRASH_SHELL, \
ARG_CRASH_REBOOT, \
+ ARG_CRASH_ACTION, \
ARG_CONFIRM_SPAWN, \
ARG_SHOW_STATUS, \
ARG_DESERIALIZE, \
{ "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 }, \
_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);
#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"
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;
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;
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;
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 },
{ "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 },
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:
" --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"
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;
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
+#include <errno.h>
#include <stdbool.h>
+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;
#ShowStatus=yes
#CrashChangeVT=no
#CrashShell=no
-#CrashReboot=no
+#CrashAction=freeze
#CtrlAltDelBurstAction=reboot-force
#CPUAffinity=
#NUMAPolicy=default
CapabilityBoundingSet=
CrashChangeVT=
CrashReboot=
+CrashAction=
CrashShell=
CtrlAltDelBurstAction=
DefaultBlockIOAccounting=