]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/core/emergency-action.c
tree-wide: beautify remaining copyright statements
[thirdparty/systemd.git] / src / core / emergency-action.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2 /***
3 Copyright © 2012 Michael Olbrich
4 ***/
5
6 #include <sys/reboot.h>
7
8 #include "bus-error.h"
9 #include "bus-util.h"
10 #include "emergency-action.h"
11 #include "raw-reboot.h"
12 #include "reboot-util.h"
13 #include "special.h"
14 #include "string-table.h"
15 #include "terminal-util.h"
16
17 static void log_and_status(Manager *m, const char *message, const char *reason) {
18 log_warning("%s: %s", message, reason);
19 manager_status_printf(m, STATUS_TYPE_EMERGENCY,
20 ANSI_HIGHLIGHT_RED " !! " ANSI_NORMAL,
21 "%s: %s", message, reason);
22 }
23
24 int emergency_action(
25 Manager *m,
26 EmergencyAction action,
27 const char *reboot_arg,
28 const char *reason) {
29
30 assert(m);
31 assert(action >= 0);
32 assert(action < _EMERGENCY_ACTION_MAX);
33
34 if (action == EMERGENCY_ACTION_NONE)
35 return -ECANCELED;
36
37 if (!m->service_watchdogs) {
38 log_warning("Watchdog disabled! Not acting on: %s", reason);
39 return -ECANCELED;
40 }
41
42 if (!MANAGER_IS_SYSTEM(m)) {
43 /* Downgrade all options to simply exiting if we run
44 * in user mode */
45
46 log_warning("Exiting: %s", reason);
47 m->exit_code = MANAGER_EXIT;
48 return -ECANCELED;
49 }
50
51 switch (action) {
52
53 case EMERGENCY_ACTION_REBOOT:
54 log_and_status(m, "Rebooting", reason);
55
56 (void) update_reboot_parameter_and_warn(reboot_arg);
57 (void) manager_add_job_by_name_and_warn(m, JOB_START, SPECIAL_REBOOT_TARGET, JOB_REPLACE_IRREVERSIBLY, NULL);
58
59 break;
60
61 case EMERGENCY_ACTION_REBOOT_FORCE:
62 log_and_status(m, "Forcibly rebooting", reason);
63
64 (void) update_reboot_parameter_and_warn(reboot_arg);
65 m->exit_code = MANAGER_REBOOT;
66
67 break;
68
69 case EMERGENCY_ACTION_REBOOT_IMMEDIATE:
70 log_and_status(m, "Rebooting immediately", reason);
71
72 sync();
73
74 if (!isempty(reboot_arg)) {
75 log_info("Rebooting with argument '%s'.", reboot_arg);
76 (void) raw_reboot(LINUX_REBOOT_CMD_RESTART2, reboot_arg);
77 log_warning_errno(errno, "Failed to reboot with parameter, retrying without: %m");
78 }
79
80 log_info("Rebooting.");
81 (void) reboot(RB_AUTOBOOT);
82 break;
83
84 case EMERGENCY_ACTION_POWEROFF:
85 log_and_status(m, "Powering off", reason);
86 (void) manager_add_job_by_name_and_warn(m, JOB_START, SPECIAL_POWEROFF_TARGET, JOB_REPLACE_IRREVERSIBLY, NULL);
87 break;
88
89 case EMERGENCY_ACTION_POWEROFF_FORCE:
90 log_and_status(m, "Forcibly powering off", reason);
91 m->exit_code = MANAGER_POWEROFF;
92 break;
93
94 case EMERGENCY_ACTION_POWEROFF_IMMEDIATE:
95 log_and_status(m, "Powering off immediately", reason);
96
97 sync();
98
99 log_info("Powering off.");
100 (void) reboot(RB_POWER_OFF);
101 break;
102
103 default:
104 assert_not_reached("Unknown emergency action");
105 }
106
107 return -ECANCELED;
108 }
109
110 static const char* const emergency_action_table[_EMERGENCY_ACTION_MAX] = {
111 [EMERGENCY_ACTION_NONE] = "none",
112 [EMERGENCY_ACTION_REBOOT] = "reboot",
113 [EMERGENCY_ACTION_REBOOT_FORCE] = "reboot-force",
114 [EMERGENCY_ACTION_REBOOT_IMMEDIATE] = "reboot-immediate",
115 [EMERGENCY_ACTION_POWEROFF] = "poweroff",
116 [EMERGENCY_ACTION_POWEROFF_FORCE] = "poweroff-force",
117 [EMERGENCY_ACTION_POWEROFF_IMMEDIATE] = "poweroff-immediate"
118 };
119 DEFINE_STRING_TABLE_LOOKUP(emergency_action, EmergencyAction);