Re: [BUGS] BUG #14720: getsockopt(TCP_KEEPALIVE) failed: Option not supported by protocol

Поиск
Список
Период
Сортировка
От Tom Lane
Тема Re: [BUGS] BUG #14720: getsockopt(TCP_KEEPALIVE) failed: Option not supported by protocol
Дата
Msg-id 1982.1498602401@sss.pgh.pa.us
обсуждение исходный текст
Ответ на Re: [BUGS] BUG #14720: getsockopt(TCP_KEEPALIVE) failed: Option not supported by protocol  (Tom Lane <tgl@sss.pgh.pa.us>)
Ответы Re: [BUGS] BUG #14720: getsockopt(TCP_KEEPALIVE) failed: Option notsupported by protocol  (Michael Paquier <michael.paquier@gmail.com>)
Re: [BUGS] BUG #14720: getsockopt(TCP_KEEPALIVE) failed: Option not supported by protocol  (Tom Lane <tgl@sss.pgh.pa.us>)
Список pgsql-bugs
I wrote:
> So apparently, Linux's TCP_KEEPIDLE corresponds to Solaris'
> TCP_KEEPALIVE_THRESHOLD.  TCP_KEEPINTVL and TCP_KEEPCNT seem to have no
> direct equivalent, although TCP_KEEPALIVE_ABORT_THRESHOLD would correspond
> to their product.

> I suggest that we ought to expand the keepalive code to know about this
> synonym.

Concretely, something like the attached.  I have no way to test this
locally, so I'm thinking of just pushing it and seeing what the buildfarm
says.

            regards, tom lane

diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c
index 261e9be..c62f7e9 100644
*** a/src/backend/libpq/pqcomm.c
--- b/src/backend/libpq/pqcomm.c
*************** pq_setkeepaliveswin32(Port *port, int id
*** 1676,1682 ****
  int
  pq_getkeepalivesidle(Port *port)
  {
! #if defined(TCP_KEEPIDLE) || defined(TCP_KEEPALIVE) || defined(WIN32)
      if (port == NULL || IS_AF_UNIX(port->laddr.addr.ss_family))
          return 0;

--- 1676,1682 ----
  int
  pq_getkeepalivesidle(Port *port)
  {
! #if defined(TCP_KEEPIDLE) || defined(TCP_KEEPALIVE_THRESHOLD) || defined(TCP_KEEPALIVE) || defined(WIN32)
      if (port == NULL || IS_AF_UNIX(port->laddr.addr.ss_family))
          return 0;

*************** pq_getkeepalivesidle(Port *port)
*** 1688,1694 ****
  #ifndef WIN32
          ACCEPT_TYPE_ARG3 size = sizeof(port->default_keepalives_idle);

! #ifdef TCP_KEEPIDLE
          if (getsockopt(port->sock, IPPROTO_TCP, TCP_KEEPIDLE,
                         (char *) &port->default_keepalives_idle,
                         &size) < 0)
--- 1688,1695 ----
  #ifndef WIN32
          ACCEPT_TYPE_ARG3 size = sizeof(port->default_keepalives_idle);

! #if defined(TCP_KEEPIDLE)
!         /* TCP_KEEPIDLE is the name of this option on Linux and *BSD */
          if (getsockopt(port->sock, IPPROTO_TCP, TCP_KEEPIDLE,
                         (char *) &port->default_keepalives_idle,
                         &size) < 0)
*************** pq_getkeepalivesidle(Port *port)
*** 1696,1702 ****
              elog(LOG, "getsockopt(TCP_KEEPIDLE) failed: %m");
              port->default_keepalives_idle = -1; /* don't know */
          }
! #else
          if (getsockopt(port->sock, IPPROTO_TCP, TCP_KEEPALIVE,
                         (char *) &port->default_keepalives_idle,
                         &size) < 0)
--- 1697,1713 ----
              elog(LOG, "getsockopt(TCP_KEEPIDLE) failed: %m");
              port->default_keepalives_idle = -1; /* don't know */
          }
! #elif defined(TCP_KEEPALIVE_THRESHOLD)
!         /* TCP_KEEPALIVE_THRESHOLD is the name of this option on Solaris */
!         if (getsockopt(port->sock, IPPROTO_TCP, TCP_KEEPALIVE_THRESHOLD,
!                        (char *) &port->default_keepalives_idle,
!                        &size) < 0)
!         {
!             elog(LOG, "getsockopt(TCP_KEEPALIVE_THRESHOLD) failed: %m");
!             port->default_keepalives_idle = -1; /* don't know */
!         }
! #else                            /* must have TCP_KEEPALIVE */
!         /* TCP_KEEPALIVE is the name of this option on macOS */
          if (getsockopt(port->sock, IPPROTO_TCP, TCP_KEEPALIVE,
                         (char *) &port->default_keepalives_idle,
                         &size) < 0)
*************** pq_getkeepalivesidle(Port *port)
*** 1704,1710 ****
              elog(LOG, "getsockopt(TCP_KEEPALIVE) failed: %m");
              port->default_keepalives_idle = -1; /* don't know */
          }
! #endif                            /* TCP_KEEPIDLE */
  #else                            /* WIN32 */
          /* We can't get the defaults on Windows, so return "don't know" */
          port->default_keepalives_idle = -1;
--- 1715,1721 ----
              elog(LOG, "getsockopt(TCP_KEEPALIVE) failed: %m");
              port->default_keepalives_idle = -1; /* don't know */
          }
! #endif                            /* KEEPIDLE/KEEPALIVE_THRESHOLD/KEEPALIVE */
  #else                            /* WIN32 */
          /* We can't get the defaults on Windows, so return "don't know" */
          port->default_keepalives_idle = -1;
*************** pq_setkeepalivesidle(int idle, Port *por
*** 1723,1729 ****
      if (port == NULL || IS_AF_UNIX(port->laddr.addr.ss_family))
          return STATUS_OK;

! #if defined(TCP_KEEPIDLE) || defined(TCP_KEEPALIVE) || defined(SIO_KEEPALIVE_VALS)
      if (idle == port->keepalives_idle)
          return STATUS_OK;

--- 1734,1741 ----
      if (port == NULL || IS_AF_UNIX(port->laddr.addr.ss_family))
          return STATUS_OK;

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

*************** pq_setkeepalivesidle(int idle, Port *por
*** 1742,1755 ****
      if (idle == 0)
          idle = port->default_keepalives_idle;

! #ifdef TCP_KEEPIDLE
      if (setsockopt(port->sock, IPPROTO_TCP, TCP_KEEPIDLE,
                     (char *) &idle, sizeof(idle)) < 0)
      {
          elog(LOG, "setsockopt(TCP_KEEPIDLE) failed: %m");
          return STATUS_ERROR;
      }
! #else
      if (setsockopt(port->sock, IPPROTO_TCP, TCP_KEEPALIVE,
                     (char *) &idle, sizeof(idle)) < 0)
      {
--- 1754,1777 ----
      if (idle == 0)
          idle = port->default_keepalives_idle;

! #if defined(TCP_KEEPIDLE)
!     /* TCP_KEEPIDLE is the name of this option on Linux and *BSD */
      if (setsockopt(port->sock, IPPROTO_TCP, TCP_KEEPIDLE,
                     (char *) &idle, sizeof(idle)) < 0)
      {
          elog(LOG, "setsockopt(TCP_KEEPIDLE) failed: %m");
          return STATUS_ERROR;
      }
! #elif defined(TCP_KEEPALIVE_THRESHOLD)
!     /* TCP_KEEPALIVE_THRESHOLD is the name of this option on Solaris */
!     if (setsockopt(port->sock, IPPROTO_TCP, TCP_KEEPALIVE_THRESHOLD,
!                    (char *) &idle, sizeof(idle)) < 0)
!     {
!         elog(LOG, "setsockopt(TCP_KEEPALIVE_THRESHOLD) failed: %m");
!         return STATUS_ERROR;
!     }
! #else                            /* must have TCP_KEEPALIVE */
!     /* TCP_KEEPALIVE is the name of this option on macOS */
      if (setsockopt(port->sock, IPPROTO_TCP, TCP_KEEPALIVE,
                     (char *) &idle, sizeof(idle)) < 0)
      {
*************** pq_setkeepalivesidle(int idle, Port *por
*** 1762,1768 ****
  #else                            /* WIN32 */
      return pq_setkeepaliveswin32(port, idle, port->keepalives_interval);
  #endif
! #else                            /* TCP_KEEPIDLE || SIO_KEEPALIVE_VALS */
      if (idle != 0)
      {
          elog(LOG, "setting the keepalive idle time is not supported");
--- 1784,1790 ----
  #else                            /* WIN32 */
      return pq_setkeepaliveswin32(port, idle, port->keepalives_interval);
  #endif
! #else                            /* no way to set it */
      if (idle != 0)
      {
          elog(LOG, "setting the keepalive idle time is not supported");
*************** pq_setkeepalivesinterval(int interval, P
*** 1812,1818 ****
      if (port == NULL || IS_AF_UNIX(port->laddr.addr.ss_family))
          return STATUS_OK;

! #if defined(TCP_KEEPINTVL) || defined (SIO_KEEPALIVE_VALS)
      if (interval == port->keepalives_interval)
          return STATUS_OK;

--- 1834,1840 ----
      if (port == NULL || IS_AF_UNIX(port->laddr.addr.ss_family))
          return STATUS_OK;

! #if defined(TCP_KEEPINTVL) || defined(SIO_KEEPALIVE_VALS)
      if (interval == port->keepalives_interval)
          return STATUS_OK;

diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index 764e960..e32c42b 100644
*** a/src/interfaces/libpq/fe-connect.c
--- b/src/interfaces/libpq/fe-connect.c
*************** setKeepalivesIdle(PGconn *conn)
*** 1470,1476 ****
      if (idle < 0)
          idle = 0;

! #ifdef TCP_KEEPIDLE
      if (setsockopt(conn->sock, IPPROTO_TCP, TCP_KEEPIDLE,
                     (char *) &idle, sizeof(idle)) < 0)
      {
--- 1470,1477 ----
      if (idle < 0)
          idle = 0;

! #if defined(TCP_KEEPIDLE)
!     /* TCP_KEEPIDLE is the name of this option on Linux and *BSD */
      if (setsockopt(conn->sock, IPPROTO_TCP, TCP_KEEPIDLE,
                     (char *) &idle, sizeof(idle)) < 0)
      {
*************** setKeepalivesIdle(PGconn *conn)
*** 1481,1489 ****
                            SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
          return 0;
      }
! #else
! #ifdef TCP_KEEPALIVE
!     /* macOS uses TCP_KEEPALIVE rather than TCP_KEEPIDLE */
      if (setsockopt(conn->sock, IPPROTO_TCP, TCP_KEEPALIVE,
                     (char *) &idle, sizeof(idle)) < 0)
      {
--- 1482,1501 ----
                            SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
          return 0;
      }
! #elif defined(TCP_KEEPALIVE_THRESHOLD)
!     /* TCP_KEEPALIVE_THRESHOLD is the name of this option on Solaris */
!     if (setsockopt(conn->sock, IPPROTO_TCP, TCP_KEEPALIVE_THRESHOLD,
!                    (char *) &idle, sizeof(idle)) < 0)
!     {
!         char        sebuf[256];
!
!         appendPQExpBuffer(&conn->errorMessage,
!                           libpq_gettext("setsockopt(TCP_KEEPALIVE_THRESHOLD) failed: %s\n"),
!                           SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
!         return 0;
!     }
! #elif defined(TCP_KEEPALIVE)
!     /* TCP_KEEPALIVE is the name of this option on macOS */
      if (setsockopt(conn->sock, IPPROTO_TCP, TCP_KEEPALIVE,
                     (char *) &idle, sizeof(idle)) < 0)
      {
*************** setKeepalivesIdle(PGconn *conn)
*** 1495,1501 ****
          return 0;
      }
  #endif
- #endif

      return 1;
  }
--- 1507,1512 ----
*************** setKeepalivesCount(PGconn *conn)
*** 1562,1568 ****

      return 1;
  }
! #else                            /* Win32 */
  #ifdef SIO_KEEPALIVE_VALS
  /*
   * Enable keepalives and set the keepalive values on Win32,
--- 1573,1579 ----

      return 1;
  }
! #else                            /* WIN32 */
  #ifdef SIO_KEEPALIVE_VALS
  /*
   * Enable keepalives and set the keepalive values on Win32,

-- 
Sent via pgsql-bugs mailing list (pgsql-bugs@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-bugs

В списке pgsql-bugs по дате отправления:

Предыдущее
От: Tom Lane
Дата:
Сообщение: Re: [BUGS] BUG #14720: getsockopt(TCP_KEEPALIVE) failed: Option not supported by protocol
Следующее
От: Michael Paquier
Дата:
Сообщение: Re: [BUGS] BUG #14720: getsockopt(TCP_KEEPALIVE) failed: Option notsupported by protocol