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