Line data Source code
1 : /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2 :
3 : /***
4 : This file is part of systemd.
5 :
6 : Copyright 2014 Lennart Poettering
7 : Copyright 2012 Michael Olbrich
8 :
9 : systemd is free software; you can redistribute it and/or modify it
10 : under the terms of the GNU Lesser General Public License as published by
11 : the Free Software Foundation; either version 2.1 of the License, or
12 : (at your option) any later version.
13 :
14 : systemd is distributed in the hope that it will be useful, but
15 : WITHOUT ANY WARRANTY; without even the implied warranty of
16 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 : Lesser General Public License for more details.
18 :
19 : You should have received a copy of the GNU Lesser General Public License
20 : along with systemd; If not, see <http://www.gnu.org/licenses/>.
21 : ***/
22 :
23 : #include <sys/reboot.h>
24 : #include <linux/reboot.h>
25 :
26 : #include "bus-util.h"
27 : #include "bus-error.h"
28 : #include "special.h"
29 : #include "failure-action.h"
30 : #include "terminal-util.h"
31 :
32 0 : static void log_and_status(Manager *m, const char *message) {
33 0 : log_warning("%s", message);
34 0 : manager_status_printf(m, STATUS_TYPE_EMERGENCY,
35 : ANSI_HIGHLIGHT_RED_ON " !! " ANSI_HIGHLIGHT_OFF,
36 : "%s", message);
37 0 : }
38 :
39 0 : int failure_action(
40 : Manager *m,
41 : FailureAction action,
42 : const char *reboot_arg) {
43 :
44 : int r;
45 :
46 0 : assert(m);
47 0 : assert(action >= 0);
48 0 : assert(action < _FAILURE_ACTION_MAX);
49 :
50 0 : if (action == FAILURE_ACTION_NONE)
51 0 : return -ECANCELED;
52 :
53 0 : if (m->running_as == MANAGER_USER) {
54 : /* Downgrade all options to simply exiting if we run
55 : * in user mode */
56 :
57 0 : log_warning("Exiting as result of failure.");
58 0 : m->exit_code = MANAGER_EXIT;
59 0 : return -ECANCELED;
60 : }
61 :
62 0 : switch (action) {
63 :
64 : case FAILURE_ACTION_REBOOT: {
65 0 : _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
66 :
67 0 : log_and_status(m, "Rebooting as result of failure.");
68 :
69 0 : update_reboot_param_file(reboot_arg);
70 0 : r = manager_add_job_by_name(m, JOB_START, SPECIAL_REBOOT_TARGET, JOB_REPLACE, true, &error, NULL);
71 0 : if (r < 0)
72 0 : log_error("Failed to reboot: %s.", bus_error_message(&error, r));
73 :
74 0 : break;
75 : }
76 :
77 : case FAILURE_ACTION_REBOOT_FORCE:
78 0 : log_and_status(m, "Forcibly rebooting as result of failure.");
79 :
80 0 : update_reboot_param_file(reboot_arg);
81 0 : m->exit_code = MANAGER_REBOOT;
82 0 : break;
83 :
84 : case FAILURE_ACTION_REBOOT_IMMEDIATE:
85 0 : log_and_status(m, "Rebooting immediately as result of failure.");
86 :
87 0 : sync();
88 :
89 0 : if (reboot_arg) {
90 0 : log_info("Rebooting with argument '%s'.", reboot_arg);
91 0 : syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_RESTART2, reboot_arg);
92 : }
93 :
94 0 : log_info("Rebooting.");
95 0 : reboot(RB_AUTOBOOT);
96 0 : break;
97 :
98 : case FAILURE_ACTION_POWEROFF: {
99 0 : _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
100 :
101 0 : log_and_status(m, "Powering off as result of failure.");
102 :
103 0 : r = manager_add_job_by_name(m, JOB_START, SPECIAL_POWEROFF_TARGET, JOB_REPLACE, true, &error, NULL);
104 0 : if (r < 0)
105 0 : log_error("Failed to poweroff: %s.", bus_error_message(&error, r));
106 :
107 0 : break;
108 : }
109 :
110 : case FAILURE_ACTION_POWEROFF_FORCE:
111 0 : log_and_status(m, "Forcibly powering off as result of failure.");
112 0 : m->exit_code = MANAGER_POWEROFF;
113 0 : break;
114 :
115 : case FAILURE_ACTION_POWEROFF_IMMEDIATE:
116 0 : log_and_status(m, "Powering off immediately as result of failure.");
117 :
118 0 : sync();
119 :
120 0 : log_info("Powering off.");
121 0 : reboot(RB_POWER_OFF);
122 0 : break;
123 :
124 : default:
125 0 : assert_not_reached("Unknown failure action");
126 : }
127 :
128 0 : return -ECANCELED;
129 : }
130 :
131 : static const char* const failure_action_table[_FAILURE_ACTION_MAX] = {
132 : [FAILURE_ACTION_NONE] = "none",
133 : [FAILURE_ACTION_REBOOT] = "reboot",
134 : [FAILURE_ACTION_REBOOT_FORCE] = "reboot-force",
135 : [FAILURE_ACTION_REBOOT_IMMEDIATE] = "reboot-immediate",
136 : [FAILURE_ACTION_POWEROFF] = "poweroff",
137 : [FAILURE_ACTION_POWEROFF_FORCE] = "poweroff-force",
138 : [FAILURE_ACTION_POWEROFF_IMMEDIATE] = "poweroff-immediate"
139 : };
140 18 : DEFINE_STRING_TABLE_LOOKUP(failure_action, FailureAction);
|