]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/emergency-action.c
Add SPDX license identifiers to source files under the LGPL
[thirdparty/systemd.git] / src / core / emergency-action.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
2928b0a8
LP
2/***
3 This file is part of systemd.
4
5 Copyright 2014 Lennart Poettering
6 Copyright 2012 Michael Olbrich
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
22#include <sys/reboot.h>
23#include <linux/reboot.h>
2928b0a8 24
2928b0a8 25#include "bus-error.h"
8b43440b 26#include "bus-util.h"
87a47f99 27#include "emergency-action.h"
8b43440b
LP
28#include "special.h"
29#include "string-table.h"
288a74cc 30#include "terminal-util.h"
2928b0a8 31
87a47f99
LN
32static void log_and_status(Manager *m, const char *message, const char *reason) {
33 log_warning("%s: %s", message, reason);
ebc5788e 34 manager_status_printf(m, STATUS_TYPE_EMERGENCY,
9b9881d7 35 ANSI_HIGHLIGHT_RED " !! " ANSI_NORMAL,
87a47f99 36 "%s: %s", message, reason);
ebc5788e
ZJS
37}
38
87a47f99 39int emergency_action(
2928b0a8 40 Manager *m,
87a47f99
LN
41 EmergencyAction action,
42 const char *reboot_arg,
43 const char *reason) {
2928b0a8 44
2928b0a8
LP
45 assert(m);
46 assert(action >= 0);
87a47f99 47 assert(action < _EMERGENCY_ACTION_MAX);
2928b0a8 48
87a47f99 49 if (action == EMERGENCY_ACTION_NONE)
f07756bf 50 return -ECANCELED;
2928b0a8 51
463d0d15 52 if (!MANAGER_IS_SYSTEM(m)) {
f07756bf
LP
53 /* Downgrade all options to simply exiting if we run
54 * in user mode */
55
87a47f99 56 log_warning("Exiting: %s", reason);
f07756bf
LP
57 m->exit_code = MANAGER_EXIT;
58 return -ECANCELED;
59 }
60
61 switch (action) {
2928b0a8 62
87a47f99
LN
63 case EMERGENCY_ACTION_REBOOT:
64 log_and_status(m, "Rebooting", reason);
2928b0a8 65
27c06cb5
LP
66 (void) update_reboot_parameter_and_warn(reboot_arg);
67 (void) manager_add_job_by_name_and_warn(m, JOB_START, SPECIAL_REBOOT_TARGET, JOB_REPLACE_IRREVERSIBLY, NULL);
2928b0a8
LP
68
69 break;
2928b0a8 70
87a47f99
LN
71 case EMERGENCY_ACTION_REBOOT_FORCE:
72 log_and_status(m, "Forcibly rebooting", reason);
ebc5788e 73
27c06cb5 74 (void) update_reboot_parameter_and_warn(reboot_arg);
2928b0a8 75 m->exit_code = MANAGER_REBOOT;
27c06cb5 76
2928b0a8
LP
77 break;
78
87a47f99
LN
79 case EMERGENCY_ACTION_REBOOT_IMMEDIATE:
80 log_and_status(m, "Rebooting immediately", reason);
2928b0a8
LP
81
82 sync();
83
27c06cb5 84 if (!isempty(reboot_arg)) {
2928b0a8
LP
85 log_info("Rebooting with argument '%s'.", reboot_arg);
86 syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_RESTART2, reboot_arg);
27c06cb5 87 log_warning_errno(errno, "Failed to reboot with parameter, retrying without: %m");
2928b0a8
LP
88 }
89
90 log_info("Rebooting.");
91 reboot(RB_AUTOBOOT);
92 break;
93
87a47f99
LN
94 case EMERGENCY_ACTION_POWEROFF:
95 log_and_status(m, "Powering off", reason);
27c06cb5 96 (void) manager_add_job_by_name_and_warn(m, JOB_START, SPECIAL_POWEROFF_TARGET, JOB_REPLACE_IRREVERSIBLY, NULL);
f07756bf 97 break;
f07756bf 98
87a47f99
LN
99 case EMERGENCY_ACTION_POWEROFF_FORCE:
100 log_and_status(m, "Forcibly powering off", reason);
f07756bf
LP
101 m->exit_code = MANAGER_POWEROFF;
102 break;
103
87a47f99
LN
104 case EMERGENCY_ACTION_POWEROFF_IMMEDIATE:
105 log_and_status(m, "Powering off immediately", reason);
f07756bf
LP
106
107 sync();
108
109 log_info("Powering off.");
110 reboot(RB_POWER_OFF);
111 break;
112
2928b0a8 113 default:
87a47f99 114 assert_not_reached("Unknown emergency action");
2928b0a8
LP
115 }
116
117 return -ECANCELED;
118}
119
87a47f99
LN
120static const char* const emergency_action_table[_EMERGENCY_ACTION_MAX] = {
121 [EMERGENCY_ACTION_NONE] = "none",
122 [EMERGENCY_ACTION_REBOOT] = "reboot",
123 [EMERGENCY_ACTION_REBOOT_FORCE] = "reboot-force",
124 [EMERGENCY_ACTION_REBOOT_IMMEDIATE] = "reboot-immediate",
125 [EMERGENCY_ACTION_POWEROFF] = "poweroff",
126 [EMERGENCY_ACTION_POWEROFF_FORCE] = "poweroff-force",
127 [EMERGENCY_ACTION_POWEROFF_IMMEDIATE] = "poweroff-immediate"
2928b0a8 128};
87a47f99 129DEFINE_STRING_TABLE_LOOKUP(emergency_action, EmergencyAction);