Skip to content

Commit f0256c7

Browse files
committed
Support tcp_keepalives_idle option on Solaris.
Turns out that the socket option for this is named TCP_KEEPALIVE_THRESHOLD, at least according to the tcp(7P) man page for Solaris 11. (But since that text refers to "SunOS", it's likely pretty ancient.) It appears that the symbol TCP_KEEPALIVE does get defined on that platform, but it doesn't seem to represent a valid protocol-level socket option. This leads to bleats in the postmaster log, and no tcp_keepalives_idle functionality. Per bug #14720 from Andrey Lizenko, as well as an earlier report from Dhiraj Chawla that nobody had followed up on. The issue's been there since we added the TCP_KEEPALIVE code path in commit 5acd417, so back-patch to all supported branches. Discussion: https://postgr.es/m/20170627163757.25161.528@wrigleys.postgresql.org
1 parent 9c7dc89 commit f0256c7

File tree

2 files changed

+48
-15
lines changed

2 files changed

+48
-15
lines changed

src/backend/libpq/pqcomm.c

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1676,7 +1676,7 @@ pq_setkeepaliveswin32(Port *port, int idle, int interval)
16761676
int
16771677
pq_getkeepalivesidle(Port *port)
16781678
{
1679-
#if defined(TCP_KEEPIDLE) || defined(TCP_KEEPALIVE) || defined(WIN32)
1679+
#if defined(TCP_KEEPIDLE) || defined(TCP_KEEPALIVE_THRESHOLD) || defined(TCP_KEEPALIVE) || defined(WIN32)
16801680
if (port == NULL || IS_AF_UNIX(port->laddr.addr.ss_family))
16811681
return 0;
16821682

@@ -1688,23 +1688,34 @@ pq_getkeepalivesidle(Port *port)
16881688
#ifndef WIN32
16891689
ACCEPT_TYPE_ARG3 size = sizeof(port->default_keepalives_idle);
16901690

1691-
#ifdef TCP_KEEPIDLE
1691+
#if defined(TCP_KEEPIDLE)
1692+
/* TCP_KEEPIDLE is the name of this option on Linux and *BSD */
16921693
if (getsockopt(port->sock, IPPROTO_TCP, TCP_KEEPIDLE,
16931694
(char *) &port->default_keepalives_idle,
16941695
&size) < 0)
16951696
{
16961697
elog(LOG, "getsockopt(TCP_KEEPIDLE) failed: %m");
16971698
port->default_keepalives_idle = -1; /* don't know */
16981699
}
1699-
#else
1700+
#elif defined(TCP_KEEPALIVE_THRESHOLD)
1701+
/* TCP_KEEPALIVE_THRESHOLD is the name of this option on Solaris */
1702+
if (getsockopt(port->sock, IPPROTO_TCP, TCP_KEEPALIVE_THRESHOLD,
1703+
(char *) &port->default_keepalives_idle,
1704+
&size) < 0)
1705+
{
1706+
elog(LOG, "getsockopt(TCP_KEEPALIVE_THRESHOLD) failed: %m");
1707+
port->default_keepalives_idle = -1; /* don't know */
1708+
}
1709+
#else /* must have TCP_KEEPALIVE */
1710+
/* TCP_KEEPALIVE is the name of this option on macOS */
17001711
if (getsockopt(port->sock, IPPROTO_TCP, TCP_KEEPALIVE,
17011712
(char *) &port->default_keepalives_idle,
17021713
&size) < 0)
17031714
{
17041715
elog(LOG, "getsockopt(TCP_KEEPALIVE) failed: %m");
17051716
port->default_keepalives_idle = -1; /* don't know */
17061717
}
1707-
#endif /* TCP_KEEPIDLE */
1718+
#endif /* KEEPIDLE/KEEPALIVE_THRESHOLD/KEEPALIVE */
17081719
#else /* WIN32 */
17091720
/* We can't get the defaults on Windows, so return "don't know" */
17101721
port->default_keepalives_idle = -1;
@@ -1723,7 +1734,8 @@ pq_setkeepalivesidle(int idle, Port *port)
17231734
if (port == NULL || IS_AF_UNIX(port->laddr.addr.ss_family))
17241735
return STATUS_OK;
17251736

1726-
#if defined(TCP_KEEPIDLE) || defined(TCP_KEEPALIVE) || defined(SIO_KEEPALIVE_VALS)
1737+
/* check SIO_KEEPALIVE_VALS here, not just WIN32, as some toolchains lack it */
1738+
#if defined(TCP_KEEPIDLE) || defined(TCP_KEEPALIVE_THRESHOLD) || defined(TCP_KEEPALIVE) || defined(SIO_KEEPALIVE_VALS)
17271739
if (idle == port->keepalives_idle)
17281740
return STATUS_OK;
17291741

@@ -1742,14 +1754,24 @@ pq_setkeepalivesidle(int idle, Port *port)
17421754
if (idle == 0)
17431755
idle = port->default_keepalives_idle;
17441756

1745-
#ifdef TCP_KEEPIDLE
1757+
#if defined(TCP_KEEPIDLE)
1758+
/* TCP_KEEPIDLE is the name of this option on Linux and *BSD */
17461759
if (setsockopt(port->sock, IPPROTO_TCP, TCP_KEEPIDLE,
17471760
(char *) &idle, sizeof(idle)) < 0)
17481761
{
17491762
elog(LOG, "setsockopt(TCP_KEEPIDLE) failed: %m");
17501763
return STATUS_ERROR;
17511764
}
1752-
#else
1765+
#elif defined(TCP_KEEPALIVE_THRESHOLD)
1766+
/* TCP_KEEPALIVE_THRESHOLD is the name of this option on Solaris */
1767+
if (setsockopt(port->sock, IPPROTO_TCP, TCP_KEEPALIVE_THRESHOLD,
1768+
(char *) &idle, sizeof(idle)) < 0)
1769+
{
1770+
elog(LOG, "setsockopt(TCP_KEEPALIVE_THRESHOLD) failed: %m");
1771+
return STATUS_ERROR;
1772+
}
1773+
#else /* must have TCP_KEEPALIVE */
1774+
/* TCP_KEEPALIVE is the name of this option on macOS */
17531775
if (setsockopt(port->sock, IPPROTO_TCP, TCP_KEEPALIVE,
17541776
(char *) &idle, sizeof(idle)) < 0)
17551777
{
@@ -1762,7 +1784,7 @@ pq_setkeepalivesidle(int idle, Port *port)
17621784
#else /* WIN32 */
17631785
return pq_setkeepaliveswin32(port, idle, port->keepalives_interval);
17641786
#endif
1765-
#else /* TCP_KEEPIDLE || SIO_KEEPALIVE_VALS */
1787+
#else /* no way to set it */
17661788
if (idle != 0)
17671789
{
17681790
elog(LOG, "setting the keepalive idle time is not supported");
@@ -1812,7 +1834,7 @@ pq_setkeepalivesinterval(int interval, Port *port)
18121834
if (port == NULL || IS_AF_UNIX(port->laddr.addr.ss_family))
18131835
return STATUS_OK;
18141836

1815-
#if defined(TCP_KEEPINTVL) || defined (SIO_KEEPALIVE_VALS)
1837+
#if defined(TCP_KEEPINTVL) || defined(SIO_KEEPALIVE_VALS)
18161838
if (interval == port->keepalives_interval)
18171839
return STATUS_OK;
18181840

src/interfaces/libpq/fe-connect.c

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1470,7 +1470,8 @@ setKeepalivesIdle(PGconn *conn)
14701470
if (idle < 0)
14711471
idle = 0;
14721472

1473-
#ifdef TCP_KEEPIDLE
1473+
#if defined(TCP_KEEPIDLE)
1474+
/* TCP_KEEPIDLE is the name of this option on Linux and *BSD */
14741475
if (setsockopt(conn->sock, IPPROTO_TCP, TCP_KEEPIDLE,
14751476
(char *) &idle, sizeof(idle)) < 0)
14761477
{
@@ -1481,9 +1482,20 @@ setKeepalivesIdle(PGconn *conn)
14811482
SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
14821483
return 0;
14831484
}
1484-
#else
1485-
#ifdef TCP_KEEPALIVE
1486-
/* macOS uses TCP_KEEPALIVE rather than TCP_KEEPIDLE */
1485+
#elif defined(TCP_KEEPALIVE_THRESHOLD)
1486+
/* TCP_KEEPALIVE_THRESHOLD is the name of this option on Solaris */
1487+
if (setsockopt(conn->sock, IPPROTO_TCP, TCP_KEEPALIVE_THRESHOLD,
1488+
(char *) &idle, sizeof(idle)) < 0)
1489+
{
1490+
char sebuf[256];
1491+
1492+
appendPQExpBuffer(&conn->errorMessage,
1493+
libpq_gettext("setsockopt(TCP_KEEPALIVE_THRESHOLD) failed: %s\n"),
1494+
SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
1495+
return 0;
1496+
}
1497+
#elif defined(TCP_KEEPALIVE)
1498+
/* TCP_KEEPALIVE is the name of this option on macOS */
14871499
if (setsockopt(conn->sock, IPPROTO_TCP, TCP_KEEPALIVE,
14881500
(char *) &idle, sizeof(idle)) < 0)
14891501
{
@@ -1494,7 +1506,6 @@ setKeepalivesIdle(PGconn *conn)
14941506
SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
14951507
return 0;
14961508
}
1497-
#endif
14981509
#endif
14991510

15001511
return 1;
@@ -1562,7 +1573,7 @@ setKeepalivesCount(PGconn *conn)
15621573

15631574
return 1;
15641575
}
1565-
#else /* Win32 */
1576+
#else /* WIN32 */
15661577
#ifdef SIO_KEEPALIVE_VALS
15671578
/*
15681579
* Enable keepalives and set the keepalive values on Win32,

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy