From: Lennart Poettering Date: Sat, 22 Dec 2012 20:21:09 +0000 (+0100) Subject: nspawn: try to orderly shutdown container when receiving SIGTERM X-Git-Tag: v197~105 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=commitdiff_plain;h=57cb4adf4ed61ab9eeb7f190f94d700a56bafad0 nspawn: try to orderly shutdown container when receiving SIGTERM --- diff --git a/src/core/manager.c b/src/core/manager.c index ac11ce180..a3839e153 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -1176,7 +1176,8 @@ static int manager_process_signal_fd(Manager *m) { assert(m); for (;;) { - if ((n = read(m->signal_watch.fd, &sfsi, sizeof(sfsi))) != sizeof(sfsi)) { + n = read(m->signal_watch.fd, &sfsi, sizeof(sfsi)); + if (n != sizeof(sfsi)) { if (n >= 0) return -EIO; diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index f5fb59d2d..1f3bda5b4 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -817,13 +817,18 @@ static int is_os_tree(const char *path) { return r < 0 ? 0 : 1; } -static int process_pty(int master, sigset_t *mask) { +static int process_pty(int master, pid_t pid, sigset_t *mask) { char in_buffer[LINE_MAX], out_buffer[LINE_MAX]; size_t in_buffer_full = 0, out_buffer_full = 0; struct epoll_event stdin_ev, stdout_ev, master_ev, signal_ev; bool stdin_readable = false, stdout_writable = false, master_readable = false, master_writable = false; int ep = -1, signal_fd = -1, r; + bool tried_orderly_shutdown = false; + + assert(master >= 0); + assert(pid > 0); + assert(mask); fd_nonblock(STDIN_FILENO, 1); fd_nonblock(STDOUT_FILENO, 1); @@ -940,6 +945,14 @@ static int process_pty(int master, sigset_t *mask) { /* The window size changed, let's forward that. */ if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) >= 0) ioctl(master, TIOCSWINSZ, &ws); + } else if (sfsi.ssi_signo == SIGTERM && arg_boot && !tried_orderly_shutdown) { + + log_info("Trying to halt container. Send SIGTERM again to trigger immediate termination."); + + /* This only works for systemd... */ + tried_orderly_shutdown = true; + kill(pid, SIGRTMIN+3); + } else { r = 0; goto finish; @@ -1451,7 +1464,7 @@ int main(int argc, char *argv[]) { fdset_free(fds); fds = NULL; - if (process_pty(master, &mask) < 0) + if (process_pty(master, pid, &mask) < 0) goto finish; if (saved_attr_valid)