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

📄 cache_handler.c

📁 snmp的源代码,已经在我的ubuntu下编译通过
💻 C
📖 第 1 页 / 共 2 页
字号:
                               int timeout, NetsnmpCacheLoad * load_hook,                               NetsnmpCacheFree * free_hook){    netsnmp_mib_handler *handler = NULL;    handler = netsnmp_get_cache_handler(timeout, load_hook, free_hook,                                        reginfo->rootoid,                                        reginfo->rootoid_len);    netsnmp_inject_handler(reginfo, handler);    return netsnmp_register_handler(reginfo);}NETSNMP_STATIC_INLINE char *_build_cache_name(const char *name){    char *dup = malloc(strlen(name) + strlen(CACHE_NAME) + 2);    if (NULL == dup)        return NULL;    sprintf(dup, "%s:%s", CACHE_NAME, name);    return dup;}/** Insert the cache information for a given request (PDU) */voidnetsnmp_cache_reqinfo_insert(netsnmp_cache* cache,                             netsnmp_agent_request_info * reqinfo,                             const char *name){    char *cache_name = _build_cache_name(name);    if (NULL == netsnmp_agent_get_list_data(reqinfo, cache_name)) {        DEBUGMSGTL(("verbose:helper:cache_handler", " adding '%s' to %p\n",                    cache_name, reqinfo));        netsnmp_agent_add_list_data(reqinfo,                                    netsnmp_create_data_list(cache_name,                                                             cache, NULL));    }    SNMP_FREE(cache_name);}/** Extract the cache information for a given request (PDU) */netsnmp_cache  *netsnmp_cache_reqinfo_extract(netsnmp_agent_request_info * reqinfo,                              const char *name){    netsnmp_cache  *result;    char *cache_name = _build_cache_name(name);    result = netsnmp_agent_get_list_data(reqinfo, cache_name);    SNMP_FREE(cache_name);    return result;}/** Extract the cache information for a given request (PDU) */netsnmp_cache  *netsnmp_extract_cache_info(netsnmp_agent_request_info * reqinfo){    return netsnmp_cache_reqinfo_extract(reqinfo, CACHE_NAME);}/** Check if the cache timeout has passed. Sets and return the expired flag. */intnetsnmp_cache_check_expired(netsnmp_cache *cache){    if(NULL == cache)        return 0;        if(!cache->valid || (NULL == cache->timestamp) || (-1 == cache->timeout))        cache->expired = 1;    else        cache->expired = atime_ready(cache->timestamp, 1000 * cache->timeout);        return cache->expired;}/** Reload the cache if required */intnetsnmp_cache_check_and_reload(netsnmp_cache * cache){    if (!cache) {        DEBUGMSG(("helper:cache_handler", " no cache\n"));        return 0;	/* ?? or -1 */    }    if (!cache->valid || netsnmp_cache_check_expired(cache))        return _cache_load( cache );    else {        DEBUGMSG(("helper:cache_handler", " cached (%d)\n",                  cache->timeout));        return 0;    }}/** Is the cache valid for a given request? */intnetsnmp_cache_is_valid(netsnmp_agent_request_info * reqinfo,                        const char* name){    netsnmp_cache  *cache = netsnmp_cache_reqinfo_extract(reqinfo, name);    return (cache && cache->valid);}/** Is the cache valid for a given request? * for backwards compatability. netsnmp_cache_is_valid() is preferred. */intnetsnmp_is_cache_valid(netsnmp_agent_request_info * reqinfo){    return netsnmp_cache_is_valid(reqinfo, CACHE_NAME);}/** Implements the cache handler */intnetsnmp_cache_helper_handler(netsnmp_mib_handler * handler,                             netsnmp_handler_registration * reginfo,                             netsnmp_agent_request_info * reqinfo,                             netsnmp_request_info * requests){    netsnmp_cache  *cache = NULL;    DEBUGMSGTL(("helper:cache_handler", "Got request (%d) for %s: ",                reqinfo->mode, reginfo->handlerName));    DEBUGMSGOID(("helper:cache_handler", reginfo->rootoid,                 reginfo->rootoid_len));    netsnmp_assert(handler->flags & MIB_HANDLER_AUTO_NEXT);    cache = (netsnmp_cache *) handler->myvoid;    if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,                               NETSNMP_DS_AGENT_NO_CACHING) ||        !cache || !cache->enabled || !cache->load_cache) {        DEBUGMSG(("helper:cache_handler", " caching disabled or "                  "cache not found, disabled or had no load method\n"));        return SNMP_ERR_NOERROR;    }    switch (reqinfo->mode) {    case MODE_GET:    case MODE_GETNEXT:    case MODE_GETBULK:    case MODE_SET_RESERVE1: {        netsnmp_handler_args cache_hint;        /*         * only touch cache once per pdu request, to prevent a cache         * reload while a module is using cached data.         *         * XXX: this won't catch a request reloading the cache while         * a previous (delegated) request is still using the cache.         * maybe use a reference counter?         */        if (netsnmp_cache_is_valid(reqinfo, reginfo->handlerName))            return SNMP_ERR_NOERROR;        if (cache->flags & NETSNMP_CACHE_HINT_HANDLER_ARGS) {            netsnmp_assert(NULL == cache->cache_hint);            cache_hint.handler = handler;            cache_hint.reginfo = reginfo;            cache_hint.reqinfo = reqinfo;            cache_hint.requests = requests;            cache->cache_hint = &cache_hint;        }        /*         * call the load hook, and update the cache timestamp.         * If it's not already there, add to reqinfo         */        netsnmp_cache_check_and_reload(cache);        netsnmp_cache_reqinfo_insert(cache, reqinfo, reginfo->handlerName);        cache->cache_hint = NULL;        /** next handler called automatically - 'AUTO_NEXT' */        }        return SNMP_ERR_NOERROR;    case MODE_SET_RESERVE2:    case MODE_SET_FREE:    case MODE_SET_ACTION:    case MODE_SET_UNDO:        netsnmp_assert(netsnmp_cache_is_valid(reqinfo, reginfo->handlerName));        /** next handler called automatically - 'AUTO_NEXT' */        return SNMP_ERR_NOERROR;        /*         * A (successful) SET request wouldn't typically trigger a reload of         *  the cache, but might well invalidate the current contents.         * Only do this on the last pass through.         */    case MODE_SET_COMMIT:        if (cache->valid &&             ! (cache->flags & NETSNMP_CACHE_DONT_INVALIDATE_ON_SET) ) {            cache->free_cache(cache, cache->magic);            cache->valid = 0;        }        /** next handler called automatically - 'AUTO_NEXT' */        return SNMP_ERR_NOERROR;    default:        snmp_log(LOG_WARNING, "cache_handler: Unrecognised mode (%d)\n",                 reqinfo->mode);        netsnmp_set_all_requests_error(reqinfo, requests,                                       SNMP_ERR_GENERR);        return SNMP_ERR_GENERR;    }    netsnmp_set_all_requests_error(reqinfo, requests, SNMP_ERR_GENERR);    return SNMP_ERR_GENERR;     /* should never get here */}static void_cache_free( netsnmp_cache *cache ){    if (NULL != cache->free_cache) {        cache->free_cache(cache, cache->magic);        cache->valid = 0;    }}static int_cache_load( netsnmp_cache *cache ){    int ret = -1;    /*     * If we've got a valid cache, then release it before reloading     */    if (cache->valid &&        (! (cache->flags & NETSNMP_CACHE_DONT_FREE_BEFORE_LOAD)))        _cache_free(cache);    if ( cache->load_cache)        ret = cache->load_cache(cache, cache->magic);    if (ret < 0) {        DEBUGMSG(("helper:cache_handler", " load failed (%d)\n",                  ret));        cache->valid = 0;        return ret;    }    cache->valid = 1;    cache->expired = 0;    /*     * If we didn't previously have any valid caches outstanding,     *   then schedule a pass of the auto-release routine.     */    if ((!cache_outstanding_valid) &&        (! (cache->flags & NETSNMP_CACHE_DONT_FREE_EXPIRED))) {        snmp_alarm_register(CACHE_RELEASE_FREQUENCY,                            0, release_cached_resources, NULL);        cache_outstanding_valid = 1;    }    if (cache->timestamp)        atime_setMarker(cache->timestamp);    else        cache->timestamp = atime_newMarker();    DEBUGMSG(("helper:cache_handler", " loaded (%d)\n",              cache->timeout));    return ret;}/** run regularly to automatically release cached resources. * xxx - method to prevent cache from expiring while a request *     is being processed (e.g. delegated request). proposal: *     set a flag, which would be cleared when request finished *     (which could be acomplished by a dummy data list item in *     agent req info & custom free function). */voidrelease_cached_resources(unsigned int regNo, void *clientargs){    netsnmp_cache  *cache = NULL;    cache_outstanding_valid = 0;    DEBUGMSGTL(("helper:cache_handler", "running auto-release\n"));    for (cache = cache_head; cache; cache = cache->next) {        DEBUGMSGTL(("helper:cache_handler"," checking %p (flags 0x%x)\n",                     cache, cache->flags));        if (cache->valid &&            ! (cache->flags & NETSNMP_CACHE_DONT_AUTO_RELEASE)) {            DEBUGMSGTL(("helper:cache_handler","  releasing %p\n", cache));            /*             * Check to see if this cache has timed out.             * If so, release the cached resources.             * Otherwise, note that we still have at             *   least one active cache.             */            if (netsnmp_cache_check_expired(cache)) {                if(! (cache->flags & NETSNMP_CACHE_DONT_FREE_EXPIRED))                    _cache_free(cache);            } else {                cache_outstanding_valid = 1;            }        }    }    /*     * If there are any caches still valid & active,     *   then schedule another pass.     */    if (cache_outstanding_valid) {        snmp_alarm_register(CACHE_RELEASE_FREQUENCY,                            0, release_cached_resources, NULL);    }}

⌨️ 快捷键说明

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