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