From 30d862650bcc26588ddcb07d1126b43e0ec4c121 Mon Sep 17 00:00:00 2001 From: roopa Date: Mon, 12 Nov 2012 12:38:32 -0800 Subject: [PATCH] New cache manager add cache api 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, ...); Signed-off-by: Thomas Graf --- 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); -- 2.40.0