diff options
Diffstat (limited to 'src/core/killall.c')
-rw-r--r-- | src/core/killall.c | 48 |
1 files changed, 32 insertions, 16 deletions
diff --git a/src/core/killall.c b/src/core/killall.c index 2a9d72c901..a8b814e868 100644 --- a/src/core/killall.c +++ b/src/core/killall.c @@ -1,5 +1,3 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - /*** This file is part of systemd. @@ -19,21 +17,24 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include <sys/wait.h> -#include <signal.h> #include <errno.h> +#include <signal.h> +#include <sys/wait.h> #include <unistd.h> -#include "util.h" -#include "killall.h" -#include "set.h" +#include "alloc-util.h" +#include "def.h" +#include "fd-util.h" #include "formats-util.h" +#include "killall.h" +#include "parse-util.h" #include "process-util.h" +#include "set.h" +#include "string-util.h" #include "terminal-util.h" +#include "util.h" -#define TIMEOUT_USEC (10 * USEC_PER_SEC) - -static bool ignore_proc(pid_t pid) { +static bool ignore_proc(pid_t pid, bool warn_rootfs) { _cleanup_fclose_ FILE *f = NULL; char c; const char *p; @@ -68,7 +69,22 @@ static bool ignore_proc(pid_t pid) { * spree. * * http://www.freedesktop.org/wiki/Software/systemd/RootStorageDaemons */ - if (count == 1 && c == '@') + if (c == '@' && warn_rootfs) { + _cleanup_free_ char *comm = NULL; + + r = pid_from_same_root_fs(pid); + if (r < 0) + return true; + + get_process_comm(pid, &comm); + + if (r) + log_notice("Process " PID_FMT " (%s) has been marked to be excluded from killing. It is " + "running from the root file system, and thus likely to block re-mounting of the " + "root file system to read-only. Please consider moving it into an initrd file " + "system instead.", pid, strna(comm)); + return true; + } else if (c == '@') return true; return false; @@ -82,7 +98,7 @@ static void wait_for_children(Set *pids, sigset_t *mask) { if (set_isempty(pids)) return; - until = now(CLOCK_MONOTONIC) + TIMEOUT_USEC; + until = now(CLOCK_MONOTONIC) + DEFAULT_TIMEOUT_USEC; for (;;) { struct timespec ts; int k; @@ -108,7 +124,7 @@ static void wait_for_children(Set *pids, sigset_t *mask) { return; } - set_remove(pids, ULONG_TO_PTR(pid)); + (void) set_remove(pids, PID_TO_PTR(pid)); } /* Now explicitly check who might be remaining, who @@ -117,7 +133,7 @@ static void wait_for_children(Set *pids, sigset_t *mask) { /* We misuse getpgid as a check whether a * process still exists. */ - if (getpgid((pid_t) PTR_TO_ULONG(p)) >= 0) + if (getpgid(PTR_TO_PID(p)) >= 0) continue; if (errno != ESRCH) @@ -167,7 +183,7 @@ static int killall(int sig, Set *pids, bool send_sighup) { if (parse_pid(d->d_name, &pid) < 0) continue; - if (ignore_proc(pid)) + if (ignore_proc(pid, sig == SIGKILL && !in_initrd())) continue; if (sig == SIGKILL) { @@ -179,7 +195,7 @@ static int killall(int sig, Set *pids, bool send_sighup) { if (kill(pid, sig) >= 0) { if (pids) { - r = set_put(pids, ULONG_TO_PTR(pid)); + r = set_put(pids, PID_TO_PTR(pid)); if (r < 0) log_oom(); } |