From: Tatsuo Ishii Date: Tue, 27 May 2025 10:15:54 +0000 (+0900) Subject: Fix watchdog receive socket creation without IPv6. X-Git-Url: http://git.postgresql.org/gitweb/?a=commitdiff_plain;h=7540d06245c7e35fd8c9e746454992bbedea2182;p=pgpool2.git Fix watchdog receive socket creation without IPv6. When IPv6 network is not available, it was possible that watchdog process won't start. Previously wd_create_recv_socket() issued elog(ERROR) if creation or handling IPv6 socket failed. Unfortunately at the time when wd_create_recv_socket() is called, the exception stack is not established, and elog happily converts ERROR to FATAL, which causes exiting watchdog process, thus exiting pgpool process. To fix this, the elog(ERROR) calls are changed to elog(LOG). Reported-by: Bo Peng (pengbo@sraoss.co.jp) Discussion: https://github.com/pgpool/pgpool2/issues/99 Backpatch-through: v4.6 --- diff --git a/src/watchdog/watchdog.c b/src/watchdog/watchdog.c index faab4e6e5..693793444 100644 --- a/src/watchdog/watchdog.c +++ b/src/watchdog/watchdog.c @@ -862,7 +862,6 @@ wd_create_recv_socket(int port) { int one = 1; int sock = -1; - int saved_errno; int gai_ret, n = 0, target_n = n; @@ -909,12 +908,10 @@ wd_create_recv_socket(int port) if ((sock = socket(walk->ai_family, walk->ai_socktype, walk->ai_protocol)) < 0) { /* socket create failed */ - saved_errno = errno; - freeaddrinfo(res); - errno = saved_errno; - ereport(ERROR, + ereport(LOG, (errmsg("failed to create watchdog receive socket"), errdetail("create socket failed with reason: \"%m\""))); + continue; } socket_set_nonblock(sock); @@ -922,77 +919,72 @@ wd_create_recv_socket(int port) if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &one, sizeof(one)) == -1) { /* setsockopt(SO_REUSEADDR) failed */ - saved_errno = errno; - freeaddrinfo(res); - close(sock); - errno = saved_errno; - ereport(ERROR, + ereport(LOG, (errmsg("failed to create watchdog receive socket"), errdetail("setsockopt(SO_REUSEADDR) failed with reason: \"%m\""))); + close(sock); + continue; } if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *) &one, sizeof(one)) == -1) { /* setsockopt(TCP_NODELAY) failed */ - saved_errno = errno; - freeaddrinfo(res); - close(sock); - errno = saved_errno; - ereport(ERROR, + ereport(LOG, (errmsg("failed to create watchdog receive socket"), errdetail("setsockopt(TCP_NODELAY) failed with reason: \"%m\""))); + close(sock); + continue; } if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (char *) &one, sizeof(one)) == -1) { /* setsockopt(SO_KEEPALIVE) failed */ - saved_errno = errno; - freeaddrinfo(res); - close(sock); - errno = saved_errno; - ereport(ERROR, + ereport(LOG, (errmsg("failed to create watchdog receive socket"), errdetail("setsockopt(SO_KEEPALIVE) failed with reason: \"%m\""))); + close(sock); + continue; } if (walk->ai_family == AF_INET6) { if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(one)) == -1) { - saved_errno = errno; - freeaddrinfo(res); - close(sock); - errno = saved_errno; - ereport(ERROR, + ereport(LOG, (errmsg("failed to set IPPROTO_IPV6 option to watchdog receive socket"), errdetail("setsockopt(IPV6_V6ONLY) failed with reason: \"%m\""))); + close(sock); + continue; } } if (bind(sock, walk->ai_addr, walk->ai_addrlen) < 0) { /* bind failed */ - saved_errno = errno; - freeaddrinfo(res); - close(sock); - errno = saved_errno; - ereport(ERROR, + ereport(LOG, (errmsg("failed to create watchdog receive socket"), errdetail("bind on \"TCP:%d\" failed with reason: \"%m\"", port))); + close(sock); + continue; } if (listen(sock, MAX_WATCHDOG_NUM * 2) < 0) { /* listen failed */ - saved_errno = errno; - freeaddrinfo(res); - close(sock); - errno = saved_errno; - ereport(ERROR, + ereport(LOG, (errmsg("failed to create watchdog receive socket"), errdetail("listen failed with reason: \"%m\""))); + close(sock); + continue; } socks = lappend_int(socks, sock); n++; } + /* + * Fatal error. No recevive sockets were created. + */ + if (n == 0) + ereport(FATAL, + (errmsg("failed to create any of watchdog receive sockets"))); + if (target_n != n) ereport(WARNING, (errmsg("failed to create watchdog receive socket as much intended"),