[HACKERS] Upgrading postmaster's log messages about bind/listen errors - Mailing list pgsql-hackers

From Tom Lane
Subject [HACKERS] Upgrading postmaster's log messages about bind/listen errors
Date
Msg-id 9564.1489091245@sss.pgh.pa.us
Whole thread Raw
Responses Re: [HACKERS] Upgrading postmaster's log messages about bind/listenerrors  (Joe Conway <mail@joeconway.com>)
List pgsql-hackers
Over in
https://www.postgresql.org/message-id/flat/201703072317.01345.john.iliffe%40iliffe.ca
we spent quite a lot of effort to diagnose what turned out to be a simple
networking misconfiguration.  It would probably have taken a lot less
effort if the postmaster were more forthcoming about exactly what address
it's trying to bind to.  I seem to recall having wanted to include that
info in the messages many years ago, but at the time we lacked any
reasonably-portable way to decode a struct addrinfo.  Now we have
pg_getnameinfo_all(), so PFA a patch to include the specific address in
any complaint about failures in the socket/bind/listen sequence.

For good measure I also added a DEBUG1 log message reporting successful
binding to a port.  I'm not sure if there's an argument for putting this
out at LOG level (i.e. by default) --- any thoughts about that?

There are probably a couple of example messages in the SGML docs that
would need to be updated, but I've not trawled for them yet.

            regards, tom lane

diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c
index 7939b1f..3f3b2f2 100644
*** a/src/backend/libpq/pqcomm.c
--- b/src/backend/libpq/pqcomm.c
*************** StreamServerPort(int family, char *hostN
*** 319,324 ****
--- 319,326 ----
      char        portNumberStr[32];
      const char *familyDesc;
      char        familyDescBuf[64];
+     const char *addrDesc;
+     char        addrBuf[NI_MAXHOST];
      char       *service;
      struct addrinfo *addrs = NULL,
                 *addr;
*************** StreamServerPort(int family, char *hostN
*** 407,413 ****
              break;
          }

!         /* set up family name for possible error messages */
          switch (addr->ai_family)
          {
              case AF_INET:
--- 409,415 ----
              break;
          }

!         /* set up address family name for log messages */
          switch (addr->ai_family)
          {
              case AF_INET:
*************** StreamServerPort(int family, char *hostN
*** 431,443 ****
                  break;
          }

          if ((fd = socket(addr->ai_family, SOCK_STREAM, 0)) == PGINVALID_SOCKET)
          {
              ereport(LOG,
                      (errcode_for_socket_access(),
!             /* translator: %s is IPv4, IPv6, or Unix */
!                      errmsg("could not create %s socket: %m",
!                             familyDesc)));
              continue;
          }

--- 433,460 ----
                  break;
          }

+         /* set up text form of address for log messages */
+ #ifdef HAVE_UNIX_SOCKETS
+         if (addr->ai_family == AF_UNIX)
+             addrDesc = unixSocketPath;
+         else
+ #endif
+         {
+             pg_getnameinfo_all((const struct sockaddr_storage *) addr->ai_addr,
+                                addr->ai_addrlen,
+                                addrBuf, sizeof(addrBuf),
+                                NULL, 0,
+                                NI_NUMERICHOST);
+             addrDesc = addrBuf;
+         }
+
          if ((fd = socket(addr->ai_family, SOCK_STREAM, 0)) == PGINVALID_SOCKET)
          {
              ereport(LOG,
                      (errcode_for_socket_access(),
!             /* translator: first %s is IPv4, IPv6, or Unix */
!                   errmsg("could not create %s socket for address \"%s\": %m",
!                          familyDesc, addrDesc)));
              continue;
          }

*************** StreamServerPort(int family, char *hostN
*** 461,467 ****
              {
                  ereport(LOG,
                          (errcode_for_socket_access(),
!                          errmsg("setsockopt(SO_REUSEADDR) failed: %m")));
                  closesocket(fd);
                  continue;
              }
--- 478,486 ----
              {
                  ereport(LOG,
                          (errcode_for_socket_access(),
!                 /* translator: first %s is IPv4, IPv6, or Unix */
!                          errmsg("setsockopt(SO_REUSEADDR) failed for %s address \"%s\": %m",
!                                 familyDesc, addrDesc)));
                  closesocket(fd);
                  continue;
              }
*************** StreamServerPort(int family, char *hostN
*** 476,482 ****
              {
                  ereport(LOG,
                          (errcode_for_socket_access(),
!                          errmsg("setsockopt(IPV6_V6ONLY) failed: %m")));
                  closesocket(fd);
                  continue;
              }
--- 495,503 ----
              {
                  ereport(LOG,
                          (errcode_for_socket_access(),
!                 /* translator: first %s is IPv4, IPv6, or Unix */
!                          errmsg("setsockopt(IPV6_V6ONLY) failed for %s address \"%s\": %m",
!                                 familyDesc, addrDesc)));
                  closesocket(fd);
                  continue;
              }
*************** StreamServerPort(int family, char *hostN
*** 494,502 ****
          {
              ereport(LOG,
                      (errcode_for_socket_access(),
!             /* translator: %s is IPv4, IPv6, or Unix */
!                      errmsg("could not bind %s socket: %m",
!                             familyDesc),
                       (IS_AF_UNIX(addr->ai_family)) ?
                    errhint("Is another postmaster already running on port %d?"
                            " If not, remove socket file \"%s\" and retry.",
--- 515,523 ----
          {
              ereport(LOG,
                      (errcode_for_socket_access(),
!             /* translator: first %s is IPv4, IPv6, or Unix */
!                      errmsg("could not bind %s address \"%s\": %m",
!                             familyDesc, addrDesc),
                       (IS_AF_UNIX(addr->ai_family)) ?
                    errhint("Is another postmaster already running on port %d?"
                            " If not, remove socket file \"%s\" and retry.",
*************** StreamServerPort(int family, char *hostN
*** 533,544 ****
          {
              ereport(LOG,
                      (errcode_for_socket_access(),
!             /* translator: %s is IPv4, IPv6, or Unix */
!                      errmsg("could not listen on %s socket: %m",
!                             familyDesc)));
              closesocket(fd);
              continue;
          }
          ListenSocket[listen_index] = fd;
          added++;
      }
--- 554,571 ----
          {
              ereport(LOG,
                      (errcode_for_socket_access(),
!             /* translator: first %s is IPv4, IPv6, or Unix */
!                      errmsg("could not listen on %s address \"%s\": %m",
!                             familyDesc, addrDesc)));
              closesocket(fd);
              continue;
          }
+
+         ereport(DEBUG1,
+         /* translator: first %s is IPv4, IPv6, or Unix */
+                 (errmsg("listening on %s address \"%s\"",
+                         familyDesc, addrDesc)));
+
          ListenSocket[listen_index] = fd;
          added++;
      }

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

pgsql-hackers by date:

Previous
From: "Sven R. Kunze"
Date:
Subject: Re: [HACKERS] adding an immutable variant of to_date
Next
From: Peter Eisentraut
Date:
Subject: Re: [HACKERS] cast result of copyNode()