From 0bee65f0622c4faa8ac8ae771cc0c8a936dfa284 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 25 Nov 2013 18:08:02 +0100 Subject: [PATCH] shutdown: during final killing spree also send SIGHUP in addition to SIGTERM to deal with shells This makes shutdown a bit faster if debug-shell.service is enabled. --- TODO | 2 ++ src/core/killall.c | 22 +++++++++++++++++++--- src/core/killall.h | 2 +- src/core/main.c | 2 +- src/core/shutdown.c | 4 ++-- src/shared/util.c | 12 +++++------- 6 files changed, 30 insertions(+), 14 deletions(-) diff --git a/TODO b/TODO index 9b898bb57..d63e13e31 100644 --- a/TODO +++ b/TODO @@ -43,6 +43,8 @@ CGroup Rework Completion: Features: +* general: get rid of readdir_r/dirent_storage stuff, it's unnecessary on Linux + * add API to clone sd_bus_message objects * sd-bus: synthesized messages should get serial number (uint32_t) -1 diff --git a/src/core/killall.c b/src/core/killall.c index e39505010..a7828dc04 100644 --- a/src/core/killall.c +++ b/src/core/killall.c @@ -145,7 +145,7 @@ static void wait_for_children(Set *pids, sigset_t *mask) { } } -static int killall(int sig, Set *pids) { +static int killall(int sig, Set *pids, bool send_sighup) { _cleanup_closedir_ DIR *dir = NULL; struct dirent *d; @@ -178,12 +178,28 @@ static int killall(int sig, Set *pids) { set_put(pids, ULONG_TO_PTR((unsigned long) pid)); } else if (errno != ENOENT) log_warning("Could not kill %d: %m", pid); + + if (send_sighup) { + /* Optionally, also send a SIGHUP signal, but + only if the process has a controlling + tty. This is useful to allow handling of + shells which ignore SIGTERM but react to + SIGHUP. We do not send this to processes that + have no controlling TTY since we don't want to + trigger reloads of daemon processes. Also we + make sure to only send this after SIGTERM so + that SIGTERM is always first in the queue. */ + + + if (get_ctty_devnr(pid, NULL) >= 0) + kill(pid, SIGHUP); + } } return set_size(pids); } -void broadcast_signal(int sig, bool wait_for_exit) { +void broadcast_signal(int sig, bool send_sighup, bool wait_for_exit) { sigset_t mask, oldmask; Set *pids = NULL; @@ -197,7 +213,7 @@ void broadcast_signal(int sig, bool wait_for_exit) { if (kill(-1, SIGSTOP) < 0 && errno != ESRCH) log_warning("kill(-1, SIGSTOP) failed: %m"); - killall(sig, pids); + killall(sig, pids, send_sighup); if (kill(-1, SIGCONT) < 0 && errno != ESRCH) log_warning("kill(-1, SIGCONT) failed: %m"); diff --git a/src/core/killall.h b/src/core/killall.h index 95b110fae..bdb73e44b 100644 --- a/src/core/killall.h +++ b/src/core/killall.h @@ -21,4 +21,4 @@ along with systemd; If not, see . ***/ -void broadcast_signal(int sig, bool wait); +void broadcast_signal(int sig, bool wait, bool send_sighup); diff --git a/src/core/main.c b/src/core/main.c index bc92f65fd..dbc98db84 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -1745,7 +1745,7 @@ finish: * initrd, but don't wait for them, so that we * can handle the SIGCHLD for them after * deserializing. */ - broadcast_signal(SIGTERM, false); + broadcast_signal(SIGTERM, false, true); /* And switch root */ r = switch_root(switch_root_dir); diff --git a/src/core/shutdown.c b/src/core/shutdown.c index bcf2eecf3..31129b769 100644 --- a/src/core/shutdown.c +++ b/src/core/shutdown.c @@ -195,10 +195,10 @@ int main(int argc, char *argv[]) { mlockall(MCL_CURRENT|MCL_FUTURE); log_info("Sending SIGTERM to remaining processes..."); - broadcast_signal(SIGTERM, true); + broadcast_signal(SIGTERM, true, true); log_info("Sending SIGKILL to remaining processes..."); - broadcast_signal(SIGKILL, true); + broadcast_signal(SIGKILL, true, false); if (in_container) { need_swapoff = false; diff --git a/src/shared/util.c b/src/shared/util.c index 97c9497df..3a4d1965a 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -2525,10 +2525,8 @@ int get_ctty_devnr(pid_t pid, dev_t *d) { char line[LINE_MAX], *p; unsigned long ttynr; const char *fn; - int k; assert(pid >= 0); - assert(d); if (pid == 0) fn = "/proc/self/stat"; @@ -2539,10 +2537,8 @@ int get_ctty_devnr(pid_t pid, dev_t *d) { if (!f) return -errno; - if (!fgets(line, sizeof(line), f)) { - k = feof(f) ? -EIO : -errno; - return k; - } + if (!fgets(line, sizeof(line), f)) + return feof(f) ? -EIO : -errno; p = strrchr(line, ')'); if (!p) @@ -2562,7 +2558,9 @@ int get_ctty_devnr(pid_t pid, dev_t *d) { if (major(ttynr) == 0 && minor(ttynr) == 0) return -ENOENT; - *d = (dev_t) ttynr; + if (d) + *d = (dev_t) ttynr; + return 0; } -- 2.30.2