[PATCH] Bug Fix: Add new fill socket to cache manager

roopa at cumulusnetworks.com roopa at cumulusnetworks.com
Mon Nov 19 01:14:23 EST 2012


From: roopa <roopa at cumulusnetworks.com>

This patch adds a new socket to cache manager to request fill's on.
cache manager today uses cm_sock to request dump from
the kernel. It also listens to netlink async events on the same sock.
The problem with this is that when libnl is waiting to process the
response to get dump request sent to the kernel during fill,
it may receive an async event, resulting in libnl complaining about
unexpected msg

This is usually reproducible when there is heavy netlink async event
traffic during nl_cache_mngr_add.

This patch adds a new cm_sync_sock to use for fill during cache manager
add cache.

The other option is to provide an api to set the cm_sync_sock. But since
this is a bug fix its probably better to fix the cache manager add api
like this patch does. Please suggest otherwise.

Signed-off-by: Roopa Prabhu <roopa at cumulusnetworks.com>
Reviewed-by: Nolan Leake <nolan at cumulusnetworks.com>
Reviewed-by: Shrijeet Mukherjee <shm at cumulusnetworks.com>
---
 include/netlink-types.h |    1 +
 lib/cache_mngr.c        |   16 +++++++++++++++-
 2 files changed, 16 insertions(+), 1 deletions(-)

diff --git a/include/netlink-types.h b/include/netlink-types.h
index 2bb4f0a..057ea2b 100644
--- a/include/netlink-types.h
+++ b/include/netlink-types.h
@@ -98,6 +98,7 @@ struct nl_cache_mngr
 	int			cm_flags;
 	int			cm_nassocs;
 	struct nl_sock *	cm_sock;
+	struct nl_sock *	cm_sync_sock;
 	struct nl_cache_assoc *	cm_assocs;
 };
 
diff --git a/lib/cache_mngr.c b/lib/cache_mngr.c
index bf92d11..d5dc1f3 100644
--- a/lib/cache_mngr.c
+++ b/lib/cache_mngr.c
@@ -171,12 +171,21 @@ int nl_cache_mngr_alloc(struct nl_sock *sk, int protocol, int flags,
 	if ((err = nl_socket_set_nonblocking(mngr->cm_sock) < 0))
 		goto errout;
 
+	/* Create and allocate socket for sync cache fills */
+	mngr->cm_sync_sock = nl_socket_alloc();
+	if (!mngr->cm_sync_sock)
+		goto errout;
+	if ((err = nl_connect(mngr->cm_sync_sock, protocol)) < 0)
+		goto errout_free_sync_sock;
+
 	NL_DBG(1, "Allocated cache manager %p, protocol %d, %d caches\n",
 	       mngr, protocol, mngr->cm_nassocs);
 
 	*result = mngr;
 	return 0;
 
+errout_free_sync_sock:
+	nl_socket_free(mngr->cm_sync_sock);
 errout:
 	nl_cache_mngr_free(mngr);
 	return err;
@@ -256,7 +265,7 @@ retry:
 			return err;
 	}
 
-	err = nl_cache_refill(mngr->cm_sock, cache);
+	err = nl_cache_refill(mngr->cm_sync_sock, cache);
 	if (err < 0)
 		goto errout_drop_membership;
 
@@ -490,6 +499,11 @@ void nl_cache_mngr_free(struct nl_cache_mngr *mngr)
 	if (mngr->cm_sock)
 		nl_close(mngr->cm_sock);
 
+	if (mngr->cm_sync_sock) {
+		nl_close(mngr->cm_sync_sock);
+		nl_socket_free(mngr->cm_sync_sock);
+	}
+
 	if (mngr->cm_flags & NL_ALLOCATED_SOCK)
 		nl_socket_free(mngr->cm_sock);
 
-- 
1.7.2.5




More information about the libnl mailing list