intel / openlldp

Other
54 stars 42 forks source link

Out of buffers #45

Closed apconole closed 3 years ago

apconole commented 4 years ago

The following perror is triggered occasionally: https://github.com/intel/openlldp/blob/b71bfb87fefb31c4b1a6a7ae351791c90966c3a8/event_iface.c#L402

Speficically with the message: "No buffer space available"

This usually means that the kernel has sent lots of messages down the socket and the receiver couldn't keep up.

We can either test for this and emit a lower-priority message, or we can try to re-write the polling mechanism to call the poll more frequently. Not sure what the best approach is.

apconole commented 4 years ago

Actually, this seems wrong:

https://github.com/intel/openlldp/blob/b71bfb87fefb31c4b1a6a7ae351791c90966c3a8/event_iface.c#L457

This means at best we can support 4k worth of backlog on the socket... but the default on my fedora system is like 200k - why do we shrink it?

apconole commented 4 years ago

How do you feel about the following (untested) patch:

From c807220d96262e270b4548fa759225385f209cbe Mon Sep 17 00:00:00 2001
From: Aaron Conole <aconole@redhat.com>
Date: Tue, 17 Mar 2020 09:39:39 -0400
Subject: [PATCH] event_iface: allow configurable buffer size

Signed-off-by: Aaron Conole <aconole@redhat.com>
---
 event_iface.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/event_iface.c b/event_iface.c
index 43a95c7..86c10da 100644
--- a/event_iface.c
+++ b/event_iface.c
@@ -44,6 +44,7 @@
 #include <syslog.h>
 #include <unistd.h>
 #include <fcntl.h>
+#include "config.h"
 #include "linux/if.h"
 #include "linux/if_vlan.h"
 #include "linux/rtnetlink.h"
@@ -415,18 +416,25 @@ event_iface_receive(int sock, UNUSED void *eloop_ctx, UNUSED void *sock_ctx)
    event_if_process_recvmsg(nlh);
 }

+extern config_t lldpad_cfg;
+
 int event_iface_init()
 {
    int fd;
-   int rcv_size = MAX_PAYLOAD;
+   int rcv_size = 0;
    struct sockaddr_nl snl;
+   int rc;

    fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);

    if (fd < 0)
        return fd;

-   if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &rcv_size, sizeof(int)) < 0) {
+#define NL_SOCK_BUF_SETTING "nlsock_bufsz"
+   rc = config_lookup_int(&lldpad_cfg, NL_SOCK_BUF_SETTING, &rcv_size);
+   if (rc != CONFIG_FALSE && rcv_size &&
+       setsockopt(fd, SOL_SOCKET, SO_RCVBUF,
+              &rcv_size, sizeof(int)) < 0) {
        close(fd);
        return -EIO;
    }
-- 
2.24.1
apconole commented 3 years ago

Closing this since it will be resolved as part of resovling #67