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:
parent
26fefda707
commit
0bee65f062
2
TODO
2
TODO
|
@ -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
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue