Mercurial > dovecot > core-2.2
changeset 18951:52368e60177c
master: Changed passing of listener settings from master to process to be more flexible.
This is needed to allow adding new listener settings, such as `haproxy'.
Patch by Stephan Bosch - with some small changes.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Tue, 18 Aug 2015 20:23:45 +0300 |
parents | a0e8c6b88072 |
children | 4d7a83ddb644 |
files | src/lib-master/master-service-private.h src/lib-master/master-service.c src/master/service-process.c |
diffstat | 3 files changed, 90 insertions(+), 104 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-master/master-service-private.h Mon Jun 15 18:50:53 2015 +0200 +++ b/src/lib-master/master-service-private.h Tue Aug 18 20:23:45 2015 +0300 @@ -6,10 +6,14 @@ struct master_service_listener { struct master_service *service; - int fd; + char *name; + + /* settings */ bool ssl; + + /* state */ + int fd; struct io *io; - const char *name; }; struct master_service { @@ -28,10 +32,8 @@ int config_fd; int syslog_facility; - unsigned int socket_count, ssl_socket_count; struct master_service_listener *listeners; - char **listener_names; - unsigned int listener_names_count; + unsigned int socket_count; struct io *io_status_write, *io_status_error; unsigned int service_count_left;
--- a/src/lib-master/master-service.c Mon Jun 15 18:50:53 2015 +0200 +++ b/src/lib-master/master-service.c Tue Aug 18 20:23:45 2015 +0300 @@ -106,13 +106,53 @@ } } +static void master_service_init_socket_listeners(struct master_service *service) +{ + unsigned int i; + const char *value; + bool have_ssl_sockets = FALSE; + + if (service->socket_count == 0) + return; + + service->listeners = + i_new(struct master_service_listener, service->socket_count); + + for (i = 0; i < service->socket_count; i++) { + struct master_service_listener *l = &service->listeners[i]; + + l->service = service; + l->fd = MASTER_LISTEN_FD_FIRST + i; + + value = getenv(t_strdup_printf("SOCKET%u_SETTINGS", i)); + if (value != NULL) { + const char *const *settings = + t_strsplit_tabescaped(value); + + if (*settings != NULL) { + l->name = i_strdup_empty(*settings); + settings++; + } + while (*settings != NULL) { + if (strcmp(*settings, "ssl") == 0) { + l->ssl = TRUE; + have_ssl_sockets = TRUE; + } + settings++; + } + } + } + service->want_ssl_settings = have_ssl_sockets || + (service->flags & MASTER_SERVICE_FLAG_USE_SSL_SETTINGS) != 0; +} + struct master_service * master_service_init(const char *name, enum master_service_flags flags, int *argc, char **argv[], const char *getopt_str) { struct master_service *service; + unsigned int count; const char *value; - unsigned int count; i_assert(name != NULL); @@ -177,21 +217,14 @@ } else { service->version_string = PACKAGE_VERSION; } + + /* listener configuration */ value = getenv("SOCKET_COUNT"); if (value != NULL) service->socket_count = atoi(value); - value = getenv("SSL_SOCKET_COUNT"); - if (value != NULL) - service->ssl_socket_count = atoi(value); - value = getenv("SOCKET_NAMES"); - if (value != NULL) { - service->listener_names = - p_strsplit_tabescaped(default_pool, value); - service->listener_names_count = - str_array_length((void *)service->listener_names); - } - service->want_ssl_settings = service->ssl_socket_count > 0 || - (flags & MASTER_SERVICE_FLAG_USE_SSL_SETTINGS) != 0; + T_BEGIN { + master_service_init_socket_listeners(service); + } T_END; /* set up some kind of logging until we know exactly how and where we want to log */ @@ -574,8 +607,9 @@ i_assert(listen_fd >= MASTER_LISTEN_FD_FIRST); i = listen_fd - MASTER_LISTEN_FD_FIRST; - return i < service->listener_names_count ? - service->listener_names[i] : ""; + i_assert(i < service->socket_count); + return service->listeners[i].name != NULL ? + service->listeners[i].name : ""; } void master_service_set_avail_overflow_callback(struct master_service *service, @@ -807,6 +841,7 @@ void master_service_deinit(struct master_service **_service) { struct master_service *service = *_service; + unsigned int i; *_service = NULL; @@ -836,8 +871,8 @@ lib_atexit_run(); io_loop_destroy(&service->ioloop); - if (service->listener_names != NULL) - p_strsplit_free(default_pool, service->listener_names); + for (i = 0; i < service->socket_count; i++) + i_free(service->listeners[i].name); i_free(service->listeners); i_free(service->getopt_str); i_free(service->name); @@ -912,29 +947,6 @@ master_service_client_connection_callback(service, &conn); } -static void io_listeners_init(struct master_service *service) -{ - unsigned int i; - - if (service->socket_count == 0) - return; - - service->listeners = - i_new(struct master_service_listener, service->socket_count); - - for (i = 0; i < service->socket_count; i++) { - struct master_service_listener *l = &service->listeners[i]; - - l->service = service; - l->fd = MASTER_LISTEN_FD_FIRST + i; - l->name = i < service->listener_names_count ? - service->listener_names[i] : ""; - - if (i >= service->socket_count - service->ssl_socket_count) - l->ssl = TRUE; - } -} - void master_service_io_listeners_add(struct master_service *service) { unsigned int i; @@ -942,9 +954,6 @@ if (service->stopping) return; - if (service->listeners == NULL) - io_listeners_init(service); - for (i = 0; i < service->socket_count; i++) { struct master_service_listener *l = &service->listeners[i]; @@ -959,11 +968,9 @@ { unsigned int i; - if (service->listeners != NULL) { - for (i = 0; i < service->socket_count; i++) { - if (service->listeners[i].io != NULL) - io_remove(&service->listeners[i].io); - } + for (i = 0; i < service->socket_count; i++) { + if (service->listeners[i].io != NULL) + io_remove(&service->listeners[i].io); } } @@ -971,12 +978,10 @@ { unsigned int i; - if (service->listeners != NULL) { - for (i = 0; i < service->socket_count; i++) { - if (service->listeners[i].io != NULL && - service->listeners[i].ssl) - io_remove(&service->listeners[i].io); - } + for (i = 0; i < service->socket_count; i++) { + if (service->listeners[i].io != NULL && + service->listeners[i].ssl) + io_remove(&service->listeners[i].io); } } @@ -984,24 +989,15 @@ { unsigned int i; - if (service->listeners != NULL) { - /* close via listeners. some fds might be pipes that are - currently handled as clients. we don't want to close them. */ - for (i = 0; i < service->socket_count; i++) { - if (service->listeners[i].fd != -1) { - if (close(service->listeners[i].fd) < 0) { - i_error("close(listener %d) failed: %m", - service->listeners[i].fd); - } - service->listeners[i].fd = -1; + /* close via listeners. some fds might be pipes that are + currently handled as clients. we don't want to close them. */ + for (i = 0; i < service->socket_count; i++) { + if (service->listeners[i].fd != -1) { + if (close(service->listeners[i].fd) < 0) { + i_error("close(listener %d) failed: %m", + service->listeners[i].fd); } - } - } else { - for (i = 0; i < service->socket_count; i++) { - int fd = MASTER_LISTEN_FD_FIRST + i; - - if (close(fd) < 0) - i_error("close(listener %d) failed: %m", fd); + service->listeners[i].fd = -1; } } }
--- a/src/master/service-process.c Mon Jun 15 18:50:53 2015 +0200 +++ b/src/master/service-process.c Tue Aug 18 20:23:45 2015 +0300 @@ -58,9 +58,9 @@ { struct service_listener *const *listeners; ARRAY_TYPE(dup2) dups; - string_t *listener_names; + string_t *listener_settings; int fd = MASTER_LISTEN_FD_FIRST; - unsigned int i, count, socket_listener_count, ssl_socket_count; + unsigned int i, count, socket_listener_count; /* stdin/stdout is already redirected to /dev/null. Other master fds should have been opened with fd_close_on_exec() so we don't have to @@ -72,7 +72,6 @@ socket_listener_count = 0; listeners = array_get(&service->listeners, &count); t_array_init(&dups, count + 10); - listener_names = t_str_new(256); switch (service->type) { case SERVICE_TYPE_LOG: @@ -94,34 +93,25 @@ break; } - /* anvil/log fds have no names */ - for (i = MASTER_LISTEN_FD_FIRST; i < (unsigned int)fd; i++) - str_append_c(listener_names, '\t'); - - /* first add non-ssl listeners */ + /* add listeners */ + listener_settings = t_str_new(256); for (i = 0; i < count; i++) { - if (listeners[i]->fd != -1 && - (listeners[i]->type != SERVICE_LISTENER_INET || - !listeners[i]->set.inetset.set->ssl)) { - str_append_tabescaped(listener_names, listeners[i]->name); - str_append_c(listener_names, '\t'); + if (listeners[i]->fd != -1) { + str_truncate(listener_settings, 0); + str_append_tabescaped(listener_settings, listeners[i]->name); + + if (listeners[i]->type == SERVICE_LISTENER_INET) { + if (listeners[i]->set.inetset.set->ssl) + str_append(listener_settings, "\tssl"); + } + dup2_append(&dups, listeners[i]->fd, fd++); + + env_put(t_strdup_printf("SOCKET%d_SETTINGS=%s", + socket_listener_count, str_c(listener_settings))); socket_listener_count++; } } - /* then ssl-listeners */ - ssl_socket_count = 0; - for (i = 0; i < count; i++) { - if (listeners[i]->fd != -1 && - listeners[i]->type == SERVICE_LISTENER_INET && - listeners[i]->set.inetset.set->ssl) { - str_append_tabescaped(listener_names, listeners[i]->name); - str_append_c(listener_names, '\t'); - dup2_append(&dups, listeners[i]->fd, fd++); - socket_listener_count++; - ssl_socket_count++; - } - } if (service->login_notify_fd != -1) { dup2_append(&dups, service->login_notify_fd, @@ -174,8 +164,6 @@ i_assert(fd == MASTER_LISTEN_FD_FIRST + (int)socket_listener_count); env_put(t_strdup_printf("SOCKET_COUNT=%d", socket_listener_count)); - env_put(t_strdup_printf("SSL_SOCKET_COUNT=%d", ssl_socket_count)); - env_put(t_strdup_printf("SOCKET_NAMES=%s", str_c(listener_names))); } static void