1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 This file is part of systemd.
5 Copyright 2014 Lennart Poettering
6 Copyright 2012 Michael Olbrich
9 #include <sys/reboot.h>
11 #include "bus-error.h"
13 #include "emergency-action.h"
14 #include "raw-reboot.h"
15 #include "reboot-util.h"
17 #include "string-table.h"
18 #include "terminal-util.h"
20 static void log_and_status(Manager
*m
, const char *message
, const char *reason
) {
21 log_warning("%s: %s", message
, reason
);
22 manager_status_printf(m
, STATUS_TYPE_EMERGENCY
,
23 ANSI_HIGHLIGHT_RED
" !! " ANSI_NORMAL
,
24 "%s: %s", message
, reason
);
29 EmergencyAction action
,
30 const char *reboot_arg
,
35 assert(action
< _EMERGENCY_ACTION_MAX
);
37 if (action
== EMERGENCY_ACTION_NONE
)
40 if (!m
->service_watchdogs
) {
41 log_warning("Watchdog disabled! Not acting on: %s", reason
);
45 if (!MANAGER_IS_SYSTEM(m
)) {
46 /* Downgrade all options to simply exiting if we run
49 log_warning("Exiting: %s", reason
);
50 m
->exit_code
= MANAGER_EXIT
;
56 case EMERGENCY_ACTION_REBOOT
:
57 log_and_status(m
, "Rebooting", reason
);
59 (void) update_reboot_parameter_and_warn(reboot_arg
);
60 (void) manager_add_job_by_name_and_warn(m
, JOB_START
, SPECIAL_REBOOT_TARGET
, JOB_REPLACE_IRREVERSIBLY
, NULL
);
64 case EMERGENCY_ACTION_REBOOT_FORCE
:
65 log_and_status(m
, "Forcibly rebooting", reason
);
67 (void) update_reboot_parameter_and_warn(reboot_arg
);
68 m
->exit_code
= MANAGER_REBOOT
;
72 case EMERGENCY_ACTION_REBOOT_IMMEDIATE
:
73 log_and_status(m
, "Rebooting immediately", reason
);
77 if (!isempty(reboot_arg
)) {
78 log_info("Rebooting with argument '%s'.", reboot_arg
);
79 (void) raw_reboot(LINUX_REBOOT_CMD_RESTART2
, reboot_arg
);
80 log_warning_errno(errno
, "Failed to reboot with parameter, retrying without: %m");
83 log_info("Rebooting.");
84 (void) reboot(RB_AUTOBOOT
);
87 case EMERGENCY_ACTION_POWEROFF
:
88 log_and_status(m
, "Powering off", reason
);
89 (void) manager_add_job_by_name_and_warn(m
, JOB_START
, SPECIAL_POWEROFF_TARGET
, JOB_REPLACE_IRREVERSIBLY
, NULL
);
92 case EMERGENCY_ACTION_POWEROFF_FORCE
:
93 log_and_status(m
, "Forcibly powering off", reason
);
94 m
->exit_code
= MANAGER_POWEROFF
;
97 case EMERGENCY_ACTION_POWEROFF_IMMEDIATE
:
98 log_and_status(m
, "Powering off immediately", reason
);
102 log_info("Powering off.");
103 (void) reboot(RB_POWER_OFF
);
107 assert_not_reached("Unknown emergency action");
113 static const char* const emergency_action_table
[_EMERGENCY_ACTION_MAX
] = {
114 [EMERGENCY_ACTION_NONE
] = "none",
115 [EMERGENCY_ACTION_REBOOT
] = "reboot",
116 [EMERGENCY_ACTION_REBOOT_FORCE
] = "reboot-force",
117 [EMERGENCY_ACTION_REBOOT_IMMEDIATE
] = "reboot-immediate",
118 [EMERGENCY_ACTION_POWEROFF
] = "poweroff",
119 [EMERGENCY_ACTION_POWEROFF_FORCE
] = "poweroff-force",
120 [EMERGENCY_ACTION_POWEROFF_IMMEDIATE
] = "poweroff-immediate"
122 DEFINE_STRING_TABLE_LOOKUP(emergency_action
, EmergencyAction
);