[PATCH v2 2/3] New cache manager add cache api

roopa at cumulusnetworks.com roopa at cumulusnetworks.com
Mon Nov 12 15:38:32 EST 2012


From: roopa <roopa at cumulusnetworks.com>

This patch is an attempt to add a new nl_cache_mngr_add_cache api
to allow adding an existing cache to cache manager.

Since the new api is similar to nl_cache_mngr_add
except for allocating the cache, the patch moves most of the
nl_cache_mngr_add code to nl_cache_mngr_add_cache and changes
nl_cache_mngr_add to call nl_cache_mngr_add_cache.

One use case for this api as pointed out by thomas would be to set cache
flags before associating the cache with a cache manager.

nl_cache_alloc_name("route/link", &cache);
nl_cache_set_flags(cache, NL_CACHE_AF_ITER);
nl_cache_mngr_add_cache(mngr, cache, ...);
---
 include/netlink/cache.h |    3 ++
 lib/cache_mngr.c        |   86 +++++++++++++++++++++++++++++++++++-----------
 2 files changed, 68 insertions(+), 21 deletions(-)

diff --git a/include/netlink/cache.h b/include/netlink/cache.h
index ee3b5d8..7de389d 100644
--- a/include/netlink/cache.h
+++ b/include/netlink/cache.h
@@ -124,6 +124,9 @@ extern int			nl_cache_mngr_add(struct nl_cache_mngr *,
 						  change_func_t,
 						  void *,
 						  struct nl_cache **);
+extern int			nl_cache_mngr_add_cache(struct nl_cache_mngr *mngr,
+							struct nl_cache *cache,
+							change_func_t cb, void *data);
 extern int			nl_cache_mngr_get_fd(struct nl_cache_mngr *);
 extern int			nl_cache_mngr_poll(struct nl_cache_mngr *,
 						   int);
diff --git a/lib/cache_mngr.c b/lib/cache_mngr.c
index cdf2b7b..63cc0d3 100644
--- a/lib/cache_mngr.c
+++ b/lib/cache_mngr.c
@@ -183,18 +183,16 @@ errout:
 }
 
 /**
- * Add cache responsibility to cache manager
+ * Add cache to cache manager
  * @arg mngr		Cache manager.
- * @arg name		Name of cache to keep track of
+ * @arg cache		Cache to be added to cache manager
  * @arg cb		Function to be called upon changes.
  * @arg data		Argument passed on to change callback
- * @arg result		Pointer to store added cache (optional)
  *
- * Allocates a new cache of the specified type and adds it to the manager.
- * The operation will trigger a full dump request from the kernel to
- * initially fill the contents of the cache. The manager will subscribe
- * to the notification group of the cache and keep track of any further
- * changes.
+ * Adds cache to the manager. The operation will trigger a full
+ * dump request from the kernel to initially fill the contents
+ * of the cache. The manager will subscribe to the notification group
+ * of the cache and keep track of any further changes.
  *
  * The user is responsible for calling nl_cache_mngr_poll() or monitor
  * the socket and call nl_cache_mngr_data_ready() to allow the library
@@ -204,23 +202,21 @@ errout:
  * @see nl_cache_mngr_data_ready()
  *
  * @return 0 on success or a negative error code.
- * @return -NLE_NOCACHE Unknown cache type
  * @return -NLE_PROTO_MISMATCH Protocol mismatch between cache manager and
  * 			       cache type
  * @return -NLE_OPNOTSUPP Cache type does not support updates
  * @return -NLE_EXIST Cache of this type already being managed
  */
-int nl_cache_mngr_add(struct nl_cache_mngr *mngr, const char *name,
-		      change_func_t cb, void *data, struct nl_cache **result)
+int nl_cache_mngr_add_cache(struct nl_cache_mngr *mngr, struct nl_cache *cache,
+		      change_func_t cb, void *data)
 {
 	struct nl_cache_ops *ops;
-	struct nl_cache *cache;
 	struct nl_af_group *grp;
 	int err, i;
 
-	ops = nl_cache_ops_lookup(name);
+	ops = cache->c_ops;
 	if (!ops)
-		return -NLE_NOCACHE;
+		return -NLE_INVAL;
 
 	if (ops->co_protocol != mngr->cm_protocol)
 		return -NLE_PROTO_MISMATCH;
@@ -254,14 +250,10 @@ retry:
 		goto retry;
 	}
 
-	cache = nl_cache_alloc(ops);
-	if (!cache)
-		return -NLE_NOMEM;
-
 	for (grp = ops->co_groups; grp->ag_group; grp++) {
 		err = nl_socket_add_membership(mngr->cm_sock, grp->ag_group);
 		if (err < 0)
-			goto errout_free_cache;
+			return err;
 	}
 
 	err = nl_cache_refill(mngr->cm_sock, cache);
@@ -278,13 +270,65 @@ retry:
 	NL_DBG(1, "Added cache %p <%s> to cache manager %p\n",
 	       cache, nl_cache_name(cache), mngr);
 
-	if (result)
-		*result = cache;
 	return 0;
 
 errout_drop_membership:
 	for (grp = ops->co_groups; grp->ag_group; grp++)
 		nl_socket_drop_membership(mngr->cm_sock, grp->ag_group);
+
+	return err;
+}
+
+/**
+ * Add cache to cache manager
+ * @arg mngr		Cache manager.
+ * @arg name		Name of cache to keep track of
+ * @arg cb		Function to be called upon changes.
+ * @arg data		Argument passed on to change callback
+ * @arg result		Pointer to store added cache (optional)
+ *
+ * Allocates a new cache of the specified type and adds it to the manager.
+ * The operation will trigger a full dump request from the kernel to
+ * initially fill the contents of the cache. The manager will subscribe
+ * to the notification group of the cache and keep track of any further
+ * changes.
+ *
+ * The user is responsible for calling nl_cache_mngr_poll() or monitor
+ * the socket and call nl_cache_mngr_data_ready() to allow the library
+ * to process netlink notification events.
+ *
+ * @see nl_cache_mngr_poll()
+ * @see nl_cache_mngr_data_ready()
+ *
+ * @return 0 on success or a negative error code.
+ * @return -NLE_NOCACHE Unknown cache type
+ * @return -NLE_PROTO_MISMATCH Protocol mismatch between cache manager and
+ * 			       cache type
+ * @return -NLE_OPNOTSUPP Cache type does not support updates
+ * @return -NLE_EXIST Cache of this type already being managed
+ */
+int nl_cache_mngr_add(struct nl_cache_mngr *mngr, const char *name,
+		      change_func_t cb, void *data, struct nl_cache **result)
+{
+	struct nl_cache_ops *ops;
+	struct nl_cache *cache;
+	int err;
+
+	ops = nl_cache_ops_lookup(name);
+	if (!ops)
+		return -NLE_NOCACHE;
+
+	cache = nl_cache_alloc(ops);
+	if (!cache)
+		return -NLE_NOMEM;
+
+	err = nl_cache_mngr_add_cache(mngr, cache, cb, data);
+	if (err < 0)
+		goto errout_free_cache;
+
+	*result = cache;
+	return 0;
+
 errout_free_cache:
 	nl_cache_free(cache);
 
-- 
1.7.2.5




More information about the libnl mailing list