1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-10 17:42:29 +03:00

Add GUC variables to control keep-alive times for idle, interval, and

count.

Oliver Jowett
This commit is contained in:
Bruce Momjian
2005-07-30 15:17:26 +00:00
parent b2b6548c79
commit 1f54d43075
7 changed files with 399 additions and 7 deletions

View File

@@ -30,7 +30,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/backend/libpq/pqcomm.c,v 1.176 2005/02/22 04:35:57 momjian Exp $
* $PostgreSQL: pgsql/src/backend/libpq/pqcomm.c,v 1.177 2005/07/30 15:17:20 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -87,7 +87,7 @@
#include "libpq/libpq.h"
#include "miscadmin.h"
#include "storage/ipc.h"
#include "utils/guc.h"
/*
* Configuration options
@@ -594,6 +594,19 @@ StreamConnection(int server_fd, Port *port)
elog(LOG, "setsockopt(SO_KEEPALIVE) failed: %m");
return STATUS_ERROR;
}
/* Set default keepalive parameters. This should also catch
* misconfigurations (non-zero values when socket options aren't
* supported)
*/
if (pq_setkeepalivesidle(tcp_keepalives_idle, port) != STATUS_OK)
return STATUS_ERROR;
if (pq_setkeepalivesinterval(tcp_keepalives_interval, port) != STATUS_OK)
return STATUS_ERROR;
if (pq_setkeepalivescount(tcp_keepalives_count, port) != STATUS_OK)
return STATUS_ERROR;
}
return STATUS_OK;
@@ -1158,3 +1171,199 @@ pq_endcopyout(bool errorAbort)
/* in non-error case, copy.c will have emitted the terminator line */
DoingCopyOut = false;
}
int
pq_getkeepalivesidle(Port *port)
{
#ifdef TCP_KEEPIDLE
if (IS_AF_UNIX(port->laddr.addr.ss_family))
return 0;
if (port->keepalives_idle != 0)
return port->keepalives_idle;
if (port->default_keepalives_idle == 0)
{
socklen_t size = sizeof(port->default_keepalives_idle);
if (getsockopt(port->sock, SOL_TCP, TCP_KEEPIDLE,
(char *) &port->default_keepalives_idle,
&size) < 0)
{
elog(LOG, "getsockopt(TCP_KEEPIDLE) failed: %m");
return -1;
}
}
return port->default_keepalives_idle;
#else
return 0;
#endif
}
int
pq_setkeepalivesidle(int idle, Port *port)
{
if (IS_AF_UNIX(port->laddr.addr.ss_family))
return STATUS_OK;
#ifdef TCP_KEEPIDLE
if (idle == port->keepalives_idle)
return STATUS_OK;
if (port->default_keepalives_idle == 0)
{
if (pq_getkeepalivesidle(port) < 0)
return STATUS_ERROR;
}
if (idle == 0)
idle = port->default_keepalives_idle;
if (setsockopt(port->sock, SOL_TCP, TCP_KEEPIDLE,
(char *) &idle, sizeof(idle)) < 0)
{
elog(LOG, "setsockopt(TCP_KEEPIDLE) failed: %m");
return STATUS_ERROR;
}
port->keepalives_idle = idle;
#else
if (idle != 0)
{
elog(LOG, "setsockopt(TCP_KEEPIDLE) not supported");
return STATUS_ERROR;
}
#endif
return STATUS_OK;
}
int
pq_getkeepalivesinterval(Port *port)
{
#ifdef TCP_KEEPINTVL
if (IS_AF_UNIX(port->laddr.addr.ss_family))
return 0;
if (port->keepalives_interval != 0)
return port->keepalives_interval;
if (port->default_keepalives_interval == 0)
{
socklen_t size = sizeof(port->default_keepalives_interval);
if (getsockopt(port->sock, SOL_TCP, TCP_KEEPINTVL,
(char *) &port->default_keepalives_interval,
&size) < 0)
{
elog(LOG, "getsockopt(TCP_KEEPINTVL) failed: %m");
return -1;
}
}
return port->default_keepalives_interval;
#else
return 0;
#endif
}
int
pq_setkeepalivesinterval(int interval, Port *port)
{
if (IS_AF_UNIX(port->laddr.addr.ss_family))
return STATUS_OK;
#ifdef TCP_KEEPINTVL
if (interval == port->keepalives_interval)
return STATUS_OK;
if (port->default_keepalives_interval == 0) {
if (pq_getkeepalivesinterval(port) < 0)
return STATUS_ERROR;
}
if (interval == 0)
interval = port->default_keepalives_interval;
if (setsockopt(port->sock, SOL_TCP, TCP_KEEPINTVL,
(char *) &interval, sizeof(interval)) < 0)
{
elog(LOG, "setsockopt(TCP_KEEPINTVL) failed: %m");
return STATUS_ERROR;
}
port->keepalives_interval = interval;
#else
if (interval != 0)
{
elog(LOG, "setsockopt(TCP_KEEPINTVL) not supported");
return STATUS_ERROR;
}
#endif
return STATUS_OK;
}
int
pq_getkeepalivescount(Port *port)
{
#ifdef TCP_KEEPCNT
if (IS_AF_UNIX(port->laddr.addr.ss_family))
return 0;
if (port->keepalives_count != 0)
return port->keepalives_count;
if (port->default_keepalives_count == 0)
{
socklen_t size = sizeof(port->default_keepalives_count);
if (getsockopt(port->sock, SOL_TCP, TCP_KEEPCNT,
(char *) &port->default_keepalives_count,
&size) < 0)
{
elog(LOG, "getsockopt(TCP_KEEPCNT) failed: %m");
return -1;
}
}
return port->default_keepalives_count;
#else
return 0;
#endif
}
int
pq_setkeepalivescount(int count, Port *port)
{
if (IS_AF_UNIX(port->laddr.addr.ss_family))
return STATUS_OK;
#ifdef TCP_KEEPCNT
if (count == port->keepalives_count)
return STATUS_OK;
if (port->default_keepalives_count == 0) {
if (pq_getkeepalivescount(port) < 0)
return STATUS_ERROR;
}
if (count == 0)
count = port->default_keepalives_count;
if (setsockopt(port->sock, SOL_TCP, TCP_KEEPCNT,
(char *) &count, sizeof(count)) < 0)
{
elog(LOG, "setsockopt(TCP_KEEPCNT) failed: %m");
return STATUS_ERROR;
}
port->keepalives_count = count;
#else
if (count != 0)
{
elog(LOG, "setsockopt(TCP_KEEPCNT) not supported");
return STATUS_ERROR;
}
#endif
return STATUS_OK;
}