Fix exit signal handlers to not call ereport.
authorTatsuo Ishii <ishii@postgresql.org>
Fri, 22 Sep 2017 01:51:45 +0000 (10:51 +0900)
committerTatsuo Ishii <ishii@postgresql.org>
Fri, 22 Sep 2017 02:01:43 +0000 (11:01 +0900)
There could be a race condition in the exit signal handlers. While
ereport is called in the handler, other interruption could call
ereport again. If ereport calls tz_convert which tries to acquire a
lock, it goes into a deadlock situation. In other word, tz_convert is
not reentrant and should not be used in signal handlers. So I removed
all ereport calls from exit signal handlers.

BTW pcp main calls ereport before the exception handler is
established. This could cause problem of course. So I fixed this
together. See [pgpool-hackers: 2545] for more details.

src/main/pgpool_main.c
src/pcp_con/pcp_child.c

index 1f3dab3724d337d427f70014a63c7683a065f68a..cb3bac54ecfe078206591dbe10465638694a9907 100644 (file)
@@ -1302,6 +1302,7 @@ static RETSIGTYPE exit_handler(int sig)
 {
        int i;
     pid_t wpid;
+       int *walk;
 
        int save_errno = errno;
        POOL_SETMASK(&AuthBlockSig);
@@ -1312,28 +1313,12 @@ static RETSIGTYPE exit_handler(int sig)
         */
        if (getpid() != mypid)
        {
-               ereport(DEBUG1,
-                       (errmsg("exit_handler: I am not parent")));
-
                POOL_SETMASK(&UnBlockSig);
                proc_exit(0);
        }
 
-       if (sig == SIGTERM)
-               ereport(LOG,
-                (errmsg("received smart shutdown request")));
-       else if (sig == SIGINT)
-               ereport(LOG,
-                (errmsg("received fast shutdown request")));
-       else if (sig == SIGQUIT)
-               ereport(LOG,
-                (errmsg("received immediate shutdown request")));
-       else
+       if (sig != SIGTERM && sig != SIGINT && sig != SIGQUIT)
        {
-               ereport(LOG,
-                       (errmsg("main process received unknown signal: %d",sig),
-                                errdetail("ignoring...")));
-
                POOL_SETMASK(&UnBlockSig);
                errno = save_errno;
                return;
@@ -1342,10 +1327,6 @@ static RETSIGTYPE exit_handler(int sig)
     processState = EXITING;
 
     /* Close listen socket */
-       ereport(LOG,
-               (errmsg("shutdown request. closing listen socket")));
-
-       int *walk;
        for (walk = fds; *walk != -1; walk++)
                close(*walk);
 
@@ -1394,14 +1375,8 @@ static RETSIGTYPE exit_handler(int sig)
         wpid = waitpid(-1, &ret_pid, 0);
     } while (wpid > 0 || (wpid == -1 && errno == EINTR));
 
-    if (wpid == -1 && errno != ECHILD)
-        ereport(LOG,
-                (errmsg("wait() failed. reason:%s", strerror(errno))));
-
        process_info = NULL;
        exit(0);
-
-       errno = save_errno;
 }
 
 /*
index fbabdc5bff023278901a9b04756a36ee7189724e..5c919fbfb195b9204cd882e63c499f1c29eb8a83 100644 (file)
@@ -101,9 +101,6 @@ void pcp_main(int unix_fd, int inet_fd)
        sigjmp_buf      local_sigjmp_buf;
        struct timeval uptime;
 
-       ereport(DEBUG1,
-                       (errmsg("I am PCP child with pid:%d",getpid())));
-
        /* Identify myself via ps */
        init_ps_display("", "", "", "");
 
@@ -143,6 +140,10 @@ void pcp_main(int unix_fd, int inet_fd)
        }
        /* We can now handle ereport(ERROR) */
        PG_exception_stack = &local_sigjmp_buf;
+
+       ereport(DEBUG1,
+                       (errmsg("I am PCP child with pid:%d",getpid())));
+
        for(;;)
        {
                int port;
@@ -354,29 +355,15 @@ pcp_exit_handler(int sig)
        pid_t wpid;
 
        POOL_SETMASK(&AuthBlockSig);
-       ereport(DEBUG1,
-                       (errmsg("PCP child receives shutdown request signal %d, Forwarding to all children", sig)));
 
        pcp_kill_all_children(sig);
 
        if (sig == SIGTERM) /* smart shutdown */
        {
-               ereport(DEBUG1,
-                               (errmsg("PCP child receives smart shutdown request")));
                /* close the listening sockets */
                close(pcp_unix_fd);
                close(pcp_inet_fd);
        }
-       else if (sig == SIGINT)
-       {
-               ereport(DEBUG1,
-                               (errmsg("PCP child receives fast shutdown request")));
-       }
-       else if (sig == SIGQUIT)
-       {
-               ereport(DEBUG1,
-                               (errmsg("PCP child receives immediate shutdown request")));
-       }
 
        POOL_SETMASK(&UnBlockSig);
 
@@ -387,9 +374,6 @@ pcp_exit_handler(int sig)
                        wpid = wait(NULL);
                }while (wpid > 0 || (wpid == -1 && errno == EINTR));
                
-               if (wpid == -1 && errno != ECHILD)
-                       ereport(WARNING,
-                                       (errmsg("wait() on pcp worker children failed. reason:%s", strerror(errno))));
                list_free(pcp_worker_children);
        }
        pcp_worker_children = NULL;