dovecot-2.2: master: Changed passing of listener settings from m...

dovecot at dovecot.org dovecot at dovecot.org
Tue Aug 18 18:02:14 UTC 2015


details:   http://hg.dovecot.org/dovecot-2.2/rev/52368e60177c
changeset: 18951:52368e60177c
user:      Timo Sirainen <tss at iki.fi>
date:      Tue Aug 18 20:23:45 2015 +0300
description:
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.

diffstat:

 src/lib-master/master-service-private.h |   12 +-
 src/lib-master/master-service.c         |  138 +++++++++++++++----------------
 src/master/service-process.c            |   44 +++------
 3 files changed, 90 insertions(+), 104 deletions(-)

diffs (truncated from 334 to 300 lines):

diff -r a0e8c6b88072 -r 52368e60177c src/lib-master/master-service-private.h
--- 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;
diff -r a0e8c6b88072 -r 52368e60177c src/lib-master/master-service.c
--- 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;
 		}
 	}
 }
diff -r a0e8c6b88072 -r 52368e60177c src/master/service-process.c
--- 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');
+	/* add listeners */
+	listener_settings = t_str_new(256);
+	for (i = 0; i < count; i++) {
+		if (listeners[i]->fd != -1) {
+			str_truncate(listener_settings, 0);
+			str_append_tabescaped(listener_settings, listeners[i]->name);
 
-	/* first add non-ssl listeners */
-	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]->type == SERVICE_LISTENER_INET) {
+				if (listeners[i]->set.inetset.set->ssl)
+					str_append(listener_settings, "\tssl");


More information about the dovecot-cvs mailing list