]> git.ipfire.org Git - thirdparty/ntp.git/commitdiff
[Bug 3428] ntpd spinning consuming CPU on Linux router with full table.
authorDave Hart <hart@ntp.org>
Sat, 25 Mar 2023 05:48:40 +0000 (01:48 -0400)
committerDave Hart <hart@ntp.org>
Sat, 25 Mar 2023 05:48:40 +0000 (01:48 -0400)
bk: 641e8b38HySUJ-QI6qiVc8RLCtSRlg

ChangeLog
libntp/work_thread.c
ntpd/ntp_io.c

index a62ab34c844e4a401c6c32c8a95ca9b5ad4a25bb..b57eccfa1e2fe730d0cbc47bcf0961f0a060bb28 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -66,6 +66,8 @@
   - applied patch by Gerry Garvey
 * [Bug 3432] refclocks that 'write()' should check the result <perlinger@ntp.org>
   - backport from -dev, plus some more work on warnings for unchecked results
+* [Bug 3428] ntpd spinning consuming CPU on Linux router with full table.
+             Reported by Israel G. Lugo. <hart@ntp.org>
 * [Bug 3103] libopts zsave_warn format string too few arguments <bkorb@gnu.org>
 * [Bug 2525] Turn on automake subdir-objects across the project. <hart@ntp.org>
 * [Bug 2410] syslog an error message on panic exceeded. <brian.utterback@oracle.com>
index a8e3e2766be46daf205a0e11d16eb66fe23e9cdb..c1fe5c20c99586dc38acb89a903a5770faf3cdf5 100644 (file)
@@ -389,7 +389,7 @@ send_blocking_resp_internal(
 #ifndef WORK_PIPE
 
 /* --------------------------------------------------------------------
- * Check if a (Windows-)hanndle to a semaphore is actually the same we
+ * Check if a (Windows-)handle to a semaphore is actually the same we
  * are using inside the sema wrapper.
  */
 static BOOL
index 7dde346c39324217ddf6f9bc187cb4fc988406ed..2e10b7a02d11acfa3494fc5b62d3c069a90e7a8f 100644 (file)
@@ -4511,7 +4511,7 @@ kill_asyncio(
 
 
 /*
- * Add and delete functions for the list of open sockets
+ * Add and delete functions for the list of input file descriptors
  */
 static void
 add_fd_to_list(
@@ -4701,14 +4701,16 @@ localaddrtoa(
 
 #ifdef HAS_ROUTING_SOCKET
 # ifndef UPDATE_GRACE
-#  define UPDATE_GRACE 2       /* wait UPDATE_GRACE seconds before scanning */
+#  define UPDATE_GRACE 3       /* min. UPDATE_GRACE - 1 seconds before scanning */
 # endif
 
 static void
 process_routing_msgs(struct asyncio_reader *reader)
 {
-       char buffer[5120];
-       int cnt, msg_type;
+       static char *   buffer;
+       static size_t   buffsz = 8192;
+       int             cnt, new, msg_type;
+       socklen_t       len;
 #ifdef HAVE_RTNETLINK
        struct nlmsghdr *nh;
 #else
@@ -4726,15 +4728,34 @@ process_routing_msgs(struct asyncio_reader *reader)
                return;
        }
 
-       cnt = read(reader->fd, buffer, sizeof(buffer));
+       if (NULL == buffer) {
+               buffer = emalloc(buffsz);
+       }
+
+       cnt = read(reader->fd, buffer, buffsz);
 
        if (cnt < 0) {
                if (errno == ENOBUFS) {
-                       msyslog(LOG_ERR,
-                               "routing socket reports: %m");
+                       /* increase socket buffer by 25% */
+                       len = sizeof cnt;
+                       if (0 > getsockopt(reader->fd, SOL_SOCKET, SO_RCVBUF, &cnt, &len) ||
+                           sizeof cnt != len) {
+                               msyslog(LOG_ERR,
+                                       "routing getsockopt SO_RCVBUF %u %u: %m - disabling",
+                                       (u_int)cnt, (u_int)sizeof cnt);
+                               goto disable;
+                       }
+                       new = cnt + (cnt / 4);
+                       if (0 > setsockopt(reader->fd, SOL_SOCKET, SO_RCVBUF, &new, sizeof new)) {
+                               msyslog(LOG_ERR,
+                                       "routing setsockopt SO_RCVBUF %d -> %d: %m - disabling",
+                                       cnt, new);
+                               goto disable;
+                       }
                } else {
                        msyslog(LOG_ERR,
                                "routing socket reports: %m - disabling");
+                   disable:
                        remove_asyncio_reader(reader);
                        delete_asyncio_reader(reader);
                }