Fix a posible hang during health checking
authorYugo Nagata <nagata@sraoss.co.jp>
Wed, 15 Jun 2016 06:24:21 +0000 (15:24 +0900)
committerYugo Nagata <nagata@sraoss.co.jp>
Wed, 15 Jun 2016 06:24:21 +0000 (15:24 +0900)
Helath checking was hang when any data wasn't sent
from backend after connect(2) succeeded. To fix this,
pool_check_fd() returns 1 when select(2) exits with
EINTR due to SIGALRM while health checkking is performed.

Reported and patch provided by harukat and some modification
by Yugo. Per bug #204.

backported from 3.4 or later;
https://git.postgresql.org/gitweb/?p=pgpool2.git;a=commitdiff;h=ed9f2900f1b611f5cfd52e8f758c3616861e60c0

pool_process_query.c

index 73d5f4162e32891bc734ac5afccbe9e1d7112daa..ef2b62e576fb64a3275aa68db6de8263f56956f4 100644 (file)
@@ -920,6 +920,7 @@ int pool_check_fd(POOL_CONNECTION *cp)
        int fds;
        struct timeval timeout;
        struct timeval *timeoutp;
+       int save_errno;
 
        /*
         * If SSL is enabled, we need to check SSL internal buffer
@@ -949,8 +950,15 @@ int pool_check_fd(POOL_CONNECTION *cp)
                FD_SET(fd, &exceptmask);
 
                fds = select(fd+1, &readmask, NULL, &exceptmask, timeoutp);
+               save_errno = errno;
                if (fds == -1)
                {
+                       if (health_check_timer_expired && errno == EINTR)
+                       {
+                               pool_error("health check timed out while waiting for reading data");
+                               errno = save_errno;
+                               return 1;
+                       }
                        if (errno == EAGAIN || errno == EINTR)
                                continue;