mirror of
https://github.com/postgres/postgres.git
synced 2025-05-01 01:04:50 +03:00
Make creation of statistics collection socket more robust, by allowing it
to try additional addresses returned from getaddrinfo() if the first one fails at the bind() or connect() steps. Per yesterday's discussion.
This commit is contained in:
parent
472d9726dd
commit
5b6b587a95
@ -13,7 +13,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 2001-2003, PostgreSQL Global Development Group
|
* Copyright (c) 2001-2003, PostgreSQL Global Development Group
|
||||||
*
|
*
|
||||||
* $Header: /cvsroot/pgsql/src/backend/postmaster/pgstat.c,v 1.46 2003/11/07 21:55:50 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/postmaster/pgstat.c,v 1.47 2003/11/15 17:24:07 tgl Exp $
|
||||||
* ----------
|
* ----------
|
||||||
*/
|
*/
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
@ -203,6 +203,14 @@ pgstat_init(void)
|
|||||||
goto startup_failed;
|
goto startup_failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* On some platforms, getaddrinfo_all() may return multiple addresses
|
||||||
|
* only one of which will actually work (eg, both IPv6 and IPv4 addresses
|
||||||
|
* when kernel will reject IPv6). Worse, the failure may occur at the
|
||||||
|
* bind() or perhaps even connect() stage. So we must loop through the
|
||||||
|
* results till we find a working combination. We will generate LOG
|
||||||
|
* messages, but no error, for bogus combinations.
|
||||||
|
*/
|
||||||
for (addr = addrs; addr; addr = addr->ai_next)
|
for (addr = addrs; addr; addr = addr->ai_next)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_UNIX_SOCKETS
|
#ifdef HAVE_UNIX_SOCKETS
|
||||||
@ -210,16 +218,15 @@ pgstat_init(void)
|
|||||||
if (addr->ai_family == AF_UNIX)
|
if (addr->ai_family == AF_UNIX)
|
||||||
continue;
|
continue;
|
||||||
#endif
|
#endif
|
||||||
if ((pgStatSock = socket(addr->ai_family, SOCK_DGRAM, 0)) >= 0)
|
/*
|
||||||
break;
|
* Create the socket.
|
||||||
}
|
*/
|
||||||
|
if ((pgStatSock = socket(addr->ai_family, SOCK_DGRAM, 0)) < 0)
|
||||||
if (!addr || pgStatSock < 0)
|
|
||||||
{
|
{
|
||||||
ereport(LOG,
|
ereport(LOG,
|
||||||
(errcode_for_socket_access(),
|
(errcode_for_socket_access(),
|
||||||
errmsg("could not create socket for statistics collector: %m")));
|
errmsg("could not create socket for statistics collector: %m")));
|
||||||
goto startup_failed;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -231,19 +238,20 @@ pgstat_init(void)
|
|||||||
ereport(LOG,
|
ereport(LOG,
|
||||||
(errcode_for_socket_access(),
|
(errcode_for_socket_access(),
|
||||||
errmsg("could not bind socket for statistics collector: %m")));
|
errmsg("could not bind socket for statistics collector: %m")));
|
||||||
goto startup_failed;
|
closesocket(pgStatSock);
|
||||||
|
pgStatSock = -1;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
freeaddrinfo_all(hints.ai_family, addrs);
|
|
||||||
addrs = NULL;
|
|
||||||
|
|
||||||
alen = sizeof(pgStatAddr);
|
alen = sizeof(pgStatAddr);
|
||||||
if (getsockname(pgStatSock, (struct sockaddr *) & pgStatAddr, &alen) < 0)
|
if (getsockname(pgStatSock, (struct sockaddr *) &pgStatAddr, &alen) < 0)
|
||||||
{
|
{
|
||||||
ereport(LOG,
|
ereport(LOG,
|
||||||
(errcode_for_socket_access(),
|
(errcode_for_socket_access(),
|
||||||
errmsg("could not get address of socket for statistics collector: %m")));
|
errmsg("could not get address of socket for statistics collector: %m")));
|
||||||
goto startup_failed;
|
closesocket(pgStatSock);
|
||||||
|
pgStatSock = -1;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -252,11 +260,26 @@ pgstat_init(void)
|
|||||||
* provides a kernel-level check that only packets from this same
|
* provides a kernel-level check that only packets from this same
|
||||||
* address will be received.
|
* address will be received.
|
||||||
*/
|
*/
|
||||||
if (connect(pgStatSock, (struct sockaddr *) & pgStatAddr, alen) < 0)
|
if (connect(pgStatSock, (struct sockaddr *) &pgStatAddr, alen) < 0)
|
||||||
{
|
{
|
||||||
ereport(LOG,
|
ereport(LOG,
|
||||||
(errcode_for_socket_access(),
|
(errcode_for_socket_access(),
|
||||||
errmsg("could not connect socket for statistics collector: %m")));
|
errmsg("could not connect socket for statistics collector: %m")));
|
||||||
|
closesocket(pgStatSock);
|
||||||
|
pgStatSock = -1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we get here, we have a working socket */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Did we find a working address? */
|
||||||
|
if (!addr || pgStatSock < 0)
|
||||||
|
{
|
||||||
|
ereport(LOG,
|
||||||
|
(errcode_for_socket_access(),
|
||||||
|
errmsg("disabling statistics collector for lack of working socket")));
|
||||||
goto startup_failed;
|
goto startup_failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -285,6 +308,8 @@ pgstat_init(void)
|
|||||||
goto startup_failed;
|
goto startup_failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
freeaddrinfo_all(hints.ai_family, addrs);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
startup_failed:
|
startup_failed:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user