chiark / gitweb /
hwclock: add taint flag for non-local hwclock
[elogind.git] / src / core / shutdown.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2010 ProFUSION embedded systems
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/mman.h>
23 #include <sys/types.h>
24 #include <sys/reboot.h>
25 #include <linux/reboot.h>
26 #include <sys/wait.h>
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <sys/mount.h>
30 #include <sys/syscall.h>
31 #include <fcntl.h>
32 #include <dirent.h>
33 #include <errno.h>
34 #include <unistd.h>
35 #include <signal.h>
36 #include <stdbool.h>
37 #include <stdlib.h>
38 #include <string.h>
39
40 #include "missing.h"
41 #include "log.h"
42 #include "umount.h"
43 #include "util.h"
44 #include "mkdir.h"
45 #include "virt.h"
46 #include "watchdog.h"
47
48 #define TIMEOUT_USEC (5 * USEC_PER_SEC)
49 #define FINALIZE_ATTEMPTS 50
50
51 static bool ignore_proc(pid_t pid) {
52         char buf[PATH_MAX];
53         FILE *f;
54         char c;
55         size_t count;
56         uid_t uid;
57         int r;
58
59         /* We are PID 1, let's not commit suicide */
60         if (pid == 1)
61                 return true;
62
63         r = get_process_uid(pid, &uid);
64         if (r < 0)
65                 return true; /* not really, but better safe than sorry */
66
67         /* Non-root processes otherwise are always subject to be killed */
68         if (uid != 0)
69                 return false;
70
71         snprintf(buf, sizeof(buf), "/proc/%lu/cmdline", (unsigned long) pid);
72         char_array_0(buf);
73
74         f = fopen(buf, "re");
75         if (!f)
76                 return true; /* not really, but has the desired effect */
77
78         count = fread(&c, 1, 1, f);
79         fclose(f);
80
81         /* Kernel threads have an empty cmdline */
82         if (count <= 0)
83                 return true;
84
85         /* Processes with argv[0][0] = '@' we ignore from the killing
86          * spree.
87          *
88          * http://www.freedesktop.org/wiki/Software/systemd/RootStorageDaemons */
89         if (count == 1 && c == '@')
90                 return true;
91
92         return false;
93 }
94
95 static int killall(int sign) {
96         DIR *dir;
97         struct dirent *d;
98         unsigned int n_processes = 0;
99
100         dir = opendir("/proc");
101         if (!dir)
102                 return -errno;
103
104         while ((d = readdir(dir))) {
105                 pid_t pid;
106
107                 if (parse_pid(d->d_name, &pid) < 0)
108                         continue;
109
110                 if (ignore_proc(pid))
111                         continue;
112
113                 if (kill(pid, sign) == 0)
114                         n_processes++;
115                 else
116                         log_warning("Could not kill %d: %m", pid);
117         }
118
119         closedir(dir);
120
121         return n_processes;
122 }
123
124 static void wait_for_children(int n_processes, sigset_t *mask) {
125         usec_t until;
126
127         assert(mask);
128
129         until = now(CLOCK_MONOTONIC) + TIMEOUT_USEC;
130         for (;;) {
131                 struct timespec ts;
132                 int k;
133                 usec_t n;
134
135                 for (;;) {
136                         pid_t pid = waitpid(-1, NULL, WNOHANG);
137
138                         if (pid == 0)
139                                 break;
140
141                         if (pid < 0 && errno == ECHILD)
142                                 return;
143
144                         if (n_processes > 0)
145                                 if (--n_processes == 0)
146                                         return;
147                 }
148
149                 n = now(CLOCK_MONOTONIC);
150                 if (n >= until)
151                         return;
152
153                 timespec_store(&ts, until - n);
154
155                 if ((k = sigtimedwait(mask, NULL, &ts)) != SIGCHLD) {
156
157                         if (k < 0 && errno != EAGAIN) {
158                                 log_error("sigtimedwait() failed: %m");
159                                 return;
160                         }
161
162                         if (k >= 0)
163                                 log_warning("sigtimedwait() returned unexpected signal.");
164                 }
165         }
166 }
167
168 static void send_signal(int sign) {
169         sigset_t mask, oldmask;
170         int n_processes;
171
172         assert_se(sigemptyset(&mask) == 0);
173         assert_se(sigaddset(&mask, SIGCHLD) == 0);
174         assert_se(sigprocmask(SIG_BLOCK, &mask, &oldmask) == 0);
175
176         if (kill(-1, SIGSTOP) < 0 && errno != ESRCH)
177                 log_warning("kill(-1, SIGSTOP) failed: %m");
178
179         n_processes = killall(sign);
180
181         if (kill(-1, SIGCONT) < 0 && errno != ESRCH)
182                 log_warning("kill(-1, SIGCONT) failed: %m");
183
184         if (n_processes <= 0)
185                 goto finish;
186
187         wait_for_children(n_processes, &mask);
188
189 finish:
190         sigprocmask(SIG_SETMASK, &oldmask, NULL);
191 }
192
193 static void ultimate_send_signal(int sign) {
194         sigset_t mask, oldmask;
195         int r;
196
197         assert_se(sigemptyset(&mask) == 0);
198         assert_se(sigaddset(&mask, SIGCHLD) == 0);
199         assert_se(sigprocmask(SIG_BLOCK, &mask, &oldmask) == 0);
200
201         if (kill(-1, SIGSTOP) < 0 && errno != ESRCH)
202                 log_warning("kill(-1, SIGSTOP) failed: %m");
203
204         r = kill(-1, sign);
205         if (r < 0 && errno != ESRCH)
206                 log_warning("kill(-1, %s) failed: %m", signal_to_string(sign));
207
208         if (kill(-1, SIGCONT) < 0 && errno != ESRCH)
209                 log_warning("kill(-1, SIGCONT) failed: %m");
210
211         if (r < 0)
212                 goto finish;
213
214         wait_for_children(0, &mask);
215
216 finish:
217         sigprocmask(SIG_SETMASK, &oldmask, NULL);
218 }
219
220 static int prepare_new_root(void) {
221         static const char dirs[] =
222                 "/run/initramfs/oldroot\0"
223                 "/run/initramfs/proc\0"
224                 "/run/initramfs/sys\0"
225                 "/run/initramfs/dev\0"
226                 "/run/initramfs/run\0";
227
228         const char *dir;
229
230         if (mount("/run/initramfs", "/run/initramfs", NULL, MS_BIND, NULL) < 0) {
231                 log_error("Failed to mount bind /run/initramfs on /run/initramfs: %m");
232                 return -errno;
233         }
234
235         if (mount(NULL, "/run/initramfs", NULL, MS_PRIVATE, NULL) < 0) {
236                 log_error("Failed to make /run/initramfs private mount: %m");
237                 return -errno;
238         }
239
240         NULSTR_FOREACH(dir, dirs)
241                 if (mkdir_p(dir, 0755) < 0 && errno != EEXIST) {
242                         log_error("Failed to mkdir %s: %m", dir);
243                         return -errno;
244                 }
245
246         if (mount("/sys", "/run/initramfs/sys", NULL, MS_BIND, NULL) < 0) {
247                 log_error("Failed to mount bind /sys on /run/initramfs/sys: %m");
248                 return -errno;
249         }
250
251         if (mount("/proc", "/run/initramfs/proc", NULL, MS_BIND, NULL) < 0) {
252                 log_error("Failed to mount bind /proc on /run/initramfs/proc: %m");
253                 return -errno;
254         }
255
256         if (mount("/dev", "/run/initramfs/dev", NULL, MS_BIND, NULL) < 0) {
257                 log_error("Failed to mount bind /dev on /run/initramfs/dev: %m");
258                 return -errno;
259         }
260
261         if (mount("/run", "/run/initramfs/run", NULL, MS_BIND, NULL) < 0) {
262                 log_error("Failed to mount bind /run on /run/initramfs/run: %m");
263                 return -errno;
264         }
265
266         return 0;
267 }
268
269 static int pivot_to_new_root(void) {
270         int fd;
271
272         chdir("/run/initramfs");
273
274         /*
275           In case some evil process made "/" MS_SHARED
276           It works for pivot_root, but the ref count for the root device
277           is not decreasing :-/
278         */
279         if (mount(NULL, "/", NULL, MS_PRIVATE, NULL) < 0) {
280                 log_error("Failed to make \"/\" private mount %m");
281                 return -errno;
282         }
283
284         if (pivot_root(".", "oldroot") < 0) {
285                 log_error("pivot failed: %m");
286                 /* only chroot if pivot root succeded */
287                 return -errno;
288         }
289
290         chroot(".");
291         log_info("Successfully changed into root pivot.");
292
293         fd = open("/dev/console", O_RDWR);
294         if (fd < 0)
295                 log_error("Failed to open /dev/console: %m");
296         else {
297                 make_stdio(fd);
298
299                 /* Initialize the controlling terminal */
300                 setsid();
301                 ioctl(STDIN_FILENO, TIOCSCTTY, NULL);
302         }
303
304         return 0;
305 }
306
307 int main(int argc, char *argv[]) {
308         int cmd, r;
309         unsigned retries;
310         bool need_umount = true, need_swapoff = true, need_loop_detach = true, need_dm_detach = true;
311         bool killed_everbody = false, in_container, use_watchdog = false;
312
313         log_parse_environment();
314         log_set_target(LOG_TARGET_CONSOLE); /* syslog will die if not gone yet */
315         log_open();
316
317         umask(0022);
318
319         if (getpid() != 1) {
320                 log_error("Not executed by init (pid 1).");
321                 r = -EPERM;
322                 goto error;
323         }
324
325         if (argc != 2) {
326                 log_error("Invalid number of arguments.");
327                 r = -EINVAL;
328                 goto error;
329         }
330
331         in_container = detect_container(NULL) > 0;
332
333         if (streq(argv[1], "reboot"))
334                 cmd = RB_AUTOBOOT;
335         else if (streq(argv[1], "poweroff"))
336                 cmd = RB_POWER_OFF;
337         else if (streq(argv[1], "halt"))
338                 cmd = RB_HALT_SYSTEM;
339         else if (streq(argv[1], "kexec"))
340                 cmd = LINUX_REBOOT_CMD_KEXEC;
341         else {
342                 log_error("Unknown action '%s'.", argv[1]);
343                 r = -EINVAL;
344                 goto error;
345         }
346
347         use_watchdog = !!getenv("WATCHDOG_USEC");
348
349         /* lock us into memory */
350         mlockall(MCL_CURRENT|MCL_FUTURE);
351
352         log_info("Sending SIGTERM to remaining processes...");
353         send_signal(SIGTERM);
354
355         log_info("Sending SIGKILL to remaining processes...");
356         send_signal(SIGKILL);
357
358         if (in_container) {
359                 need_swapoff = false;
360                 need_dm_detach = false;
361         }
362
363         /* Unmount all mountpoints, swaps, and loopback devices */
364         for (retries = 0; retries < FINALIZE_ATTEMPTS; retries++) {
365                 bool changed = false;
366
367                 if (use_watchdog)
368                         watchdog_ping();
369
370                 if (need_umount) {
371                         log_info("Unmounting file systems.");
372                         r = umount_all(&changed);
373                         if (r == 0)
374                                 need_umount = false;
375                         else if (r > 0)
376                                 log_info("Not all file systems unmounted, %d left.", r);
377                         else
378                                 log_error("Failed to unmount file systems: %s", strerror(-r));
379                 }
380
381                 if (need_swapoff) {
382                         log_info("Disabling swaps.");
383                         r = swapoff_all(&changed);
384                         if (r == 0)
385                                 need_swapoff = false;
386                         else if (r > 0)
387                                 log_info("Not all swaps are turned off, %d left.", r);
388                         else
389                                 log_error("Failed to turn off swaps: %s", strerror(-r));
390                 }
391
392                 if (need_loop_detach) {
393                         log_info("Detaching loop devices.");
394                         r = loopback_detach_all(&changed);
395                         if (r == 0)
396                                 need_loop_detach = false;
397                         else if (r > 0)
398                                 log_info("Not all loop devices detached, %d left.", r);
399                         else
400                                 log_error("Failed to detach loop devices: %s", strerror(-r));
401                 }
402
403                 if (need_dm_detach) {
404                         log_info("Detaching DM devices.");
405                         r = dm_detach_all(&changed);
406                         if (r == 0)
407                                 need_dm_detach = false;
408                         else if (r > 0)
409                                 log_warning("Not all DM devices detached, %d left.", r);
410                         else
411                                 log_error("Failed to detach DM devices: %s", strerror(-r));
412                 }
413
414                 if (!need_umount && !need_swapoff && !need_loop_detach && !need_dm_detach) {
415                         if (retries > 0)
416                                 log_info("All filesystems, swaps, loop devices, DM devices detached.");
417                         /* Yay, done */
418                         break;
419                 }
420
421                 /* If in this iteration we didn't manage to
422                  * unmount/deactivate anything, we either kill more
423                  * processes, or simply give up */
424                 if (!changed) {
425
426                         if (killed_everbody) {
427                                 /* Hmm, we already killed everybody,
428                                  * let's just give up */
429                                 log_error("Cannot finalize remaining file systems and devices, giving up.");
430                                 break;
431                         }
432
433                         log_warning("Cannot finalize remaining file systems and devices, trying to kill remaining processes.");
434                         ultimate_send_signal(SIGTERM);
435                         ultimate_send_signal(SIGKILL);
436                         killed_everbody = true;
437                 }
438
439                 log_debug("Couldn't finalize remaining file systems and devices after %u retries, trying again.", retries+1);
440         }
441
442         if (retries >= FINALIZE_ATTEMPTS)
443                 log_error("Too many iterations, giving up.");
444
445         execute_directory(SYSTEM_SHUTDOWN_PATH, NULL, NULL);
446
447         /* If we are in a container, just exit, this will kill our
448          * container for good. */
449         if (in_container) {
450                 log_error("Exiting container.");
451                 exit(0);
452         }
453
454         if (access("/run/initramfs/shutdown", X_OK) == 0) {
455
456                 if (prepare_new_root() >= 0 &&
457                     pivot_to_new_root() >= 0) {
458                         execv("/shutdown", argv);
459                         log_error("Failed to execute shutdown binary: %m");
460                 }
461         }
462
463         sync();
464
465         if (cmd == LINUX_REBOOT_CMD_KEXEC) {
466                 /* We cheat and exec kexec to avoid doing all its work */
467                 pid_t pid = fork();
468
469                 if (pid < 0)
470                         log_error("Could not fork: %m. Falling back to normal reboot.");
471                 else if (pid > 0) {
472                         wait_for_terminate_and_warn("kexec", pid);
473                         log_warning("kexec failed. Falling back to normal reboot.");
474                 } else {
475                         /* Child */
476                         const char *args[3] = { "/sbin/kexec", "-e", NULL };
477                         execv(args[0], (char * const *) args);
478                         return EXIT_FAILURE;
479                 }
480
481                 cmd = RB_AUTOBOOT;
482         }
483
484         reboot(cmd);
485         log_error("Failed to invoke reboot(): %m");
486         r = -errno;
487
488   error:
489         log_error("Critical error while doing system shutdown: %s", strerror(-r));
490
491         freeze();
492         return EXIT_FAILURE;
493 }