Logo Search packages:      
Sourcecode: libnl2 version File versions  Download package

int nl_cache_mngr_add ( struct nl_cache_mngr *  mngr,
const char *  name,
change_func_t  cb,
struct nl_cache **  result 
)

Add cache responsibility to cache manager

  • mngr Cache manager.
  • name Name of cache to keep track of
  • cb Function to be called upon changes.
  • result Pointer to store added cache.
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 to keep track of any further changes.

Returns:
0 on success or a negative error code.

Definition at line 209 of file cache_mngr.c.

References nl_af_group::ag_group, nl_cache_ops::co_groups, nl_cache_ops::co_protocol, nl_cache_alloc(), nl_cache_free(), nl_cache_mngt_provide(), nl_cache_ops_lookup(), and nl_cache_refill().

{
      struct nl_cache_ops *ops;
      struct nl_cache *cache;
      struct nl_af_group *grp;
      int err, i;

      ops = nl_cache_ops_lookup(name);
      if (!ops)
            return -NLE_NOCACHE;

      if (ops->co_protocol != mngr->cm_protocol)
            return -NLE_PROTO_MISMATCH;

      if (ops->co_groups == NULL)
            return -NLE_OPNOTSUPP;

      for (i = 0; i < mngr->cm_nassocs; i++)
            if (mngr->cm_assocs[i].ca_cache &&
                mngr->cm_assocs[i].ca_cache->c_ops == ops)
                  return -NLE_EXIST;

retry:
      for (i = 0; i < mngr->cm_nassocs; i++)
            if (!mngr->cm_assocs[i].ca_cache)
                  break;

      if (i >= mngr->cm_nassocs) {
            mngr->cm_nassocs += 16;
            mngr->cm_assocs = realloc(mngr->cm_assocs,
                                mngr->cm_nassocs *
                                sizeof(struct nl_cache_assoc));
            if (mngr->cm_assocs == NULL)
                  return -NLE_NOMEM;
            else {
                  NL_DBG(1, "Increased capacity of cache manager %p " \
                          "to %d\n", mngr, mngr->cm_nassocs);
                  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_handle, grp->ag_group);
            if (err < 0)
                  goto errout_free_cache;
      }

      err = nl_cache_refill(mngr->cm_handle, cache);
      if (err < 0)
            goto errout_drop_membership;

      mngr->cm_assocs[i].ca_cache = cache;
      mngr->cm_assocs[i].ca_change = cb;

      if (mngr->cm_flags & NL_AUTO_PROVIDE)
            nl_cache_mngt_provide(cache);

      NL_DBG(1, "Added cache %p <%s> to cache manager %p\n",
             cache, nl_cache_name(cache), mngr);

      *result = cache;
      return 0;

errout_drop_membership:
      for (grp = ops->co_groups; grp->ag_group; grp++)
            nl_socket_drop_membership(mngr->cm_handle, grp->ag_group);
errout_free_cache:
      nl_cache_free(cache);

      return err;
}


Generated by  Doxygen 1.6.0   Back to index