killall.c revision 6301a98cdf26dc073f5317506c806bfa69f74cc8
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog This file is part of systemd.
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog Copyright 2010 ProFUSION embedded systems
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog systemd is free software; you can redistribute it and/or modify it
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog under the terms of the GNU Lesser General Public License as published by
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog the Free Software Foundation; either version 2.1 of the License, or
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog (at your option) any later version.
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog systemd is distributed in the hope that it will be useful, but
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog WITHOUT ANY WARRANTY; without even the implied warranty of
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog Lesser General Public License for more details.
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog You should have received a copy of the GNU Lesser General Public License
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog along with systemd; If not, see <http://www.gnu.org/licenses/>.
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog#define TIMEOUT_USEC (10 * USEC_PER_SEC)
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog /* We are PID 1, let's not commit suicide */
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog return true; /* not really, but better safe than sorry */
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog /* Non-root processes otherwise are always subject to be killed */
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog p = procfs_file_alloca(pid, "cmdline");
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog return true; /* not really, but has the desired effect */
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog /* Kernel threads have an empty cmdline */
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog /* Processes with argv[0][0] = '@' we ignore from the killing
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog * http://www.freedesktop.org/wiki/Software/systemd/RootStorageDaemons */
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskogstatic void wait_for_children(Set *pids, sigset_t *mask) {
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog until = now(CLOCK_MONOTONIC) + TIMEOUT_USEC;
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog /* First, let the kernel inform us about killed
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog * children. Most processes will probably be our
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog * children, but some are not (might be our
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog * grandchildren instead...). */
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog /* Now explicitly check who might be remaining, who
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog * might not be our child. */
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog /* We misuse getpgid as a check whether a
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog * process still exists. */
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog if (getpgid((pid_t) PTR_TO_ULONG(p)) >= 0)
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog log_error("sigtimedwait() failed: %m");
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog log_warning("sigtimedwait() returned unexpected signal.");
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskogstatic int killall(int sig, Set *pids, bool send_sighup) {
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog log_notice("Sending SIGKILL to PID %lu (%s).", (unsigned long) pid, strna(s));
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog set_put(pids, ULONG_TO_PTR((unsigned long) pid));
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog log_warning("Could not kill %d: %m", pid);
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog /* Optionally, also send a SIGHUP signal, but
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog only if the process has a controlling
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog tty. This is useful to allow handling of
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog shells which ignore SIGTERM but react to
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog SIGHUP. We do not send this to processes that
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog have no controlling TTY since we don't want to
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog trigger reloads of daemon processes. Also we
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog make sure to only send this after SIGTERM so
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog that SIGTERM is always first in the queue. */
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskogvoid broadcast_signal(int sig, bool wait_for_exit, bool send_sighup) {
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog pids = set_new(trivial_hash_func, trivial_compare_func);
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog assert_se(sigaddset(&mask, SIGCHLD) == 0);
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog assert_se(sigprocmask(SIG_BLOCK, &mask, &oldmask) == 0);
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog if (kill(-1, SIGSTOP) < 0 && errno != ESRCH)
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog log_warning("kill(-1, SIGSTOP) failed: %m");
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog if (kill(-1, SIGCONT) < 0 && errno != ESRCH)
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog log_warning("kill(-1, SIGCONT) failed: %m");