Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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)