1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 ProFUSION embedded systems
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.
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.
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/>.
23 #include <sys/types.h>
24 #include <sys/reboot.h>
25 #include <linux/reboot.h>
27 #include <sys/types.h>
29 #include <sys/mount.h>
30 #include <sys/syscall.h>
48 #define TIMEOUT_USEC (5 * USEC_PER_SEC)
49 #define FINALIZE_ATTEMPTS 50
51 static bool ignore_proc(pid_t pid) {
59 /* We are PID 1, let's not commit suicide */
63 r = get_process_uid(pid, &uid);
65 return true; /* not really, but better safe than sorry */
67 /* Non-root processes otherwise are always subject to be killed */
71 snprintf(buf, sizeof(buf), "/proc/%lu/cmdline", (unsigned long) pid);
76 return true; /* not really, but has the desired effect */
78 count = fread(&c, 1, 1, f);
81 /* Kernel threads have an empty cmdline */
85 /* Processes with argv[0][0] = '@' we ignore from the killing
88 * http://www.freedesktop.org/wiki/Software/systemd/RootStorageDaemons */
89 if (count == 1 && c == '@')
95 static int killall(int sign) {
98 unsigned int n_processes = 0;
100 dir = opendir("/proc");
104 while ((d = readdir(dir))) {
107 if (parse_pid(d->d_name, &pid) < 0)
110 if (ignore_proc(pid))
113 if (kill(pid, sign) == 0)
116 log_warning("Could not kill %d: %m", pid);
124 static void wait_for_children(int n_processes, sigset_t *mask) {
129 until = now(CLOCK_MONOTONIC) + TIMEOUT_USEC;
136 pid_t pid = waitpid(-1, NULL, WNOHANG);
141 if (pid < 0 && errno == ECHILD)
145 if (--n_processes == 0)
149 n = now(CLOCK_MONOTONIC);
153 timespec_store(&ts, until - n);
155 if ((k = sigtimedwait(mask, NULL, &ts)) != SIGCHLD) {
157 if (k < 0 && errno != EAGAIN) {
158 log_error("sigtimedwait() failed: %m");
163 log_warning("sigtimedwait() returned unexpected signal.");
168 static void send_signal(int sign) {
169 sigset_t mask, oldmask;
172 assert_se(sigemptyset(&mask) == 0);
173 assert_se(sigaddset(&mask, SIGCHLD) == 0);
174 assert_se(sigprocmask(SIG_BLOCK, &mask, &oldmask) == 0);
176 if (kill(-1, SIGSTOP) < 0 && errno != ESRCH)
177 log_warning("kill(-1, SIGSTOP) failed: %m");
179 n_processes = killall(sign);
181 if (kill(-1, SIGCONT) < 0 && errno != ESRCH)
182 log_warning("kill(-1, SIGCONT) failed: %m");
184 if (n_processes <= 0)
187 wait_for_children(n_processes, &mask);
190 sigprocmask(SIG_SETMASK, &oldmask, NULL);
193 static void ultimate_send_signal(int sign) {
194 sigset_t mask, oldmask;
197 assert_se(sigemptyset(&mask) == 0);
198 assert_se(sigaddset(&mask, SIGCHLD) == 0);
199 assert_se(sigprocmask(SIG_BLOCK, &mask, &oldmask) == 0);
201 if (kill(-1, SIGSTOP) < 0 && errno != ESRCH)
202 log_warning("kill(-1, SIGSTOP) failed: %m");
205 if (r < 0 && errno != ESRCH)
206 log_warning("kill(-1, %s) failed: %m", signal_to_string(sign));
208 if (kill(-1, SIGCONT) < 0 && errno != ESRCH)
209 log_warning("kill(-1, SIGCONT) failed: %m");
214 wait_for_children(0, &mask);
217 sigprocmask(SIG_SETMASK, &oldmask, NULL);
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";
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");
235 if (mount(NULL, "/run/initramfs", NULL, MS_PRIVATE, NULL) < 0) {
236 log_error("Failed to make /run/initramfs private mount: %m");
240 NULSTR_FOREACH(dir, dirs)
241 if (mkdir_p(dir, 0755) < 0 && errno != EEXIST) {
242 log_error("Failed to mkdir %s: %m", dir);
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");
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");
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");
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");
269 static int pivot_to_new_root(void) {
272 chdir("/run/initramfs");
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 :-/
279 if (mount(NULL, "/", NULL, MS_PRIVATE, NULL) < 0) {
280 log_error("Failed to make \"/\" private mount %m");
284 if (pivot_root(".", "oldroot") < 0) {
285 log_error("pivot failed: %m");
286 /* only chroot if pivot root succeded */
291 log_info("Successfully changed into root pivot.");
293 fd = open("/dev/console", O_RDWR);
295 log_error("Failed to open /dev/console: %m");
299 /* Initialize the controlling terminal */
301 ioctl(STDIN_FILENO, TIOCSCTTY, NULL);
307 int main(int argc, char *argv[]) {
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;
314 log_parse_environment();
315 log_set_target(LOG_TARGET_CONSOLE); /* syslog will die if not gone yet */
321 log_error("Not executed by init (pid 1).");
327 log_error("Invalid number of arguments.");
332 in_container = detect_container(NULL) > 0;
334 if (streq(argv[1], "reboot"))
336 else if (streq(argv[1], "poweroff"))
338 else if (streq(argv[1], "halt"))
339 cmd = RB_HALT_SYSTEM;
340 else if (streq(argv[1], "kexec"))
341 cmd = LINUX_REBOOT_CMD_KEXEC;
343 log_error("Unknown action '%s'.", argv[1]);
348 use_watchdog = !!getenv("WATCHDOG_USEC");
350 /* lock us into memory */
351 mlockall(MCL_CURRENT|MCL_FUTURE);
353 log_info("Sending SIGTERM to remaining processes...");
354 send_signal(SIGTERM);
356 log_info("Sending SIGKILL to remaining processes...");
357 send_signal(SIGKILL);
360 need_swapoff = false;
361 need_dm_detach = false;
364 /* Unmount all mountpoints, swaps, and loopback devices */
365 for (retries = 0; retries < FINALIZE_ATTEMPTS; retries++) {
366 bool changed = false;
372 log_info("Unmounting file systems.");
373 r = umount_all(&changed);
377 log_info("Not all file systems unmounted, %d left.", r);
379 log_error("Failed to unmount file systems: %s", strerror(-r));
383 log_info("Disabling swaps.");
384 r = swapoff_all(&changed);
386 need_swapoff = false;
388 log_info("Not all swaps are turned off, %d left.", r);
390 log_error("Failed to turn off swaps: %s", strerror(-r));
393 if (need_loop_detach) {
394 log_info("Detaching loop devices.");
395 r = loopback_detach_all(&changed);
397 need_loop_detach = false;
399 log_info("Not all loop devices detached, %d left.", r);
401 log_error("Failed to detach loop devices: %s", strerror(-r));
404 if (need_dm_detach) {
405 log_info("Detaching DM devices.");
406 r = dm_detach_all(&changed);
408 need_dm_detach = false;
410 log_warning("Not all DM devices detached, %d left.", r);
412 log_error("Failed to detach DM devices: %s", strerror(-r));
415 if (!need_umount && !need_swapoff && !need_loop_detach && !need_dm_detach) {
417 log_info("All filesystems, swaps, loop devices, DM devices detached.");
422 /* If in this iteration we didn't manage to
423 * unmount/deactivate anything, we either kill more
424 * processes, or simply give up */
427 if (killed_everbody) {
428 /* Hmm, we already killed everybody,
429 * let's just give up */
430 log_error("Cannot finalize remaining file systems and devices, giving up.");
434 log_warning("Cannot finalize remaining file systems and devices, trying to kill remaining processes.");
435 ultimate_send_signal(SIGTERM);
436 ultimate_send_signal(SIGKILL);
437 killed_everbody = true;
440 log_debug("Couldn't finalize remaining file systems and devices after %u retries, trying again.", retries+1);
443 if (retries >= FINALIZE_ATTEMPTS)
444 log_error("Too many iterations, giving up.");
447 arguments[1] = argv[1];
449 execute_directory(SYSTEM_SHUTDOWN_PATH, NULL, arguments);
451 /* If we are in a container, just exit, this will kill our
452 * container for good. */
454 log_error("Exiting container.");
458 if (access("/run/initramfs/shutdown", X_OK) == 0) {
460 if (prepare_new_root() >= 0 &&
461 pivot_to_new_root() >= 0) {
462 execv("/shutdown", argv);
463 log_error("Failed to execute shutdown binary: %m");
469 if (cmd == LINUX_REBOOT_CMD_KEXEC) {
470 /* We cheat and exec kexec to avoid doing all its work */
474 log_error("Could not fork: %m. Falling back to normal reboot.");
476 wait_for_terminate_and_warn("kexec", pid);
477 log_warning("kexec failed. Falling back to normal reboot.");
480 const char *args[3] = { "/sbin/kexec", "-e", NULL };
481 execv(args[0], (char * const *) args);
489 log_error("Failed to invoke reboot(): %m");
493 log_error("Critical error while doing system shutdown: %s", strerror(-r));