⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cache_handler.c

📁 snmp的源代码,已经在我的ubuntu下编译通过
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <net-snmp/net-snmp-config.h>#if HAVE_STRING_H#include <string.h>#else#include <strings.h>#endif#include <net-snmp/net-snmp-includes.h>#include <net-snmp/agent/net-snmp-agent-includes.h>#include <net-snmp/agent/cache_handler.h>#if HAVE_DMALLOC_H#include <dmalloc.h>#endifstatic netsnmp_cache  *cache_head = NULL;static int             cache_outstanding_valid = 0;static int             _cache_load( netsnmp_cache *cache );#define CACHE_RELEASE_FREQUENCY 60      /* Check for expired caches every 60s */void            release_cached_resources(unsigned int regNo,                                         void *clientargs);/** @defgroup cache_handler cache_handler: Maintains a cache of data for use by lower level handlers. *  @ingroup utilities *  This helper checks to see whether the data has been loaded "recently" *  (according to the timeout for that particular cache) and calls the *  registered "load_cache" routine if necessary. *  The lower handlers can then work with this local cached data. * *  A timeout value of -1 will cause netsnmp_cache_check_expired() to *  always return true, and thus the cache will be reloaded for every *  request. * *  To minimze resource use by the agent, a periodic callback checks for *  expired caches, and will call the free_cache function for any expired *  cache. * *  The load_cache route should return a negative number if the cache *  was not successfully loaded. 0 or any positive number indicates successs. * * *  Several flags can be set to affect the operations on the cache. * *  If NETSNMP_CACHE_DONT_INVALIDATE_ON_SET is set, the free_cache method *  will not be called after a set request has processed. It is assumed that *  the lower mib handler using the cache has maintained cache consistency. * *  If NETSNMP_CACHE_DONT_FREE_BEFORE_LOAD is set, the free_cache method *  will not be called before the load_cache method is called. It is assumed *  that the load_cache routine will properly deal with being called with a *  valid cache. * *  If NETSNMP_CACHE_DONT_FREE_EXPIRED is set, the free_cache method will *  not be called with the cache expires. The expired flag will be set, but *  the valid flag will not be cleared. It is assumed that the load_cache *  routine will properly deal with being called with a valid cache. * *  If NETSNMP_CACHE_PRELOAD is set when a the cache handler is created, *  the cache load routine will be called immediately. * *  If NETSNMP_CACHE_DONT_AUTO_RELEASE is set, the periodic callback that *  checks for expired caches will skip the cache. The cache will only be *  checked for expiration when a request triggers the cache handler. This *  is useful if the cache has it's own periodic callback to keep the cache *  fresh. * *  If NETSNMP_CACHE_AUTO_RELOAD is set, a timer will be set up to reload *  the cache when it expires. This is useful for keeping the cache fresh, *  even in the absence of incoming snmp requests. * * *  Here are some suggestions for some common situations. * *  Cached File: *      If your table is based on a file that may periodically change, *      you can test the modification date to see if the file has *      changed since the last cache load. To get the cache helper to call *      the load function for every request, set the timeout to -1, which *      will cause the cache to always report that it is expired. This means *      that you will want to prevent the agent from flushing the cache when *      it has expired, and you will have to flush it manually if you *      detect that the file has changed. To accomplish this, set the *      following flags: * *          NETSNMP_CACHE_DONT_FREE_EXPIRED *          NETSNMP_CACHE_DONT_AUTO_RELEASE * * *  Constant (periodic) reload: *      If you want the cache kept up to date regularly, even if no requests *      for the table are received, you can have your cache load routine *      called periodically. This is very useful if you need to monitor the *      data for changes (eg a <i>LastChanged</i> object). You will need to *      prevent the agent from flushing the cache when it expires. Set the *      cache timeout to the frequency, in seconds, that you wish to *      reload your cache, and set the following flags: * *          NETSNMP_CACHE_DONT_FREE_EXPIRED *          NETSNMP_CACHE_DONT_AUTO_RELEASE *          NETSNMP_CACHE_AUTO_RELOAD * *  @{ *//** get cache head * @internal * unadvertised function to get cache head. You really should not * do this, since the internal storage mechanism might change. */netsnmp_cache *netsnmp_cache_get_head(void){    return cache_head;}/** find existing cache */netsnmp_cache *netsnmp_cache_find_by_oid(oid * rootoid, int rootoid_len){    netsnmp_cache  *cache;    for (cache = cache_head; cache; cache = cache->next) {        if (0 == netsnmp_oid_equals(cache->rootoid, cache->rootoid_len,                                    rootoid, rootoid_len))            return cache;    }        return NULL;}/** returns a cache */netsnmp_cache *netsnmp_cache_create(int timeout, NetsnmpCacheLoad * load_hook,                     NetsnmpCacheFree * free_hook,                     oid * rootoid, int rootoid_len){    netsnmp_cache  *cache = NULL;    cache = SNMP_MALLOC_TYPEDEF(netsnmp_cache);    if (NULL == cache) {        snmp_log(LOG_ERR,"malloc error in netsnmp_cache_create\n");        return NULL;    }    cache->timeout = timeout;    cache->load_cache = load_hook;    cache->free_cache = free_hook;    cache->enabled = 1;    if(0 == cache->timeout)        cache->timeout = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID,                                            NETSNMP_DS_AGENT_CACHE_TIMEOUT);        /*     * Add the registered OID information, and tack     * this onto the list for cache SNMP management     *     * Note that this list is not ordered.     *    table_iterator rules again!     */    if (rootoid) {        cache->rootoid = snmp_duplicate_objid(rootoid, rootoid_len);        cache->rootoid_len = rootoid_len;        cache->next = cache_head;        if (cache_head)            cache_head->prev = cache;        cache_head = cache;    }    return cache;}/** callback function to call cache load function */static void_timer_reload(unsigned int regNo, void *clientargs){    netsnmp_cache *cache = (netsnmp_cache *)clientargs;    DEBUGMSGT(("cache_timer:start", "loading cache %p\n", cache));    cache->expired = 1;    _cache_load(cache);}/** starts the recurring cache_load callback */unsigned intnetsnmp_cache_timer_start(netsnmp_cache *cache){    if(NULL == cache)        return 0;    if(0 != cache->timer_id) {        snmp_log(LOG_WARNING, "cache has existing timer id.\n");        return cache->timer_id;    }        if(! (cache->flags & NETSNMP_CACHE_AUTO_RELOAD)) {        snmp_log(LOG_ERR,                 "cache_timer_start called but auto_reload not set.\n");        return 0;    }    cache->timer_id = snmp_alarm_register(cache->timeout, SA_REPEAT,                                          _timer_reload, cache);    if(0 == cache->timer_id) {        snmp_log(LOG_ERR,"could not register alarm\n");        return 0;    }    DEBUGMSGT(("cache_timer:start",               "starting timer %d for cache %p\n", cache->timer_id, cache));    return cache->timer_id;}/** stops the recurring cache_load callback */voidnetsnmp_cache_timer_stop(netsnmp_cache *cache){    if(NULL == cache)        return;    if(0 == cache->timer_id) {        snmp_log(LOG_WARNING, "cache has no timer id.\n");        return;    }    DEBUGMSGT(("cache_timer:stop",               "stopping timer %d for cache %p\n", cache->timer_id, cache));    snmp_alarm_unregister(cache->timer_id);}/** returns a cache handler that can be injected into a given handler chain.   */netsnmp_mib_handler *netsnmp_cache_handler_get(netsnmp_cache* cache){    netsnmp_mib_handler *ret = NULL;        ret = netsnmp_create_handler("cache_handler",                                 netsnmp_cache_helper_handler);    if (ret) {        ret->flags |= MIB_HANDLER_AUTO_NEXT;        ret->myvoid = (void *) cache;                if(NULL != cache) {            if ((cache->flags & NETSNMP_CACHE_PRELOAD) && ! cache->valid) {                /*                 * load cache, ignore rc                 * (failed load doesn't affect registration)                 */                (void)_cache_load(cache);            }            if (cache->flags & NETSNMP_CACHE_AUTO_RELOAD)                netsnmp_cache_timer_start(cache);                    }    }    return ret;}/** returns a cache handler that can be injected into a given handler chain.   */netsnmp_mib_handler *netsnmp_get_cache_handler(int timeout, NetsnmpCacheLoad * load_hook,                          NetsnmpCacheFree * free_hook,                          oid * rootoid, int rootoid_len){    netsnmp_mib_handler *ret = NULL;    netsnmp_cache  *cache = NULL;    ret = netsnmp_cache_handler_get(NULL);    if (ret) {        cache = netsnmp_cache_create(timeout, load_hook, free_hook,                                     rootoid, rootoid_len);        ret->myvoid = (void *) cache;    }    return ret;}/** functionally the same as calling netsnmp_register_handler() but also * injects a cache handler at the same time for you. */intnetsnmp_cache_handler_register(netsnmp_handler_registration * reginfo,                               netsnmp_cache* cache){    netsnmp_mib_handler *handler = NULL;    handler = netsnmp_cache_handler_get(cache);    netsnmp_inject_handler(reginfo, handler);    return netsnmp_register_handler(reginfo);}/** functionally the same as calling netsnmp_register_handler() but also * injects a cache handler at the same time for you. */intnetsnmp_register_cache_handler(netsnmp_handler_registration * reginfo,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -