pgpool2.git / summary / log / commit / refs

commit    e18632ebed7069243d919293cc4e3aa760c3d91a
Author:   Tatsuo Ishii <ishii@postgresql.org>
Date:     Fri Sep 22 01:51:45 2017 +0000

    Fix exit signal handlers to not call ereport.
    
    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 | 29 ++--------------------------- src/pcp_con/pcp_child.c | 24 ++++-------------------- 2 files changed, 6 insertions(+), 47 deletions(-) diff --git a/src/main/pgpool_main.c b/src/main/pgpool_main.c index 1f3dab372..cb3bac54e 100644 --- a/src/main/pgpool_main.c +++ b/src/main/pgpool_main.c @@ -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; } /* diff --git a/src/pcp_con/pcp_child.c b/src/pcp_con/pcp_child.c index fbabdc5bf..5c919fbfb 100644 --- a/src/pcp_con/pcp_child.c +++ b/src/pcp_con/pcp_child.c @@ -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; [parent: 3cc5235a4c9b]