rfc:socketactivation:activate.patch
diff --git a/sapi/fpm/fpm/fpm_sockets.c b/sapi/fpm/fpm/fpm_sockets.c
index f56b9cf..5027ace 100644
--- a/sapi/fpm/fpm/fpm_sockets.c
+++ b/sapi/fpm/fpm/fpm_sockets.c
@@ -19,6 +19,8 @@
 #include <string.h>
 #include <errno.h>
 #include <unistd.h>
+#include <systemd/sd-daemon.h>
+#include <systemd/sd-journal.h>
 
 #include "zlog.h"
 #include "fpm_arrays.h"
@@ -34,6 +36,7 @@ struct listening_socket_s {
 	int refcount;
 	int sock;
 	int type;
+	int preserve;
 	char *key;
 };
 
@@ -73,7 +76,7 @@ static void fpm_sockets_cleanup(int which, void *arg) /* {{{ */
 
 	for (i = 0; i < sockets_list.used; i++, ls++) {
 		if (which != FPM_CLEANUP_PARENT_EXEC) {
-			close(ls->sock);
+			if (ls->preserve != 1) close(ls->sock); /* avoid close if systemd-provided socket */
 		} else { /* on PARENT EXEC we want socket fds to be inherited through environment variable */
 			char fd[32];
 			sprintf(fd, "%d", ls->sock);
@@ -83,7 +86,7 @@ static void fpm_sockets_cleanup(int which, void *arg) /* {{{ */
 
 		if (which == FPM_CLEANUP_PARENT_EXIT_MAIN) {
 			if (ls->type == FPM_AF_UNIX) {
-				unlink(ls->key);
+				if (ls->preserve != 1) unlink(ls->key); /* avoid unlink if systemd-provided socket */
 			}
 		}
 		free(ls->key);
@@ -98,7 +101,7 @@ static void fpm_sockets_cleanup(int which, void *arg) /* {{{ */
 }
 /* }}} */
 
-static int fpm_sockets_hash_op(int sock, struct sockaddr *sa, char *key, int type, int op) /* {{{ */
+static int fpm_sockets_hash_op(int sock, struct sockaddr *sa, char *key, int type, int op, int preserve) /* {{{ */
 {
 	if (key == NULL) {
 		switch (type) {
@@ -155,6 +158,7 @@ static int fpm_sockets_hash_op(int sock, struct sockaddr *sa, char *key, int typ
 			ls->type = type;
 			ls->sock = sock;
 			ls->key = strdup(key);
+			ls->preserve = preserve;
 
 			return 0;
 		}
@@ -221,13 +225,13 @@ static int fpm_sockets_get_listening_socket(struct fpm_worker_pool_s *wp, struct
 {
 	int sock;
 
-	sock = fpm_sockets_hash_op(0, sa, 0, wp->listen_address_domain, FPM_GET_USE_SOCKET);
+	sock = fpm_sockets_hash_op(0, sa, 0, wp->listen_address_domain, FPM_GET_USE_SOCKET, /* (systemd) preserve= */ 0);
 	if (sock >= 0) {
 		return sock;
 	}
 
 	sock = fpm_sockets_new_listening_socket(wp, sa, socklen);
-	fpm_sockets_hash_op(sock, sa, 0, wp->listen_address_domain, FPM_STORE_USE_SOCKET);
+	fpm_sockets_hash_op(sock, sa, 0, wp->listen_address_domain, FPM_STORE_USE_SOCKET, /* (systemd) preserve= */ 0);
 
 	return sock;
 }
@@ -301,7 +305,10 @@ static int fpm_socket_af_unix_listening_socket(struct fpm_worker_pool_s *wp) /*
 
 int fpm_sockets_init_main() /* {{{ */
 {
+	int sd_sock_count;
 	unsigned i, lq_len;
+	struct sockaddr_un address;
+	socklen_t address_len;
 	struct fpm_worker_pool_s *wp;
 	char *inherited = getenv("FPM_SOCKETS");
 	struct listening_socket_s *ls;
@@ -310,12 +317,32 @@ int fpm_sockets_init_main() /* {{{ */
 		return -1;
 	}
 
+	/* Is systemd providing any sockets? */
+	sd_sock_count = sd_listen_fds(0);
+	if (sd_sock_count < 0) sd_sock_count = 0; /* can return -errno, so set to zero */
+	
+	/* For each systemd-provided socket, get type and address and store it */
+	for (i = SD_LISTEN_FDS_START; i < SD_LISTEN_FDS_START + sd_sock_count; i++) {
+		int type, fd_no;
+
+		fd_no = i;
+		address_len = sizeof(struct sockaddr_un);
+		if (getsockname(fd_no, (struct sockaddr *)&address, &address_len)) {
+			zlog(ZLOG_ERROR, "error getting sockname from systemd-provided socket: fd=%d", fd_no);
+			continue;
+		}
+		
+		type = fpm_sockets_domain_from_address(((struct sockaddr *)&address)->sa_data);
+		zlog(ZLOG_NOTICE, "using systemd-provided socket fd=%d, \"%s\"", fd_no, ((struct sockaddr *)&address)->sa_data);
+		fpm_sockets_hash_op(fd_no, (struct sockaddr *)&address, 0, type, FPM_STORE_SOCKET, /* (systemd) preserve= */ 1);
+	}
+	
 	/* import inherited sockets */
 	while (inherited && *inherited) {
 		char *comma = strchr(inherited, ',');
 		int type, fd_no;
 		char *eq;
-
+		
 		if (comma) {
 			*comma = '\0';
 		}
@@ -326,7 +353,7 @@ int fpm_sockets_init_main() /* {{{ */
 			fd_no = atoi(eq + 1);
 			type = fpm_sockets_domain_from_address(inherited);
 			zlog(ZLOG_NOTICE, "using inherited socket fd=%d, \"%s\"", fd_no, inherited);
-			fpm_sockets_hash_op(fd_no, 0, inherited, type, FPM_STORE_SOCKET);
+			fpm_sockets_hash_op(fd_no, 0, inherited, type, FPM_STORE_SOCKET, /* (systemd) preserve= */ 0);
 		}
 
 		if (comma) {
rfc/socketactivation/activate.patch.txt · Last modified: 2012/10/18 20:58 by davidstrauss