[Cluster-devel] [PATCH dlm-tool] dlm_controld: improve netlink ENOBUFS error handling
Alexander Aring
aahringo at redhat.com
Thu Sep 10 12:22:50 UTC 2020
This patch improves the handling for ENOBUFS for newer kernels by
setting the NETLINK_NO_ENOBUFS netlink socket option which should avoid
ENOBUFS errors regardless of the receive buffer size. If this fails
we switch to increasing the socket buffer size.
---
dlm_controld/main.c | 34 +++++++++++++++++++++++++---------
1 file changed, 25 insertions(+), 9 deletions(-)
diff --git a/dlm_controld/main.c b/dlm_controld/main.c
index a82fc9c2..b3c258b5 100644
--- a/dlm_controld/main.c
+++ b/dlm_controld/main.c
@@ -765,8 +765,7 @@ static void process_uevent(int ci)
static int setup_uevent(void)
{
struct sockaddr_nl snl;
- int rcvbuf;
- int s, rv;
+ int s, rv, val;
s = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);
if (s < 0) {
@@ -783,14 +782,31 @@ static int setup_uevent(void)
* the application to detect when this happens (via the ENOBUFS error
* returned by recvmsg(2)) and resynchronize.
*
- * To prevent ENOBUFS errors we just set the receive buffer to two
- * megabyte as other applications do it. This will not ensure that we never
- * receive ENOBUFS but it's more unlikely. May it's worth to handle ENOBUFS
- * errors on a different way in future.
+ * To avoid ENOBUFS errors we set the netlink socket to realiable
+ * transmission mode which can be turned on by NETLINK_NO_ENOBUFS
+ * option. This option is available since kernel 2.6.30. If this setting
+ * fails we fallback to increase the netlink socket receive buffer.
*/
- rcvbuf = DEFAULT_NETLINK_RCVBUF;
- setsockopt(s, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf));
- setsockopt(s, SOL_SOCKET, SO_RCVBUFFORCE, &rcvbuf, sizeof(rcvbuf));
+ val = 1;
+ rv = setsockopt(s, SOL_NETLINK, NETLINK_NO_ENOBUFS, &val, sizeof(val));
+ if (rv == -1) {
+ /* Fallback handling if NETLINK_NO_ENOBUFS fails to set.
+ *
+ * To prevent ENOBUFS errors we just set the receive buffer to
+ * two megabyte as other applications do it. This will not
+ * ensure that we never receive ENOBUFS but it's more unlikely.
+ */
+ val = DEFAULT_NETLINK_RCVBUF;
+ log_error("uevent netlink NETLINK_NO_ENOBUFS errno %d, will set rcvbuf to %d bytes", errno, val);
+
+ rv = setsockopt(s, SOL_SOCKET, SO_RCVBUF, &val, sizeof(val));
+ if (rv == -1)
+ log_error("uevent netlink SO_RCVBUF errno %d", errno);
+
+ rv = setsockopt(s, SOL_SOCKET, SO_RCVBUFFORCE, &val, sizeof(val));
+ if (rv == -1)
+ log_error("uevent netlink SO_RCVBUFFORCE errno %d", errno);
+ }
memset(&snl, 0, sizeof(snl));
snl.nl_family = AF_NETLINK;
--
2.26.2
More information about the Cluster-devel
mailing list