[pgpool-committers: 821] pgpool: Fix connect_inet_domain_socket_by_port() bug introduced in 3.2.

Tatsuo Ishii ishii at postgresql.org
Sat Feb 16 18:26:59 JST 2013

Fix connect_inet_domain_socket_by_port() bug introduced in 3.2.2.

When non blocking connect() reports EINPROGRESS or EALREADY, it calls
select(2) to wait for read or write fd ready. However it mistakenly
checks error condition using getsockopt(). It should be called when
select() returns > 0, rather than 0. Because of this,
connect_inet_domain_socket_by_port() could return succeeded fd even it
actually failed.

And what is worse, this health_check() mistakenly believes that
backend is alive and tries to write to backend socket, which of course
fails. This triggers to call notice_backend_error(), which sends
SIGUSR1 signal to pgpool main's parent process. This will result in
various weird things: for example, if you start pgpool from a shell,
the signal kills the shell.  If you start pgpool in background,
pgpool's parent is the process #1. As long as you started pgpool as
non root, it's ok. Even if you start pgpool as root, init just reopens
/dev/initctl by receiving SIGUSR1. These all annoying bugs have been
there since pgpool was born. The connect_inet_domain_socket_by_port()
bug just reveals it. To fix this, I modified notice_backend_error and
child_exit() so that it does nothing when called from pgpool main
process itself to prevent pgpool from shooting itself in the foot.



Modified Files
child.c                |    8 +++++++-
main.c                 |   11 +++++++++--
pool_connection_pool.c |    6 ++++--
3 files changed, 20 insertions(+), 5 deletions(-)

More information about the pgpool-committers mailing list