From 1359fffa573f42463e3b369df5e57b0c33821a61 Mon Sep 17 00:00:00 2001 From: Michal Sekletar Date: Sun, 24 Jan 2016 16:08:36 +0100 Subject: [PATCH] shutdown: complain if process excluded from killing spree runs of the same rootfs as PID1 --- TODO | 4 ---- src/basic/process-util.c | 12 ++++++++++++ src/basic/process-util.h | 1 + src/core/killall.c | 21 ++++++++++++++++++--- 4 files changed, 31 insertions(+), 7 deletions(-) diff --git a/TODO b/TODO index 99c2e547b8..ba973005b2 100644 --- a/TODO +++ b/TODO @@ -344,10 +344,6 @@ Features: - generate a failure of a default event loop is executed out-of-thread - maybe add support for inotify events -* in the final killing spree, detect processes from the root directory, and - complain loudly if they have argv[0][0] == '@' set. - https://bugzilla.redhat.com/show_bug.cgi?id=961044 - * investigate endianness issues of UUID vs. GUID * dbus: when a unit failed to load (i.e. is in UNIT_ERROR state), we diff --git a/src/basic/process-util.c b/src/basic/process-util.c index 4341d0093f..189ef9ab60 100644 --- a/src/basic/process-util.c +++ b/src/basic/process-util.c @@ -48,6 +48,7 @@ #include "missing.h" #include "process-util.h" #include "signal-util.h" +#include "stat-util.h" #include "string-table.h" #include "string-util.h" #include "user-util.h" @@ -637,6 +638,17 @@ bool pid_is_alive(pid_t pid) { return true; } +int pid_from_same_root_fs(pid_t pid) { + const char *root; + + if (pid < 0) + return 0; + + root = procfs_file_alloca(pid, "root"); + + return files_same(root, "/proc/1/root"); +} + bool is_main_thread(void) { static thread_local int cached = 0; diff --git a/src/basic/process-util.h b/src/basic/process-util.h index ac4d05e65f..f5d193e762 100644 --- a/src/basic/process-util.h +++ b/src/basic/process-util.h @@ -70,6 +70,7 @@ int getenv_for_pid(pid_t pid, const char *field, char **_value); bool pid_is_alive(pid_t pid); bool pid_is_unwaited(pid_t pid); +int pid_from_same_root_fs(pid_t pid); bool is_main_thread(void); diff --git a/src/core/killall.c b/src/core/killall.c index 77f145b4d1..d0c7c89670 100644 --- a/src/core/killall.c +++ b/src/core/killall.c @@ -37,7 +37,7 @@ #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; @@ -72,7 +72,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 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; @@ -171,7 +186,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) {