Lines Matching +full:cache +full:- +full:to
1 /* SPDX-License-Identifier: LGPL-2.1-only */
3 * Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
9 * @brief Manager keeping caches up to date automatically.
11 * The cache manager keeps caches up to date automatically by listening to
13 * existing cache.
18 * - @core_doc{_cache_manager,Cache Manager}
23 * ------
25 * #include <netlink/cache.h>
29 #include "nl-default.h"
32 #include <netlink/cache.h>
35 #include "nl-core.h"
36 #include "nl-priv-dynamic-core/nl-core.h"
37 #include "nl-priv-dynamic-core/cache-api.h"
38 #include "nl-aux-core/nl-core.h"
59 struct nl_cache_assoc *ca = p->pp_arg; in include_cb()
60 struct nl_cache_ops *ops = ca->ca_cache->c_ops; in include_cb()
62 NL_DBG(2, "Including object %p into cache %p\n", obj, ca->ca_cache); in include_cb()
67 if (ops->co_event_filter) in include_cb()
68 if (ops->co_event_filter(ca->ca_cache, obj) != NL_OK) in include_cb()
71 if (ops->co_include_event) in include_cb()
72 return ops->co_include_event(ca->ca_cache, obj, ca->ca_change, in include_cb()
73 ca->ca_change_v2, in include_cb()
74 ca->ca_change_data); in include_cb()
76 if (ca->ca_change_v2) in include_cb()
77 return nl_cache_include_v2(ca->ca_cache, obj, ca->ca_change_v2, ca->ca_change_data); in include_cb()
79 return nl_cache_include(ca->ca_cache, obj, ca->ca_change, ca->ca_change_data); in include_cb()
88 int type = nlmsg_hdr(msg)->nlmsg_type; in event_input()
95 NL_DBG(2, "Cache manager %p, handling new message %p as event\n", in event_input()
101 if (mngr->cm_protocol != protocol) in event_input()
104 for (i = 0; i < mngr->cm_nassocs; i++) { in event_input()
105 if (mngr->cm_assocs[i].ca_cache) { in event_input()
106 ops = mngr->cm_assocs[i].ca_cache->c_ops; in event_input()
107 for (n = 0; ops->co_msgtypes[n].mt_id >= 0; n++) in event_input()
108 if (ops->co_msgtypes[n].mt_id == type) in event_input()
116 NL_DBG(2, "Associated message %p to cache %p\n", in event_input()
117 msg, mngr->cm_assocs[i].ca_cache); in event_input()
118 p.pp_arg = &mngr->cm_assocs[i]; in event_input()
124 * Allocate new cache manager
125 * @arg sk Netlink socket or NULL to auto allocate
130 * Allocates a new cache manager for the specified netlink protocol.
135 * 2. The socket will be put in non-blocking mode and sequence checking
141 * If the flag \c NL_AUTO_PROVIDE is specified, any cache added to the
142 * manager will automatically be made available to other users using
146 * to use the socket for anything else besides receiving netlink
158 * Allocate new cache manager, with custom callback on refill socket
159 * @arg sk Netlink socket or NULL to auto allocate
160 * @arg sync_sk Blocking Netlink socket for cache refills
166 * Note: ownership of the sync_sk passes to the cache manager
181 return -NLE_NOMEM; in nl_cache_mngr_alloc_ex()
183 mngr->cm_flags = flags; in nl_cache_mngr_alloc_ex()
187 return -NLE_NOMEM; in nl_cache_mngr_alloc_ex()
188 mngr->cm_flags |= NL_ALLOCATED_SOCK; in nl_cache_mngr_alloc_ex()
190 mngr->cm_sock = sk; in nl_cache_mngr_alloc_ex()
194 return -NLE_NOMEM; in nl_cache_mngr_alloc_ex()
195 mngr->cm_flags |= NL_ALLOCATED_SYNC_SOCK; in nl_cache_mngr_alloc_ex()
197 mngr->cm_sync_sock = sync_sk; in nl_cache_mngr_alloc_ex()
199 mngr->cm_nassocs = NASSOC_INIT; in nl_cache_mngr_alloc_ex()
200 mngr->cm_protocol = protocol; in nl_cache_mngr_alloc_ex()
201 mngr->cm_assocs = calloc(mngr->cm_nassocs, in nl_cache_mngr_alloc_ex()
203 if (!mngr->cm_assocs) in nl_cache_mngr_alloc_ex()
204 return -NLE_NOMEM; in nl_cache_mngr_alloc_ex()
206 /* Required to receive async event notifications */ in nl_cache_mngr_alloc_ex()
207 nl_socket_disable_seq_check(mngr->cm_sock); in nl_cache_mngr_alloc_ex()
209 if ((err = nl_connect(mngr->cm_sock, protocol)) < 0) in nl_cache_mngr_alloc_ex()
212 if ((err = nl_socket_set_nonblocking(mngr->cm_sock)) < 0) in nl_cache_mngr_alloc_ex()
215 if ((err = nl_connect(mngr->cm_sync_sock, protocol)) < 0) in nl_cache_mngr_alloc_ex()
218 NL_DBG(1, "Allocated cache manager %p, protocol %d, %d caches\n", in nl_cache_mngr_alloc_ex()
219 mngr, protocol, mngr->cm_nassocs); in nl_cache_mngr_alloc_ex()
226 * Set change_func_v2 for cache manager
227 * @arg mngr Cache manager.
228 * @arg cache Cache associated with the callback
229 * @arg cb Function to be called upon changes.
230 * @arg data Argument passed on to change callback
232 * Adds callback change_func_v2 to a registered cache. This callback provides
236 * change_func registered during cache registration. Hence only one callback is
239 * The first netlink object in the callback is refering to the old object and
240 * the second to the new. This means on NL_ACT_CHANGE the first is the previous
241 * object in the cache and the second the updated version. On NL_ACT_DEL the
246 * the socket and call nl_cache_mngr_data_ready() to allow the library
247 * to process netlink notification events.
253 * @return -NLE_PROTO_MISMATCH Protocol mismatch between cache manager and
254 * cache type
255 * @return -NLE_OPNOTSUPP Cache type does not support updates
256 * @return -NLE_RANGE Cache of this type is not registered
259 struct nl_cache *cache, in nl_cache_mngr_set_change_func_v2() argument
265 ops = cache->c_ops; in nl_cache_mngr_set_change_func_v2()
267 return -NLE_INVAL; in nl_cache_mngr_set_change_func_v2()
269 if (ops->co_protocol != mngr->cm_protocol) in nl_cache_mngr_set_change_func_v2()
270 return -NLE_PROTO_MISMATCH; in nl_cache_mngr_set_change_func_v2()
272 if (ops->co_groups == NULL) in nl_cache_mngr_set_change_func_v2()
273 return -NLE_OPNOTSUPP; in nl_cache_mngr_set_change_func_v2()
275 for (i = 0; i < mngr->cm_nassocs; i++) in nl_cache_mngr_set_change_func_v2()
276 if (mngr->cm_assocs[i].ca_cache == cache) in nl_cache_mngr_set_change_func_v2()
279 if (i >= mngr->cm_nassocs) { in nl_cache_mngr_set_change_func_v2()
280 return -NLE_RANGE; in nl_cache_mngr_set_change_func_v2()
283 mngr->cm_assocs[i].ca_change_v2 = cb; in nl_cache_mngr_set_change_func_v2()
284 mngr->cm_assocs[i].ca_change_data = data; in nl_cache_mngr_set_change_func_v2()
290 * Add cache to cache manager
291 * @arg mngr Cache manager.
292 * @arg cache Cache to be added to cache manager
293 * @arg cb Function to be called upon changes.
294 * @arg data Argument passed on to change callback
296 * Adds cache to the manager. The operation will trigger a full
297 * dump request from the kernel to initially fill the contents
298 * of the cache. The manager will subscribe to the notification group
299 * of the cache and keep track of any further changes.
302 * the socket and call nl_cache_mngr_data_ready() to allow the library
303 * to process netlink notification events.
309 * @return -NLE_PROTO_MISMATCH Protocol mismatch between cache manager and
310 * cache type
311 * @return -NLE_OPNOTSUPP Cache type does not support updates
312 * @return -NLE_EXIST Cache of this type already being managed
314 int nl_cache_mngr_add_cache(struct nl_cache_mngr *mngr, struct nl_cache *cache, in nl_cache_mngr_add_cache() argument
321 ops = cache->c_ops; in nl_cache_mngr_add_cache()
323 return -NLE_INVAL; in nl_cache_mngr_add_cache()
325 if (ops->co_protocol != mngr->cm_protocol) in nl_cache_mngr_add_cache()
326 return -NLE_PROTO_MISMATCH; in nl_cache_mngr_add_cache()
328 if (ops->co_groups == NULL) in nl_cache_mngr_add_cache()
329 return -NLE_OPNOTSUPP; in nl_cache_mngr_add_cache()
331 for (i = 0; i < mngr->cm_nassocs; i++) in nl_cache_mngr_add_cache()
332 if (mngr->cm_assocs[i].ca_cache && in nl_cache_mngr_add_cache()
333 mngr->cm_assocs[i].ca_cache->c_ops == ops) in nl_cache_mngr_add_cache()
334 return -NLE_EXIST; in nl_cache_mngr_add_cache()
336 for (i = 0; i < mngr->cm_nassocs; i++) in nl_cache_mngr_add_cache()
337 if (!mngr->cm_assocs[i].ca_cache) in nl_cache_mngr_add_cache()
340 if (i >= mngr->cm_nassocs) { in nl_cache_mngr_add_cache()
342 int cm_nassocs = mngr->cm_nassocs + NASSOC_EXPAND; in nl_cache_mngr_add_cache()
344 cm_assocs = realloc(mngr->cm_assocs, in nl_cache_mngr_add_cache()
347 return -NLE_NOMEM; in nl_cache_mngr_add_cache()
349 memset(cm_assocs + mngr->cm_nassocs, 0, in nl_cache_mngr_add_cache()
351 mngr->cm_assocs = cm_assocs; in nl_cache_mngr_add_cache()
352 mngr->cm_nassocs = cm_nassocs; in nl_cache_mngr_add_cache()
354 NL_DBG(1, "Increased capacity of cache manager %p " \ in nl_cache_mngr_add_cache()
355 "to %d\n", mngr, mngr->cm_nassocs); in nl_cache_mngr_add_cache()
358 for (grp = ops->co_groups; grp->ag_group; grp++) { in nl_cache_mngr_add_cache()
359 err = nl_socket_add_membership(mngr->cm_sock, grp->ag_group); in nl_cache_mngr_add_cache()
364 err = nl_cache_refill(mngr->cm_sync_sock, cache); in nl_cache_mngr_add_cache()
368 mngr->cm_assocs[i].ca_cache = cache; in nl_cache_mngr_add_cache()
369 mngr->cm_assocs[i].ca_change = cb; in nl_cache_mngr_add_cache()
370 mngr->cm_assocs[i].ca_change_data = data; in nl_cache_mngr_add_cache()
372 if (mngr->cm_flags & NL_AUTO_PROVIDE) in nl_cache_mngr_add_cache()
373 nl_cache_mngt_provide(cache); in nl_cache_mngr_add_cache()
375 NL_DBG(1, "Added cache %p <%s> to cache manager %p\n", in nl_cache_mngr_add_cache()
376 cache, nl_cache_name(cache), mngr); in nl_cache_mngr_add_cache()
381 for (grp = ops->co_groups; grp->ag_group; grp++) in nl_cache_mngr_add_cache()
382 nl_socket_drop_membership(mngr->cm_sock, grp->ag_group); in nl_cache_mngr_add_cache()
388 * Add cache to cache manager
389 * @arg mngr Cache manager.
390 * @arg cache Cache to be added to cache manager
391 * @arg cb V2 function to be called upon changes.
392 * @arg data Argument passed on to change callback
394 * Adds cache to the manager. The operation will trigger a full
395 * dump request from the kernel to initially fill the contents
396 * of the cache. The manager will subscribe to the notification group
397 * of the cache and keep track of any further changes.
400 * the socket and call nl_cache_mngr_data_ready() to allow the library
401 * to process netlink notification events.
407 * @return -NLE_PROTO_MISMATCH Protocol mismatch between cache manager and
408 * cache type
409 * @return -NLE_OPNOTSUPP Cache type does not support updates
410 * @return -NLE_EXIST Cache of this type already being managed
412 int nl_cache_mngr_add_cache_v2(struct nl_cache_mngr *mngr, struct nl_cache *cache, in nl_cache_mngr_add_cache_v2() argument
415 err = nl_cache_mngr_add_cache(mngr, cache, NULL, NULL); in nl_cache_mngr_add_cache_v2()
419 return nl_cache_mngr_set_change_func_v2(mngr, cache, cb, data); in nl_cache_mngr_add_cache_v2()
423 * Add cache to cache manager
424 * @arg mngr Cache manager.
425 * @arg name Name of cache to keep track of
426 * @arg cb Function to be called upon changes.
427 * @arg data Argument passed on to change callback
428 * @arg result Pointer to store added cache (optional)
430 * Allocates a new cache of the specified type and adds it to the manager.
431 * The operation will trigger a full dump request from the kernel to
432 * initially fill the contents of the cache. The manager will subscribe
433 * to the notification group of the cache and keep track of any further
437 * the socket and call nl_cache_mngr_data_ready() to allow the library
438 * to process netlink notification events.
440 * @note Versions up to 3.4.0 actually required the result argument, preventing
441 * NULL to be passed.
447 * @return -NLE_NOCACHE Unknown cache type
448 * @return -NLE_PROTO_MISMATCH Protocol mismatch between cache manager and
449 * cache type
450 * @return -NLE_OPNOTSUPP Cache type does not support updates
451 * @return -NLE_EXIST Cache of this type already being managed
457 struct nl_cache *cache; in nl_cache_mngr_add() local
462 return -NLE_NOCACHE; in nl_cache_mngr_add()
464 cache = nl_cache_alloc(ops); in nl_cache_mngr_add()
466 if (!cache) in nl_cache_mngr_add()
467 return -NLE_NOMEM; in nl_cache_mngr_add()
469 err = nl_cache_mngr_add_cache(mngr, cache, cb, data); in nl_cache_mngr_add()
474 *result = cache; in nl_cache_mngr_add()
478 nl_cache_free(cache); in nl_cache_mngr_add()
485 * @arg mngr Cache Manager
494 return nl_socket_get_fd(mngr->cm_sock); in nl_cache_mngr_get_fd()
499 * @arg mngr Cache Manager
502 * Causes poll() to be called to check for new event notifications
503 * being available. Calls nl_cache_mngr_data_ready() to process
509 * A timeout can be specified in milliseconds to limit the time the
520 .fd = nl_socket_get_fd(mngr->cm_sock), in nl_cache_mngr_poll()
524 NL_DBG(3, "Cache manager %p, poll() fd %d\n", mngr, fds.fd); in nl_cache_mngr_poll()
526 NL_DBG(3, "Cache manager %p, poll() returned %d\n", mngr, ret); in nl_cache_mngr_poll()
530 return -nl_syserr2nlerr(errno); in nl_cache_mngr_poll()
542 * @arg mngr Cache manager
544 * This function can be called if the socket associated to the manager
545 * contains updates to be received. This function should only be used
548 * The function will process messages until there is no more data to
560 NL_DBG(2, "Cache manager %p, reading new data from fd %d\n", in nl_cache_mngr_data_ready()
561 mngr, nl_socket_get_fd(mngr->cm_sock)); in nl_cache_mngr_data_ready()
563 cb = nl_cb_clone(mngr->cm_sock->s_cb); in nl_cache_mngr_data_ready()
565 return -NLE_NOMEM; in nl_cache_mngr_data_ready()
569 while ((err = nl_recvmsgs_report(mngr->cm_sock, cb)) > 0) { in nl_cache_mngr_data_ready()
570 NL_DBG(2, "Cache manager %p, recvmsgs read %d messages\n", in nl_cache_mngr_data_ready()
576 if (err < 0 && err != -NLE_AGAIN) in nl_cache_mngr_data_ready()
583 * Print information about cache manager
584 * @arg mngr Cache manager
587 * Prints information about the cache manager including all managed caches.
596 nl_dump_line(p, "cache-manager <%p>\n", mngr); in nl_cache_mngr_info()
598 nl_nlfamily2str(mngr->cm_protocol, buf, sizeof(buf))); in nl_cache_mngr_info()
599 nl_dump_line(p, " .flags = %#x\n", mngr->cm_flags); in nl_cache_mngr_info()
600 nl_dump_line(p, " .nassocs = %u\n", mngr->cm_nassocs); in nl_cache_mngr_info()
601 nl_dump_line(p, " .sock = <%p>\n", mngr->cm_sock); in nl_cache_mngr_info()
603 for (i = 0; i < mngr->cm_nassocs; i++) { in nl_cache_mngr_info()
604 struct nl_cache_assoc *assoc = &mngr->cm_assocs[i]; in nl_cache_mngr_info()
606 if (assoc->ca_cache) { in nl_cache_mngr_info()
607 nl_dump_line(p, " .cache[%d] = <%p> {\n", i, assoc->ca_cache); in nl_cache_mngr_info()
608 nl_dump_line(p, " .name = %s\n", assoc->ca_cache->c_ops->co_name); in nl_cache_mngr_info()
609 nl_dump_line(p, " .change_func = <%p>\n", assoc->ca_change); in nl_cache_mngr_info()
610 nl_dump_line(p, " .change_data = <%p>\n", assoc->ca_change_data); in nl_cache_mngr_info()
611 nl_dump_line(p, " .nitems = %u\n", nl_cache_nitems(assoc->ca_cache)); in nl_cache_mngr_info()
614 p->dp_prefix += 6; in nl_cache_mngr_info()
615 nl_cache_dump(assoc->ca_cache, p); in nl_cache_mngr_info()
616 p->dp_prefix -= 6; in nl_cache_mngr_info()
625 * Free cache manager and all caches.
626 * @arg mngr Cache manager.
628 * Release all resources held by a cache manager.
637 if (mngr->cm_sock) in nl_cache_mngr_free()
638 nl_close(mngr->cm_sock); in nl_cache_mngr_free()
640 if (mngr->cm_sync_sock) in nl_cache_mngr_free()
641 nl_close(mngr->cm_sync_sock); in nl_cache_mngr_free()
643 if (mngr->cm_flags & NL_ALLOCATED_SOCK) in nl_cache_mngr_free()
644 nl_socket_free(mngr->cm_sock); in nl_cache_mngr_free()
646 if (mngr->cm_flags & NL_ALLOCATED_SYNC_SOCK) in nl_cache_mngr_free()
647 nl_socket_free(mngr->cm_sync_sock); in nl_cache_mngr_free()
649 for (i = 0; i < mngr->cm_nassocs; i++) { in nl_cache_mngr_free()
650 if (mngr->cm_assocs[i].ca_cache) { in nl_cache_mngr_free()
651 nl_cache_mngt_unprovide(mngr->cm_assocs[i].ca_cache); in nl_cache_mngr_free()
652 nl_cache_free(mngr->cm_assocs[i].ca_cache); in nl_cache_mngr_free()
656 free(mngr->cm_assocs); in nl_cache_mngr_free()
658 NL_DBG(1, "Cache manager %p freed\n", mngr); in nl_cache_mngr_free()