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.
This commit is contained in:
Lennart Poettering 2013-11-25 18:08:02 +01:00
parent 26fefda707
commit 0bee65f062
6 changed files with 30 additions and 14 deletions

2
TODO
View File

@ -43,6 +43,8 @@ CGroup Rework Completion:
Features: Features:
* general: get rid of readdir_r/dirent_storage stuff, it's unnecessary on Linux
* add API to clone sd_bus_message objects * add API to clone sd_bus_message objects
* sd-bus: synthesized messages should get serial number (uint32_t) -1 * sd-bus: synthesized messages should get serial number (uint32_t) -1

View File

@ -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; _cleanup_closedir_ DIR *dir = NULL;
struct dirent *d; struct dirent *d;
@ -178,12 +178,28 @@ static int killall(int sig, Set *pids) {
set_put(pids, ULONG_TO_PTR((unsigned long) pid)); set_put(pids, ULONG_TO_PTR((unsigned long) pid));
} else if (errno != ENOENT) } else if (errno != ENOENT)
log_warning("Could not kill %d: %m", pid); 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); 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; sigset_t mask, oldmask;
Set *pids = NULL; Set *pids = NULL;
@ -197,7 +213,7 @@ void broadcast_signal(int sig, bool wait_for_exit) {
if (kill(-1, SIGSTOP) < 0 && errno != ESRCH) if (kill(-1, SIGSTOP) < 0 && errno != ESRCH)
log_warning("kill(-1, SIGSTOP) failed: %m"); log_warning("kill(-1, SIGSTOP) failed: %m");
killall(sig, pids); killall(sig, pids, send_sighup);
if (kill(-1, SIGCONT) < 0 && errno != ESRCH) if (kill(-1, SIGCONT) < 0 && errno != ESRCH)
log_warning("kill(-1, SIGCONT) failed: %m"); log_warning("kill(-1, SIGCONT) failed: %m");

View File

@ -21,4 +21,4 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>. along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/ ***/
void broadcast_signal(int sig, bool wait); void broadcast_signal(int sig, bool wait, bool send_sighup);

View File

@ -1745,7 +1745,7 @@ finish:
* initrd, but don't wait for them, so that we * initrd, but don't wait for them, so that we
* can handle the SIGCHLD for them after * can handle the SIGCHLD for them after
* deserializing. */ * deserializing. */
broadcast_signal(SIGTERM, false); broadcast_signal(SIGTERM, false, true);
/* And switch root */ /* And switch root */
r = switch_root(switch_root_dir); r = switch_root(switch_root_dir);

View File

@ -195,10 +195,10 @@ int main(int argc, char *argv[]) {
mlockall(MCL_CURRENT|MCL_FUTURE); mlockall(MCL_CURRENT|MCL_FUTURE);
log_info("Sending SIGTERM to remaining processes..."); log_info("Sending SIGTERM to remaining processes...");
broadcast_signal(SIGTERM, true); broadcast_signal(SIGTERM, true, true);
log_info("Sending SIGKILL to remaining processes..."); log_info("Sending SIGKILL to remaining processes...");
broadcast_signal(SIGKILL, true); broadcast_signal(SIGKILL, true, false);
if (in_container) { if (in_container) {
need_swapoff = false; need_swapoff = false;

View File

@ -2525,10 +2525,8 @@ int get_ctty_devnr(pid_t pid, dev_t *d) {
char line[LINE_MAX], *p; char line[LINE_MAX], *p;
unsigned long ttynr; unsigned long ttynr;
const char *fn; const char *fn;
int k;
assert(pid >= 0); assert(pid >= 0);
assert(d);
if (pid == 0) if (pid == 0)
fn = "/proc/self/stat"; fn = "/proc/self/stat";
@ -2539,10 +2537,8 @@ int get_ctty_devnr(pid_t pid, dev_t *d) {
if (!f) if (!f)
return -errno; return -errno;
if (!fgets(line, sizeof(line), f)) { if (!fgets(line, sizeof(line), f))
k = feof(f) ? -EIO : -errno; return feof(f) ? -EIO : -errno;
return k;
}
p = strrchr(line, ')'); p = strrchr(line, ')');
if (!p) if (!p)
@ -2562,7 +2558,9 @@ int get_ctty_devnr(pid_t pid, dev_t *d) {
if (major(ttynr) == 0 && minor(ttynr) == 0) if (major(ttynr) == 0 && minor(ttynr) == 0)
return -ENOENT; return -ENOENT;
*d = (dev_t) ttynr; if (d)
*d = (dev_t) ttynr;
return 0; return 0;
} }