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 #include #include +#include +#include #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) {