pgpool2.git / summary / log / commit / refs
commit ae8924fa4af62076b0524c5eb69f06998b9b9e4b
Author: Tatsuo Ishii <ishii at sraoss.co.jp>
Date: Wed Mar 03 00:31:39 2010 +0000
Fix bug with healh checking. If a network problem such as unplugged
wire happens while calling connect(), health checking does not work
since connect_unix_domain_socket()/connect_inet_domain_socket() do
retry if connect() is interrupted by ALARM signal. Added new retry
argument which controls the retrying behavior to those functions.
Per bug report and problem analysis by Daniel Codina.
See following message for more details.
Subject: [Pgpool-general] The Unplugged wire
Date: Mon, 1 Mar 2010 15:19:00 +0100
child.c | 8 ++++----
main.c | 8 ++++----
pool.h | 8 ++++----
pool_connection_pool.c | 28 ++++++++++++++++++----------
4 files changed, 30 insertions(+), 22 deletions(-)
diff --git a/child.c b/child.c
index 046501b33..b2dbd2785 100644
--- a/child.c
+++ b/child.c
@@ -1090,9 +1090,9 @@ void cancel_request(CancelPacket *sp)
continue;
if (*(BACKEND_INFO(i).backend_hostname) == '\0')
- fd = connect_unix_domain_socket(i);
+ fd = connect_unix_domain_socket(i, TRUE);
else
- fd = connect_inet_domain_socket(i);
+ fd = connect_inet_domain_socket(i, TRUE);
if (fd < 0)
{
@@ -1403,11 +1403,11 @@ POOL_CONNECTION_POOL_SLOT *make_persistent_db_connection(
*/
if (*hostname == '\0')
{
- fd = connect_unix_domain_socket_by_port(port, pool_config->backend_socket_dir);
+ fd = connect_unix_domain_socket_by_port(port, pool_config->backend_socket_dir, TRUE);
}
else
{
- fd = connect_inet_domain_socket_by_port(hostname, port);
+ fd = connect_inet_domain_socket_by_port(hostname, port, TRUE);
}
if (fd < 0)
diff --git a/main.c b/main.c
index 9974444f5..acd2de3cb 100644
--- a/main.c
+++ b/main.c
@@ -1538,9 +1538,9 @@ int health_check(void)
continue;
if (*(BACKEND_INFO(i).backend_hostname) == '\0')
- fd = connect_unix_domain_socket(i);
+ fd = connect_unix_domain_socket(i, FALSE);
else
- fd = connect_inet_domain_socket(i);
+ fd = connect_inet_domain_socket(i, FALSE);
if (fd < 0)
{
@@ -1650,9 +1650,9 @@ system_db_health_check(void)
return 0;
if (*SYSDB_INFO->hostname == '\0')
- fd = connect_unix_domain_socket_by_port(SYSDB_INFO->port, pool_config->backend_socket_dir);
+ fd = connect_unix_domain_socket_by_port(SYSDB_INFO->port, pool_config->backend_socket_dir, FALSE);
else
- fd = connect_inet_domain_socket_by_port(SYSDB_INFO->hostname, SYSDB_INFO->port);
+ fd = connect_inet_domain_socket_by_port(SYSDB_INFO->hostname, SYSDB_INFO->port, FALSE);
if (fd < 0)
{
diff --git a/pool.h b/pool.h
index cd8566278..d422106ef 100644
--- a/pool.h
+++ b/pool.h
@@ -571,10 +571,10 @@ extern void send_failback_request(int node_id);
extern void pool_connection_pool_timer(POOL_CONNECTION_POOL *backend);
extern RETSIGTYPE pool_backend_timer_handler(int sig);
-extern int connect_inet_domain_socket(int secondary_backend);
-extern int connect_unix_domain_socket(int secondary_backend);
-extern int connect_inet_domain_socket_by_port(char *host, int port);
-extern int connect_unix_domain_socket_by_port(int port, char *socket_dir);
+extern int connect_inet_domain_socket(int slot, bool retry);
+extern int connect_unix_domain_socket(int slot, bool retry);
+extern int connect_inet_domain_socket_by_port(char *host, int port, bool retry);
+extern int connect_unix_domain_socket_by_port(int port, char *socket_dir, bool retry);
extern void pool_set_timeout(int timeoutval);
extern int pool_check_fd(POOL_CONNECTION *cp);
diff --git a/pool_connection_pool.c b/pool_connection_pool.c
index 69794b78d..3e2732708 100644
--- a/pool_connection_pool.c
+++ b/pool_connection_pool.c
@@ -410,7 +410,7 @@ void pool_backend_timer(void)
/*
* connect to postmaster through INET domain socket
*/
-int connect_inet_domain_socket(int slot)
+int connect_inet_domain_socket(int slot, bool retry)
{
char *host;
int port;
@@ -418,13 +418,13 @@ int connect_inet_domain_socket(int slot)
host = pool_config->backend_desc->backend_info[slot].backend_hostname;
port = pool_config->backend_desc->backend_info[slot].backend_port;
- return connect_inet_domain_socket_by_port(host, port);
+ return connect_inet_domain_socket_by_port(host, port, retry);
}
/*
* connect to postmaster through UNIX domain socket
*/
-int connect_unix_domain_socket(int slot)
+int connect_unix_domain_socket(int slot, bool retry)
{
int port;
char *socket_dir;
@@ -432,10 +432,14 @@ int connect_unix_domain_socket(int slot)
port = pool_config->backend_desc->backend_info[slot].backend_port;
socket_dir = pool_config->backend_socket_dir;
- return connect_unix_domain_socket_by_port(port, socket_dir);
+ return connect_unix_domain_socket_by_port(port, socket_dir, retry);
}
-int connect_unix_domain_socket_by_port(int port, char *socket_dir)
+/*
+ * Connect to PostgreSQL server by using UNIX domain socket.
+ * If retry is true, retry to call connect() upon receiving EINTR error.
+ */
+int connect_unix_domain_socket_by_port(int port, char *socket_dir, bool retry)
{
struct sockaddr_un addr;
int fd;
@@ -457,7 +461,7 @@ int connect_unix_domain_socket_by_port(int port, char *socket_dir)
{
if (connect(fd, (struct sockaddr *)&addr, len) < 0)
{
- if (errno == EINTR || errno == EAGAIN)
+ if ((errno == EINTR && retry) || errno == EAGAIN)
continue;
pool_error("connect_unix_domain_socket_by_port: connect() failed: %s", strerror(errno));
@@ -470,7 +474,11 @@ int connect_unix_domain_socket_by_port(int port, char *socket_dir)
return fd;
}
-int connect_inet_domain_socket_by_port(char *host, int port)
+/*
+ * Connect to PostgreSQL server by using INET domain socket.
+ * If retry is true, retry to call connect() upon receiving EINTR error.
+ */
+int connect_inet_domain_socket_by_port(char *host, int port, bool retry)
{
int fd;
int len;
@@ -516,7 +524,7 @@ int connect_inet_domain_socket_by_port(char *host, int port)
{
if (connect(fd, (struct sockaddr *)&addr, len) < 0)
{
- if (errno == EINTR || errno == EAGAIN)
+ if ((errno == EINTR && retry) || errno == EAGAIN)
continue;
pool_error("connect_inet_domain_socket: connect() failed: %s",strerror(errno));
@@ -539,11 +547,11 @@ static POOL_CONNECTION_POOL_SLOT *create_cp(POOL_CONNECTION_POOL_SLOT *cp, int s
if (*b->backend_hostname == '\0')
{
- fd = connect_unix_domain_socket(slot);
+ fd = connect_unix_domain_socket(slot, TRUE);
}
else
{
- fd = connect_inet_domain_socket(slot);
+ fd = connect_inet_domain_socket(slot, TRUE);
}
if (fd < 0)
[parent: 48b86b3e2d8e]