Mercurial > dovecot > core-2.2
changeset 22027:38826e486570
lib-master: When running under master, close listeners immediately on SIGQUIT
author | Timo Sirainen <timo.sirainen@dovecot.fi> |
---|---|
date | Tue, 02 May 2017 16:13:08 +0300 |
parents | 7835a8a35d66 |
children | b914c4c07644 |
files | src/lib-master/master-service.c |
diffstat | 1 files changed, 21 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-master/master-service.c Tue May 02 18:39:06 2017 +0300 +++ b/src/lib-master/master-service.c Tue May 02 16:13:08 2017 +0300 @@ -86,6 +86,26 @@ io_loop_stop(service->ioloop); } +static void sig_close_listeners(const siginfo_t *si ATTR_UNUSED, void *context) +{ + struct master_service *service = context; + + /* We're in a signal handler: Close listeners immediately so master + can successfully restart. We can safely close only those listeners + that don't have an io, but this shouldn't be a big problem. If there + is an active io, the service is unlikely to be unresposive for + longer periods of time, so the listener gets closed soon enough via + master_status_error(). */ + for (unsigned int i = 0; i < service->socket_count; i++) { + if (service->listeners[i].fd != -1 && + service->listeners[i].io == NULL) { + if (close(service->listeners[i].fd) < 0) + lib_signals_syscall_error("signal: close(listener) failed: "); + service->listeners[i].fd = -1; + } + } +} + static void sig_state_changed(const siginfo_t *si ATTR_UNUSED, void *context) { @@ -513,6 +533,7 @@ /* start listening errors for status fd, it means master died */ service->io_status_error = io_add(MASTER_DEAD_FD, IO_ERROR, master_status_error, service); + lib_signals_set_handler(SIGQUIT, 0, sig_close_listeners, service); } master_service_io_listeners_add(service); if (service->want_ssl_settings &&