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;
313 log_parse_environment();
314 log_set_target(LOG_TARGET_CONSOLE); /* syslog will die if not gone yet */
320 log_error("Not executed by init (pid 1).");
326 log_error("Invalid number of arguments.");
331 in_container = detect_container(NULL) > 0;
333 if (streq(argv[1], "reboot"))
335 else if (streq(argv[1], "poweroff"))
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;
342 log_error("Unknown action '%s'.", argv[1]);
347 use_watchdog = !!getenv("WATCHDOG_USEC");
349 /* lock us into memory */
350 if (mlockall(MCL_CURRENT|MCL_FUTURE) != 0)
351 log_warning("Cannot lock process memory: %m");
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;
362 /* Unmount all mountpoints, swaps, and loopback devices */
363 for (retries = 0; retries < FINALIZE_ATTEMPTS; retries++) {
364 bool changed = false;
370 log_info("Unmounting file systems.");
371 r = umount_all(&changed);
375 log_info("Not all file systems unmounted, %d left.", r);
377 log_error("Failed to unmount file systems: %s", strerror(-r));
381 log_info("Disabling swaps.");
382 r = swapoff_all(&changed);
384 need_swapoff = false;
386 log_info("Not all swaps are turned off, %d left.", r);
388 log_error("Failed to turn off swaps: %s", strerror(-r));
391 if (need_loop_detach) {
392 log_info("Detaching loop devices.");
393 r = loopback_detach_all(&changed);
395 need_loop_detach = false;
397 log_info("Not all loop devices detached, %d left.", r);
399 log_error("Failed to detach loop devices: %s", strerror(-r));
402 if (need_dm_detach) {
403 log_info("Detaching DM devices.");
404 r = dm_detach_all(&changed);
406 need_dm_detach = false;
408 log_warning("Not all DM devices detached, %d left.", r);
410 log_error("Failed to detach DM devices: %s", strerror(-r));
413 if (!need_umount && !need_swapoff && !need_loop_detach && !need_dm_detach) {
415 log_info("All filesystems, swaps, loop devices, DM devices detached.");
420 /* If in this iteration we didn't manage to
421 * unmount/deactivate anything, we either kill more
422 * processes, or simply give up */
425 if (killed_everbody) {
426 /* Hmm, we already killed everybody,
427 * let's just give up */
428 log_error("Cannot finalize remaining file systems and devices, giving up.");
432 log_warning("Cannot finalize remaining file systems and devices, trying to kill remaining processes.");
433 ultimate_send_signal(SIGTERM);
434 ultimate_send_signal(SIGKILL);
435 killed_everbody = true;
438 log_debug("Couldn't finalize remaining file systems and devices after %u retries, trying again.", retries+1);
441 if (retries >= FINALIZE_ATTEMPTS)
442 log_error("Too many iterations, giving up.");
444 execute_directory(SYSTEM_SHUTDOWN_PATH, NULL, NULL);
446 /* If we are in a container, just exit, this will kill our
447 * container for good. */
449 log_error("Exiting container.");
453 if (access("/run/initramfs/shutdown", X_OK) == 0) {
455 if (prepare_new_root() >= 0 &&
456 pivot_to_new_root() >= 0) {
457 execv("/shutdown", argv);
458 log_error("Failed to execute shutdown binary: %m");
464 if (cmd == LINUX_REBOOT_CMD_KEXEC) {
465 /* We cheat and exec kexec to avoid doing all its work */
469 log_error("Could not fork: %m. Falling back to normal reboot.");
471 wait_for_terminate_and_warn("kexec", pid);
472 log_warning("kexec failed. Falling back to normal reboot.");
475 const char *args[3] = { "/sbin/kexec", "-e", NULL };
476 execv(args[0], (char * const *) args);
484 log_error("Failed to invoke reboot(): %m");
488 log_error("Critical error while doing system shutdown: %s", strerror(-r));