From: Pavan Deolasee Date: Mon, 11 Feb 2019 08:39:23 +0000 (+0530) Subject: Close listen sockets when pooler exits and remove the socket files X-Git-Tag: XL_10_R1_1~5 X-Git-Url: http://git.postgresql.org/gitweb/static/gitweb.js?a=commitdiff_plain;h=a2bad8b42bd237f1ff0614be11ab2e6b6e1448bf;p=postgres-xl.git Close listen sockets when pooler exits and remove the socket files --- diff --git a/src/backend/pgxc/pool/poolcomm.c b/src/backend/pgxc/pool/poolcomm.c index ddc58b4a96..c496086a6f 100644 --- a/src/backend/pgxc/pool/poolcomm.c +++ b/src/backend/pgxc/pool/poolcomm.c @@ -32,6 +32,7 @@ #include "storage/ipc.h" #include "utils/elog.h" #include "miscadmin.h" +#include "nodes/pg_list.h" static int pool_recvbuf(PoolPort *port); static int pool_discardbytes(PoolPort *port, size_t len); @@ -44,11 +45,11 @@ static int pool_discardbytes(PoolPort *port, size_t len); DEFAULT_PGSOCKET_DIR, \ (port)) -static char sock_path[MAXPGPATH]; +static List *sock_paths = NIL; static void StreamDoUnlink(int code, Datum arg); -static int Lock_AF_UNIX(unsigned short port, const char *unixSocketName); +static int Lock_AF_UNIX(const char *unixSocketPath); #endif /* @@ -61,10 +62,12 @@ pool_listen(unsigned short port, const char *unixSocketName) len; struct sockaddr_un unix_addr; int maxconn; - + char sock_path[MAXPGPATH]; #ifdef HAVE_UNIX_SOCKETS - if (Lock_AF_UNIX(port, unixSocketName) < 0) + POOLER_UNIXSOCK_PATH(sock_path, port, unixSocketName); + + if (Lock_AF_UNIX(sock_path) < 0) return -1; /* create a Unix domain stream socket */ @@ -78,8 +81,6 @@ pool_listen(unsigned short port, const char *unixSocketName) len = sizeof(unix_addr.sun_family) + strlen(unix_addr.sun_path) + 1; - - /* bind the name to the descriptor */ if (bind(fd, (struct sockaddr *) & unix_addr, len) < 0) return -1; @@ -97,8 +98,6 @@ pool_listen(unsigned short port, const char *unixSocketName) if (listen(fd, maxconn) < 0) return -1; - - /* Arrange to unlink the socket file at exit */ on_proc_exit(StreamDoUnlink, 0); @@ -120,23 +119,54 @@ pool_listen(unsigned short port, const char *unixSocketName) static void StreamDoUnlink(int code, Datum arg) { - Assert(sock_path[0]); - unlink(sock_path); + ListCell *lc; + + foreach (lc, sock_paths) + { + char *path = (char *) lfirst(lc); + Assert(path); + unlink(path); + } } #endif /* HAVE_UNIX_SOCKETS */ #ifdef HAVE_UNIX_SOCKETS static int -Lock_AF_UNIX(unsigned short port, const char *unixSocketName) +Lock_AF_UNIX(const char *unixSocketPath) { - POOLER_UNIXSOCK_PATH(sock_path, port, unixSocketName); + CreateSocketLockFile(unixSocketPath, true, ""); - CreateSocketLockFile(sock_path, true, ""); + /* + * Once we have the interlock, we can safely delete any pre-existing + * socket file to avoid failure at bind() time. + */ + unlink(unixSocketPath); - unlink(sock_path); + /* Remember socket path for later maintenance. */ + sock_paths = lappend(sock_paths, pstrdup(unixSocketPath)); return 0; } + +/* + * RemoveSocketFiles -- unlink socket files at pooler shutdown + */ +void +RemovePoolerSocketFiles(void) +{ + ListCell *l; + + /* Loop through all created sockets... */ + foreach(l, sock_paths) + { + char *sock_path = (char *) lfirst(l); + + /* Ignore any error. */ + (void) unlink(sock_path); + } + /* Since we're about to exit, no need to reclaim storage */ + sock_paths = NIL; +} #endif /* @@ -148,6 +178,7 @@ pool_connect(unsigned short port, const char *unixSocketName) int fd, len; struct sockaddr_un unix_addr; + char sock_path[MAXPGPATH]; #ifdef HAVE_UNIX_SOCKETS /* create a Unix domain stream socket */ diff --git a/src/backend/pgxc/pool/poolmgr.c b/src/backend/pgxc/pool/poolmgr.c index 2464b68233..26f3450dd1 100644 --- a/src/backend/pgxc/pool/poolmgr.c +++ b/src/backend/pgxc/pool/poolmgr.c @@ -349,6 +349,8 @@ static int is_pool_locked = false; static int PoolListenSockets[POOLER_MAXLISTEN]; static int PoolListenSocketsCount = 0; +#define POOLER_INVALIDSOCK -1 + static int node_info_check(PoolAgent *agent); static void agent_init(PoolAgent *agent, const char *database, const char *user_name, const char *pgoptions); @@ -1014,6 +1016,22 @@ agent_destroy(PoolAgent *agent) } } +/* + * on_proc_exit callback to close pooler's listen sockets + */ +static void +ClosePoolerPorts(int status, Datum arg) +{ + int i; + + for (i = 0; i < PoolListenSocketsCount; i++) + { + if (PoolListenSockets[i] != POOLER_INVALIDSOCK) + close(PoolListenSockets[i]); + } + RemovePoolerSocketFiles(); +} + /* * TryPingUnhealthyNode * Try pinging a node marked as unhealthy, and update shared info. @@ -3191,6 +3209,11 @@ PoolerLoop(void) "unix_socket_directories"))); } + for (i = 0; i < POOLER_MAXLISTEN; i++) + PoolListenSockets[i] = POOLER_INVALIDSOCK; + + on_proc_exit(ClosePoolerPorts, 0); + foreach(l, elemlist) { char *socketdir = (char *) lfirst(l); @@ -3314,12 +3337,7 @@ PoolerLoop(void) databasePools->user_name) == 0) break; - for (i = 0; i < PoolListenSocketsCount; i++) - { - if (PoolListenSockets[i] != 0) - close(PoolListenSockets[i]); - } - exit(0); + proc_exit(0); } /* wait for event */ diff --git a/src/include/pgxc/poolcomm.h b/src/include/pgxc/poolcomm.h index 98a62ee2ad..d706af21bd 100644 --- a/src/include/pgxc/poolcomm.h +++ b/src/include/pgxc/poolcomm.h @@ -49,4 +49,5 @@ extern int pool_recvres(PoolPort *port); extern int pool_sendpids(PoolPort *port, int *pids, int count); extern int pool_recvpids(PoolPort *port, int **pids); +extern void RemovePoolerSocketFiles(void); #endif /* POOLCOMM_H */