From: Timo Sirainen Date: Wed, 30 Sep 2009 17:03:07 +0000 (-0400) Subject: master: If anvil isn't used, read and discard all anvil input coming from mail processes. X-Git-Tag: 2.0.alpha1~98 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=cf2e6953d03a1c22f272ec19432fc03c136ac1bb;p=thirdparty%2Fdovecot%2Fcore.git master: If anvil isn't used, read and discard all anvil input coming from mail processes. --HG-- branch : HEAD --- diff --git a/src/master/service-anvil.c b/src/master/service-anvil.c index 25c9cdf61f..76b32a908f 100644 --- a/src/master/service-anvil.c +++ b/src/master/service-anvil.c @@ -1,6 +1,7 @@ /* Copyright (c) 2009 Dovecot authors, see the included COPYING file */ #include "common.h" +#include "ioloop.h" #include "fd-close-on-exec.h" #include "fd-set-nonblock.h" #include "service.h" @@ -12,6 +13,42 @@ #define ANVIL_HANDSHAKE "VERSION\tanvil\t1\t0\n" +static void +anvil_input_fd_discard(struct service_list *service_list, int fd) +{ + char buf[1024]; + ssize_t ret; + + ret = read(fd, buf, sizeof(buf)); + if (ret <= 0) { + i_error("read(anvil fd) failed: %m"); + io_remove(&service_list->anvil_io_blocking); + io_remove(&service_list->anvil_io_nonblocking); + } +} + +static void anvil_input_blocking_discard(struct service_list *service_list) +{ + anvil_input_fd_discard(service_list, + service_list->blocking_anvil_fd[0]); +} + +static void anvil_input_nonblocking_discard(struct service_list *service_list) +{ + anvil_input_fd_discard(service_list, + service_list->nonblocking_anvil_fd[0]); +} + +static void service_list_anvil_discard_input(struct service_list *service_list) +{ + service_list->anvil_io_blocking = + io_add(service_list->blocking_anvil_fd[0], IO_READ, + anvil_input_blocking_discard, service_list); + service_list->anvil_io_nonblocking = + io_add(service_list->nonblocking_anvil_fd[0], IO_READ, + anvil_input_nonblocking_discard, service_list); +} + static int anvil_send_handshake(int fd, const char **error_r) { ssize_t ret; @@ -75,6 +112,7 @@ int service_list_init_anvil(struct service_list *service_list, service_list->anvil_kills = service_process_notify_init(service_list->nonblocking_anvil_fd[1], service_process_write_anvil_kill); + service_list_anvil_discard_input(service_list); return 0; } @@ -90,3 +128,18 @@ void service_list_deinit_anvil(struct service_list *service_list) if (close(service_list->nonblocking_anvil_fd[1]) < 0) i_error("close(anvil) failed: %m"); } + +void service_anvil_process_created(struct service *service) +{ + if (service->list->anvil_io_blocking != NULL) { + io_remove(&service->list->anvil_io_blocking); + io_remove(&service->list->anvil_io_nonblocking); + } +} + +void service_anvil_process_destroyed(struct service *service) +{ + if (service->process_count == 0 && + service->list->anvil_io_blocking == NULL) + service_list_anvil_discard_input(service->list); +} diff --git a/src/master/service-anvil.h b/src/master/service-anvil.h index 425a3be5ea..05c6473eba 100644 --- a/src/master/service-anvil.h +++ b/src/master/service-anvil.h @@ -5,4 +5,7 @@ int service_list_init_anvil(struct service_list *service_list, const char **error_r); void service_list_deinit_anvil(struct service_list *service_list); +void service_anvil_process_created(struct service *service); +void service_anvil_process_destroyed(struct service *service); + #endif diff --git a/src/master/service-process.c b/src/master/service-process.c index f9979fa6c4..5d4b696380 100644 --- a/src/master/service-process.c +++ b/src/master/service-process.c @@ -20,6 +20,7 @@ #include "master-service-settings.h" #include "dup2-array.h" #include "service.h" +#include "service-anvil.h" #include "service-log.h" #include "service-auth-server.h" #include "service-auth-source.h" @@ -555,6 +556,9 @@ service_process_create(struct service *service, const char *const *auth_args, service_process_auth_source_init(process, fd[0]); (void)close(fd[1]); break; + case SERVICE_TYPE_ANVIL: + service_anvil_process_created(service); + /* fall through */ default: process = i_new(struct service_process, 1); process->service = service; @@ -602,6 +606,9 @@ void service_process_destroy(struct service_process *process) case SERVICE_TYPE_AUTH_SOURCE: service_process_auth_source_deinit(process); break; + case SERVICE_TYPE_ANVIL: + service_anvil_process_destroyed(service); + break; default: break; } diff --git a/src/master/service.h b/src/master/service.h index a755a5862d..76751fb0f5 100644 --- a/src/master/service.h +++ b/src/master/service.h @@ -121,6 +121,7 @@ struct service_list { /* used by master process to notify about dying processes */ int nonblocking_anvil_fd[2]; struct service_process_notify *anvil_kills; + struct io *anvil_io_blocking, *anvil_io_nonblocking; ARRAY_DEFINE(services, struct service *);