Close listen sockets when pooler exits and remove the socket files
authorPavan Deolasee <[email protected]>
Mon, 11 Feb 2019 08:39:23 +0000 (14:09 +0530)
committerPavan Deolasee <[email protected]>
Mon, 18 Feb 2019 05:35:38 +0000 (11:05 +0530)
src/backend/pgxc/pool/poolcomm.c
src/backend/pgxc/pool/poolmgr.c
src/include/pgxc/poolcomm.h

index ddc58b4a9648f7b242d2e680de052c030a462fbe..c496086a6ff48407af8dbab691b9d2fe4e35c7de 100644 (file)
@@ -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 */
index 2464b682330dd46da4fd9fcb16b11bc2729a700f..26f3450dd12bcc29511738eada4ee1d81726c530 100644 (file)
@@ -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 */
index 98a62ee2add58c25354c4c730f15c6fd784285da..d706af21bd24f5e3f43cdea67171efb54487b9b2 100644 (file)
@@ -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 */