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