Skip to content

Commit 55968ed

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 3a7bd59 commit 55968ed

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
@@ -1653,7 +1653,7 @@ pq_setkeepaliveswin32(Port *port, int idle, int interval)
16531653
int
16541654
pq_getkeepalivesidle(Port *port)
16551655
{
1656-
#if defined(TCP_KEEPIDLE) || defined(TCP_KEEPALIVE) || defined(WIN32)
1656+
#if defined(TCP_KEEPIDLE) || defined(TCP_KEEPALIVE_THRESHOLD) || defined(TCP_KEEPALIVE) || defined(WIN32)
16571657
if (port == NULL || IS_AF_UNIX(port->laddr.addr.ss_family))
16581658
return 0;
16591659

@@ -1665,23 +1665,34 @@ pq_getkeepalivesidle(Port *port)
16651665
#ifndef WIN32
16661666
ACCEPT_TYPE_ARG3 size = sizeof(port->default_keepalives_idle);
16671667

1668-
#ifdef TCP_KEEPIDLE
1668+
#if defined(TCP_KEEPIDLE)
1669+
/* TCP_KEEPIDLE is the name of this option on Linux and *BSD */
16691670
if (getsockopt(port->sock, IPPROTO_TCP, TCP_KEEPIDLE,
16701671
(char *) &port->default_keepalives_idle,
16711672
&size) < 0)
16721673
{
16731674
elog(LOG, "getsockopt(TCP_KEEPIDLE) failed: %m");
16741675
port->default_keepalives_idle = -1; /* don't know */
16751676
}
1676-
#else
1677+
#elif defined(TCP_KEEPALIVE_THRESHOLD)
1678+
/* TCP_KEEPALIVE_THRESHOLD is the name of this option on Solaris */
1679+
if (getsockopt(port->sock, IPPROTO_TCP, TCP_KEEPALIVE_THRESHOLD,
1680+
(char *) &port->default_keepalives_idle,
1681+
&size) < 0)
1682+
{
1683+
elog(LOG, "getsockopt(TCP_KEEPALIVE_THRESHOLD) failed: %m");
1684+
port->default_keepalives_idle = -1; /* don't know */
1685+
}
1686+
#else /* must have TCP_KEEPALIVE */
1687+
/* TCP_KEEPALIVE is the name of this option on macOS */
16771688
if (getsockopt(port->sock, IPPROTO_TCP, TCP_KEEPALIVE,
16781689
(char *) &port->default_keepalives_idle,
16791690
&size) < 0)
16801691
{
16811692
elog(LOG, "getsockopt(TCP_KEEPALIVE) failed: %m");
16821693
port->default_keepalives_idle = -1; /* don't know */
16831694
}
1684-
#endif /* TCP_KEEPIDLE */
1695+
#endif /* KEEPIDLE/KEEPALIVE_THRESHOLD/KEEPALIVE */
16851696
#else /* WIN32 */
16861697
/* We can't get the defaults on Windows, so return "don't know" */
16871698
port->default_keepalives_idle = -1;
@@ -1700,7 +1711,8 @@ pq_setkeepalivesidle(int idle, Port *port)
17001711
if (port == NULL || IS_AF_UNIX(port->laddr.addr.ss_family))
17011712
return STATUS_OK;
17021713

1703-
#if defined(TCP_KEEPIDLE) || defined(TCP_KEEPALIVE) || defined(SIO_KEEPALIVE_VALS)
1714+
/* check SIO_KEEPALIVE_VALS here, not just WIN32, as some toolchains lack it */
1715+
#if defined(TCP_KEEPIDLE) || defined(TCP_KEEPALIVE_THRESHOLD) || defined(TCP_KEEPALIVE) || defined(SIO_KEEPALIVE_VALS)
17041716
if (idle == port->keepalives_idle)
17051717
return STATUS_OK;
17061718

@@ -1719,14 +1731,24 @@ pq_setkeepalivesidle(int idle, Port *port)
17191731
if (idle == 0)
17201732
idle = port->default_keepalives_idle;
17211733

1722-
#ifdef TCP_KEEPIDLE
1734+
#if defined(TCP_KEEPIDLE)
1735+
/* TCP_KEEPIDLE is the name of this option on Linux and *BSD */
17231736
if (setsockopt(port->sock, IPPROTO_TCP, TCP_KEEPIDLE,
17241737
(char *) &idle, sizeof(idle)) < 0)
17251738
{
17261739
elog(LOG, "setsockopt(TCP_KEEPIDLE) failed: %m");
17271740
return STATUS_ERROR;
17281741
}
1729-
#else
1742+
#elif defined(TCP_KEEPALIVE_THRESHOLD)
1743+
/* TCP_KEEPALIVE_THRESHOLD is the name of this option on Solaris */
1744+
if (setsockopt(port->sock, IPPROTO_TCP, TCP_KEEPALIVE_THRESHOLD,
1745+
(char *) &idle, sizeof(idle)) < 0)
1746+
{
1747+
elog(LOG, "setsockopt(TCP_KEEPALIVE_THRESHOLD) failed: %m");
1748+
return STATUS_ERROR;
1749+
}
1750+
#else /* must have TCP_KEEPALIVE */
1751+
/* TCP_KEEPALIVE is the name of this option on macOS */
17301752
if (setsockopt(port->sock, IPPROTO_TCP, TCP_KEEPALIVE,
17311753
(char *) &idle, sizeof(idle)) < 0)
17321754
{
@@ -1739,7 +1761,7 @@ pq_setkeepalivesidle(int idle, Port *port)
17391761
#else /* WIN32 */
17401762
return pq_setkeepaliveswin32(port, idle, port->keepalives_interval);
17411763
#endif
1742-
#else /* TCP_KEEPIDLE || SIO_KEEPALIVE_VALS */
1764+
#else /* no way to set it */
17431765
if (idle != 0)
17441766
{
17451767
elog(LOG, "setting the keepalive idle time is not supported");
@@ -1789,7 +1811,7 @@ pq_setkeepalivesinterval(int interval, Port *port)
17891811
if (port == NULL || IS_AF_UNIX(port->laddr.addr.ss_family))
17901812
return STATUS_OK;
17911813

1792-
#if defined(TCP_KEEPINTVL) || defined (SIO_KEEPALIVE_VALS)
1814+
#if defined(TCP_KEEPINTVL) || defined(SIO_KEEPALIVE_VALS)
17931815
if (interval == port->keepalives_interval)
17941816
return STATUS_OK;
17951817

src/interfaces/libpq/fe-connect.c

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1280,7 +1280,8 @@ setKeepalivesIdle(PGconn *conn)
12801280
if (idle < 0)
12811281
idle = 0;
12821282

1283-
#ifdef TCP_KEEPIDLE
1283+
#if defined(TCP_KEEPIDLE)
1284+
/* TCP_KEEPIDLE is the name of this option on Linux and *BSD */
12841285
if (setsockopt(conn->sock, IPPROTO_TCP, TCP_KEEPIDLE,
12851286
(char *) &idle, sizeof(idle)) < 0)
12861287
{
@@ -1291,9 +1292,20 @@ setKeepalivesIdle(PGconn *conn)
12911292
SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
12921293
return 0;
12931294
}
1294-
#else
1295-
#ifdef TCP_KEEPALIVE
1296-
/* Darwin uses TCP_KEEPALIVE rather than TCP_KEEPIDLE */
1295+
#elif defined(TCP_KEEPALIVE_THRESHOLD)
1296+
/* TCP_KEEPALIVE_THRESHOLD is the name of this option on Solaris */
1297+
if (setsockopt(conn->sock, IPPROTO_TCP, TCP_KEEPALIVE_THRESHOLD,
1298+
(char *) &idle, sizeof(idle)) < 0)
1299+
{
1300+
char sebuf[256];
1301+
1302+
appendPQExpBuffer(&conn->errorMessage,
1303+
libpq_gettext("setsockopt(TCP_KEEPALIVE_THRESHOLD) failed: %s\n"),
1304+
SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
1305+
return 0;
1306+
}
1307+
#elif defined(TCP_KEEPALIVE)
1308+
/* TCP_KEEPALIVE is the name of this option on macOS */
12971309
if (setsockopt(conn->sock, IPPROTO_TCP, TCP_KEEPALIVE,
12981310
(char *) &idle, sizeof(idle)) < 0)
12991311
{
@@ -1304,7 +1316,6 @@ setKeepalivesIdle(PGconn *conn)
13041316
SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
13051317
return 0;
13061318
}
1307-
#endif
13081319
#endif
13091320

13101321
return 1;
@@ -1372,7 +1383,7 @@ setKeepalivesCount(PGconn *conn)
13721383

13731384
return 1;
13741385
}
1375-
#else /* Win32 */
1386+
#else /* WIN32 */
13761387
#ifdef SIO_KEEPALIVE_VALS
13771388
/*
13781389
* 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