Andrew Dunstan wrote:
Tom Lane wrote:
Andrew Dunstan <[EMAIL PROTECTED]> writes:
A small problem with it was reported to me a couple of days ago - user had firewalled off all IP6 traffic. The stats collector happily bound and connected to the socket, but all the packets fell in the bit bucket. They found it quite hard to diagnose the problem.
Possible solutions that occurred to me:
. an initial "hello"-"yes i'm here" exchange to validate the address
That one seems reasonable to me. Seems like it would take just a few more lines of code in the loop that tries to find a working socket to check that we can send a byte and receive it. You'd have to be careful not to block if the socket is indeed not working ... also, is it safe to assume that a byte sent with send() is *immediately* ready to recv()?
Revised patch attached. I think this is about as much trouble as this problem is worth ;-)
cheers
andrew
Index: src/backend/postmaster/pgstat.c =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/backend/postmaster/pgstat.c,v retrieving revision 1.61 diff -c -r1.61 pgstat.c *** src/backend/postmaster/pgstat.c 15 Mar 2004 16:21:37 -0000 1.61 --- src/backend/postmaster/pgstat.c 22 Mar 2004 12:47:54 -0000 *************** *** 191,196 **** --- 191,200 ---- *addr, hints; int ret; + fd_set rset; + struct timeval tv; + char test_byte; + int sel_res; /* * Force start of collector daemon if something to collect *************** *** 307,312 **** --- 311,365 ---- pgStatSock = -1; continue; } + + #define TESTBYTEVAL 99 + + /* try to send and receive a test byte on the socket */ + + test_byte = TESTBYTEVAL; + if (send(pgStatSock,&test_byte,1,0) != 1) + { + ereport(LOG, + (errcode_for_socket_access(), + errmsg("test byte send failure socket for statistics collector: %m"))); + closesocket(pgStatSock); + pgStatSock = -1; + continue; + } + test_byte++; + for(;;) + { + FD_ZERO(&rset); + FD_SET(pgStatSock, &rset); + tv.tv_sec = 0; + tv.tv_usec = 500000; + sel_res = select(pgStatSock+1,&rset,NULL,NULL,&tv); + if (sel_res != -1 || errno != EINTR) + break; + } + if( sel_res > 0 && FD_ISSET(pgStatSock,&rset) + && recv(pgStatSock,&test_byte,1,0) == 1) + { + if(test_byte != TESTBYTEVAL) + { + ereport(LOG, + (errcode_for_socket_access(), + errmsg("incorrect test value on send/receive on socket for statistics collector"))); + closesocket(pgStatSock); + pgStatSock = -1; + continue; + } + } + else + { + ereport(LOG, + (errcode_for_socket_access(), + errmsg("could receive test byte on socket for statistics collector: %m"))); + closesocket(pgStatSock); + pgStatSock = -1; + continue; + } + /* If we get here, we have a working socket */ break;
---------------------------(end of broadcast)--------------------------- TIP 7: don't forget to increase your free space map settings