cache__handler_8c-source.html from net-snmp at Krugle
Show cache__handler_8c-source.html syntax highlighted
<!--#set var="section" value="development" -->
<!--#include virtual="/page-top.html" -->
<!-- CONTENT START -->
<!-- Generated by Doxygen 1.3.9.1 -->
<div class="qindex">
<a class="qindex" href="index.html">Main Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class=
"qindex" href="annotated.html">Data Structures</a> | <a class="qindex" href="files.html">File List</a> | <a class=
"qindex" href="functions.html">Data Fields</a> | <a class="qindex" href="pages.html">Related Pages</a> | <a class=
"qindex" href="examples.html">Examples</a>
</div>
<div class="nav">
<a class="el" href="dir_000003.html">agent</a> / <a class="el" href="dir_000004.html">helpers</a>
</div>
<h1>cache_handler.c</h1>
<div class="fragment">
<pre class="fragment">
00001 <span class="preprocessor">#include <net-snmp/net-snmp-config.h></span>
00002
00003 <span class="preprocessor">#if HAVE_STRING_H</span>
00004 <span class="preprocessor">#include <string.h></span>
00005 <span class="preprocessor">#else</span>
00006 <span class="preprocessor">#include <strings.h></span>
00007 <span class="preprocessor">#endif</span>
00008
00009 <span class="preprocessor">#include <net-snmp/net-snmp-includes.h></span>
00010 <span class="preprocessor">#include <net-snmp/agent/net-snmp-agent-includes.h></span>
00011
00012 <span class="preprocessor">#include <net-snmp/agent/cache_handler.h></span>
00013
00014 <span class="keyword">static</span> netsnmp_cache *cache_head = NULL;
00015 <span class="keyword">static</span> <span class="keywordtype">int</span> cache_outstanding_valid = 0;
00016 <span class="keyword">static</span> <span class="keywordtype">int</span> _cache_load( netsnmp_cache *cache );
00017
00018 <span class="preprocessor">#define CACHE_RELEASE_FREQUENCY 60 </span><span class=
"comment">/* Check for expired caches every 60s */</span>
00019
00020 <span class="keywordtype">void</span> <a class="code" href=
"group__cache__handler.html#ga21">release_cached_resources</a>(<span class="keywordtype">unsigned</span> <span class=
"keywordtype">int</span> regNo,
00021 <span class="keywordtype">void</span> *clientargs);
00022
00110 netsnmp_cache *
<a name="l00111" id="l00111"></a><a class="code" href="group__cache__handler.html#ga0">00111</a> <a class="code" href=
"group__cache__handler.html#ga0">netsnmp_cache_get_head</a>(<span class="keywordtype">void</span>)
00112 {
00113 <span class="keywordflow">return</span> cache_head;
00114 }
00115
00118 netsnmp_cache *
<a name="l00119" id="l00119"></a><a class="code" href="group__cache__handler.html#ga1">00119</a> <a class="code" href=
"group__cache__handler.html#ga1">netsnmp_cache_find_by_oid</a>(oid * rootoid, <span class="keywordtype">int</span> rootoid_len)
00120 {
00121 netsnmp_cache *cache;
00122
00123 <span class="keywordflow">for</span> (cache = cache_head; cache; cache = cache->next) {
00124 <span class="keywordflow">if</span> (0 == <a class="code" href=
"group__library.html#ga106">netsnmp_oid_equals</a>(cache->rootoid, cache->rootoid_len,
00125 rootoid, rootoid_len))
00126 <span class="keywordflow">return</span> cache;
00127 }
00128
00129 <span class="keywordflow">return</span> NULL;
00130 }
00131
00134 netsnmp_cache *
<a name="l00135" id="l00135"></a><a class="code" href="group__cache__handler.html#ga2">00135</a> <a class="code" href=
"group__cache__handler.html#ga2">netsnmp_cache_create</a>(<span class=
"keywordtype">int</span> timeout, NetsnmpCacheLoad * load_hook,
00136 NetsnmpCacheFree * free_hook,
00137 oid * rootoid, <span class="keywordtype">int</span> rootoid_len)
00138 {
00139 netsnmp_cache *cache = NULL;
00140
00141 cache = <a class="code" href="group__util.html#ga39">SNMP_MALLOC_TYPEDEF</a>(netsnmp_cache);
00142 <span class="keywordflow">if</span> (NULL == cache) {
00143 <a class="code" href="group__snmp__logging.html#ga41">snmp_log</a>(LOG_ERR,<span class=
"stringliteral">"malloc error in netsnmp_cache_create\n"</span>);
00144 <span class="keywordflow">return</span> NULL;
00145 }
00146 cache->timeout = timeout;
00147 cache->load_cache = load_hook;
00148 cache->free_cache = free_hook;
00149 cache->enabled = 1;
00150
00151 <span class="keywordflow">if</span>(0 == cache->timeout)
00152 cache->timeout = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID,
00153 NETSNMP_DS_AGENT_CACHE_TIMEOUT);
00154
00155
00156 <span class="comment">/*</span>
00157 <span class="comment"> * Add the registered OID information, and tack</span>
00158 <span class="comment"> * this onto the list for cache SNMP management</span>
00159 <span class="comment"> *</span>
00160 <span class="comment"> * Note that this list is not ordered.</span>
00161 <span class="comment"> * table_iterator rules again!</span>
00162 <span class="comment"> */</span>
00163 <span class="keywordflow">if</span> (rootoid) {
00164 cache->rootoid = snmp_duplicate_objid(rootoid, rootoid_len);
00165 cache->rootoid_len = rootoid_len;
00166 cache->next = cache_head;
00167 <span class="keywordflow">if</span> (cache_head)
00168 cache_head->prev = cache;
00169 cache_head = cache;
00170 }
00171
00172 <span class="keywordflow">return</span> cache;
00173 }
00174
00176 <span class="keyword">static</span> <span class="keywordtype">void</span>
00177 _timer_reload(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> regNo, <span class=
"keywordtype">void</span> *clientargs)
00178 {
00179 netsnmp_cache *cache = (netsnmp_cache *)clientargs;
00180
00181 DEBUGMSGT((<span class="stringliteral">"cache_timer:start"</span>, <span class=
"stringliteral">"loading cache %p\n"</span>, cache));
00182
00183 cache->expired = 1;
00184
00185 _cache_load(cache);
00186 }
00187
00189 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span>
<a name="l00190" id="l00190"></a><a class="code" href="group__cache__handler.html#ga4">00190</a> <a class="code" href=
"group__cache__handler.html#ga4">netsnmp_cache_timer_start</a>(netsnmp_cache *cache)
00191 {
00192 <span class="keywordflow">if</span>(NULL == cache)
00193 <span class="keywordflow">return</span> 0;
00194
00195 DEBUGMSGTL(( <span class="stringliteral">"cache_timer:start"</span>, <span class="stringliteral">"OID: "</span>));
00196 DEBUGMSGOID((<span class="stringliteral">"cache_timer:start"</span>, cache->rootoid, cache->rootoid_len));
00197 DEBUGMSG(( <span class="stringliteral">"cache_timer:start"</span>, <span class="stringliteral">"\n"</span>));
00198
00199 <span class="keywordflow">if</span>(0 != cache->timer_id) {
00200 <a class="code" href="group__snmp__logging.html#ga41">snmp_log</a>(LOG_WARNING, <span class=
"stringliteral">"cache has existing timer id.\n"</span>);
00201 <span class="keywordflow">return</span> cache->timer_id;
00202 }
00203
00204 <span class="keywordflow">if</span>(! (cache->flags & NETSNMP_CACHE_AUTO_RELOAD)) {
00205 <a class="code" href="group__snmp__logging.html#ga41">snmp_log</a>(LOG_ERR,
00206 <span class="stringliteral">"cache_timer_start called but auto_reload not set.\n"</span>);
00207 <span class="keywordflow">return</span> 0;
00208 }
00209
00210 cache->timer_id = <a class="code" href=
"group__snmp__alarm.html#ga14">snmp_alarm_register</a>(cache->timeout, SA_REPEAT,
00211 _timer_reload, cache);
00212 <span class="keywordflow">if</span>(0 == cache->timer_id) {
00213 <a class="code" href="group__snmp__logging.html#ga41">snmp_log</a>(LOG_ERR,<span class=
"stringliteral">"could not register alarm\n"</span>);
00214 <span class="keywordflow">return</span> 0;
00215 }
00216
00217 cache->flags &= ~NETSNMP_CACHE_AUTO_RELOAD;
00218 DEBUGMSGT((<span class="stringliteral">"cache_timer:start"</span>,
00219 <span class="stringliteral">"starting timer %d for cache %p\n"</span>, cache->timer_id, cache));
00220 <span class="keywordflow">return</span> cache->timer_id;
00221 }
00222
00224 <span class="keywordtype">void</span>
<a name="l00225" id="l00225"></a><a class="code" href="group__cache__handler.html#ga5">00225</a> <a class="code" href=
"group__cache__handler.html#ga5">netsnmp_cache_timer_stop</a>(netsnmp_cache *cache)
00226 {
00227 <span class="keywordflow">if</span>(NULL == cache)
00228 <span class="keywordflow">return</span>;
00229
00230 <span class="keywordflow">if</span>(0 == cache->timer_id) {
00231 <a class="code" href="group__snmp__logging.html#ga41">snmp_log</a>(LOG_WARNING, <span class=
"stringliteral">"cache has no timer id.\n"</span>);
00232 <span class="keywordflow">return</span>;
00233 }
00234
00235 DEBUGMSGT((<span class="stringliteral">"cache_timer:stop"</span>,
00236 <span class="stringliteral">"stopping timer %d for cache %p\n"</span>, cache->timer_id, cache));
00237
00238 <a class="code" href="group__snmp__alarm.html#ga6">snmp_alarm_unregister</a>(cache->timer_id);
00239 cache->flags |= NETSNMP_CACHE_AUTO_RELOAD;
00240 }
00241
00242
00245 <a class="code" href="structnetsnmp__mib__handler__s.html">netsnmp_mib_handler</a> *
<a name="l00246" id="l00246"></a><a class="code" href="group__cache__handler.html#ga6">00246</a> <a class="code" href=
"group__cache__handler.html#ga6">netsnmp_cache_handler_get</a>(netsnmp_cache* cache)
00247 {
00248 <a class="code" href="structnetsnmp__mib__handler__s.html">netsnmp_mib_handler</a> *ret = NULL;
00249
00250 ret = <a class="code" href="group__handler.html#ga7">netsnmp_create_handler</a>(<span class=
"stringliteral">"cache_handler"</span>,
00251 netsnmp_cache_helper_handler);
00252 <span class="keywordflow">if</span> (ret) {
00253 ret-><a class="code" href="structnetsnmp__mib__handler__s.html#o2">flags</a> |= MIB_HANDLER_AUTO_NEXT;
00254 ret-><a class="code" href="structnetsnmp__mib__handler__s.html#o1">myvoid</a> = (<span class=
"keywordtype">void</span> *) cache;
00255
00256 <span class="keywordflow">if</span>(NULL != cache) {
00257 <span class=
"keywordflow">if</span> ((cache->flags & NETSNMP_CACHE_PRELOAD) && ! cache->valid) {
00258 <span class="comment">/*</span>
00259 <span class="comment"> * load cache, ignore rc</span>
00260 <span class="comment"> * (failed load doesn't affect registration)</span>
00261 <span class="comment"> */</span>
00262 (void)_cache_load(cache);
00263 }
00264 <span class="keywordflow">if</span> (cache->flags & NETSNMP_CACHE_AUTO_RELOAD)
00265 <a class="code" href="group__cache__handler.html#ga4">netsnmp_cache_timer_start</a>(cache);
00266
00267 }
00268 }
00269 <span class="keywordflow">return</span> ret;
00270 }
00271
00274 <a class="code" href="structnetsnmp__mib__handler__s.html">netsnmp_mib_handler</a> *
<a name="l00275" id="l00275"></a><a class="code" href="group__cache__handler.html#ga7">00275</a> <a class="code" href=
"group__cache__handler.html#ga7">netsnmp_get_cache_handler</a>(<span class=
"keywordtype">int</span> timeout, NetsnmpCacheLoad * load_hook,
00276 NetsnmpCacheFree * free_hook,
00277 oid * rootoid, <span class="keywordtype">int</span> rootoid_len)
00278 {
00279 <a class="code" href="structnetsnmp__mib__handler__s.html">netsnmp_mib_handler</a> *ret = NULL;
00280 netsnmp_cache *cache = NULL;
00281
00282 ret = <a class="code" href="group__cache__handler.html#ga6">netsnmp_cache_handler_get</a>(NULL);
00283 <span class="keywordflow">if</span> (ret) {
00284 cache = <a class="code" href=
"group__cache__handler.html#ga2">netsnmp_cache_create</a>(timeout, load_hook, free_hook,
00285 rootoid, rootoid_len);
00286 ret-><a class="code" href="structnetsnmp__mib__handler__s.html#o1">myvoid</a> = (<span class=
"keywordtype">void</span> *) cache;
00287 }
00288 <span class="keywordflow">return</span> ret;
00289 }
00290
00293 <span class="keywordtype">int</span>
<a name="l00294" id="l00294"></a><a class="code" href="group__cache__handler.html#ga8">00294</a> <a class="code" href=
"group__cache__handler.html#ga8">netsnmp_cache_handler_register</a>(<a class="code" href=
"structnetsnmp__handler__registration__s.html">netsnmp_handler_registration</a> * reginfo,
00295 netsnmp_cache* cache)
00296 {
00297 <a class="code" href="structnetsnmp__mib__handler__s.html">netsnmp_mib_handler</a> *handler = NULL;
00298 handler = <a class="code" href="group__cache__handler.html#ga6">netsnmp_cache_handler_get</a>(cache);
00299
00300 <a class="code" href="group__handler.html#ga14">netsnmp_inject_handler</a>(reginfo, handler);
00301 <span class="keywordflow">return</span> <a class="code" href=
"group__handler.html#ga10">netsnmp_register_handler</a>(reginfo);
00302 }
00303
00306 <span class="keywordtype">int</span>
<a name="l00307" id="l00307"></a><a class="code" href="group__cache__handler.html#ga9">00307</a> <a class="code" href=
"group__cache__handler.html#ga9">netsnmp_register_cache_handler</a>(<a class="code" href=
"structnetsnmp__handler__registration__s.html">netsnmp_handler_registration</a> * reginfo,
00308 <span class="keywordtype">int</span> timeout, NetsnmpCacheLoad * load_hook,
00309 NetsnmpCacheFree * free_hook)
00310 {
00311 <a class="code" href="structnetsnmp__mib__handler__s.html">netsnmp_mib_handler</a> *handler = NULL;
00312 handler = <a class="code" href=
"group__cache__handler.html#ga7">netsnmp_get_cache_handler</a>(timeout, load_hook, free_hook,
00313 reginfo-><a class="code" href=
"structnetsnmp__handler__registration__s.html#o2">rootoid</a>,
00314 reginfo-><a class="code" href=
"structnetsnmp__handler__registration__s.html#o3">rootoid_len</a>);
00315
00316 <a class="code" href="group__handler.html#ga14">netsnmp_inject_handler</a>(reginfo, handler);
00317 <span class="keywordflow">return</span> <a class="code" href=
"group__handler.html#ga10">netsnmp_register_handler</a>(reginfo);
00318 }
00319
00320 NETSNMP_STATIC_INLINE <span class="keywordtype">char</span> *
00321 _build_cache_name(<span class="keyword">const</span> <span class="keywordtype">char</span> *name)
00322 {
00323 <span class="keywordtype">char</span> *dup = malloc(strlen(name) + strlen(CACHE_NAME) + 2);
00324 <span class="keywordflow">if</span> (NULL == dup)
00325 <span class="keywordflow">return</span> NULL;
00326 sprintf(dup, <span class="stringliteral">"%s:%s"</span>, CACHE_NAME, name);
00327 <span class="keywordflow">return</span> dup;
00328 }
00329
00331 <span class="keywordtype">void</span>
<a name="l00332" id="l00332"></a><a class="code" href="group__cache__handler.html#ga11">00332</a> <a class="code" href=
"group__cache__handler.html#ga11">netsnmp_cache_reqinfo_insert</a>(netsnmp_cache* cache,
00333 <a class="code" href=
"structnetsnmp__agent__request__info__s.html">netsnmp_agent_request_info</a> * reqinfo,
00334 <span class="keyword">const</span> <span class="keywordtype">char</span> *name)
00335 {
00336 <span class="keywordtype">char</span> *cache_name = _build_cache_name(name);
00337 <span class="keywordflow">if</span> (NULL == netsnmp_agent_get_list_data(reqinfo, cache_name)) {
00338 DEBUGMSGTL((<span class="stringliteral">"verbose:helper:cache_handler"</span>, <span class=
"stringliteral">" adding '%s' to %p\n"</span>,
00339 cache_name, reqinfo));
00340 netsnmp_agent_add_list_data(reqinfo,
00341 <a class="code" href=
"group__data__list.html#ga3">netsnmp_create_data_list</a>(cache_name,
00342 cache, NULL));
00343 }
00344 <a class="code" href="group__util.html#ga36">SNMP_FREE</a>(cache_name);
00345 }
00346
00348 netsnmp_cache *
<a name="l00349" id="l00349"></a><a class="code" href="group__cache__handler.html#ga12">00349</a> <a class="code" href=
"group__cache__handler.html#ga12">netsnmp_cache_reqinfo_extract</a>(<a class="code" href=
"structnetsnmp__agent__request__info__s.html">netsnmp_agent_request_info</a> * reqinfo,
00350 <span class="keyword">const</span> <span class="keywordtype">char</span> *name)
00351 {
00352 netsnmp_cache *result;
00353 <span class="keywordtype">char</span> *cache_name = _build_cache_name(name);
00354 result = netsnmp_agent_get_list_data(reqinfo, cache_name);
00355 <a class="code" href="group__util.html#ga36">SNMP_FREE</a>(cache_name);
00356 <span class="keywordflow">return</span> result;
00357 }
00358
00360 netsnmp_cache *
<a name="l00361" id="l00361"></a><a class="code" href="group__cache__handler.html#ga13">00361</a> <a class="code" href=
"group__cache__handler.html#ga13">netsnmp_extract_cache_info</a>(<a class="code" href=
"structnetsnmp__agent__request__info__s.html">netsnmp_agent_request_info</a> * reqinfo)
00362 {
00363 <span class="keywordflow">return</span> <a class="code" href=
"group__cache__handler.html#ga12">netsnmp_cache_reqinfo_extract</a>(reqinfo, CACHE_NAME);
00364 }
00365
00366
00368 <span class="keywordtype">int</span>
<a name="l00369" id="l00369"></a><a class="code" href="group__cache__handler.html#ga14">00369</a> <a class="code" href=
"group__cache__handler.html#ga14">netsnmp_cache_check_expired</a>(netsnmp_cache *cache)
00370 {
00371 <span class="keywordflow">if</span>(NULL == cache)
00372 <span class="keywordflow">return</span> 0;
00373
00374 <span class="keywordflow">if</span>(!cache->valid || (NULL == cache->timestamp) || (-1 == cache->timeout))
00375 cache->expired = 1;
00376 <span class="keywordflow">else</span>
00377 cache->expired = <a class="code" href=
"group__util.html#ga20">atime_ready</a>(cache->timestamp, 1000 * cache->timeout);
00378
00379 <span class="keywordflow">return</span> cache->expired;
00380 }
00381
00383 <span class="keywordtype">int</span>
<a name="l00384" id="l00384"></a><a class="code" href="group__cache__handler.html#ga15">00384</a> <a class="code" href=
"group__cache__handler.html#ga15">netsnmp_cache_check_and_reload</a>(netsnmp_cache * cache)
00385 {
00386 <span class="keywordflow">if</span> (!cache) {
00387 DEBUGMSG((<span class="stringliteral">"helper:cache_handler"</span>, <span class=
"stringliteral">" no cache\n"</span>));
00388 <span class="keywordflow">return</span> 0; <span class="comment">/* ?? or -1 */</span>
00389 }
00390 <span class="keywordflow">if</span> (!cache->valid || <a class="code" href=
"group__cache__handler.html#ga14">netsnmp_cache_check_expired</a>(cache))
00391 <span class="keywordflow">return</span> _cache_load( cache );
00392 <span class="keywordflow">else</span> {
00393 DEBUGMSG((<span class="stringliteral">"helper:cache_handler"</span>, <span class=
"stringliteral">" cached (%d)\n"</span>,
00394 cache->timeout));
00395 <span class="keywordflow">return</span> 0;
00396 }
00397 }
00398
00400 <span class="keywordtype">int</span>
<a name="l00401" id="l00401"></a><a class="code" href="group__cache__handler.html#ga16">00401</a> <a class="code" href=
"group__cache__handler.html#ga16">netsnmp_cache_is_valid</a>(<a class="code" href=
"structnetsnmp__agent__request__info__s.html">netsnmp_agent_request_info</a> * reqinfo,
00402 <span class="keyword">const</span> <span class="keywordtype">char</span>* name)
00403 {
00404 netsnmp_cache *cache = <a class="code" href=
"group__cache__handler.html#ga12">netsnmp_cache_reqinfo_extract</a>(reqinfo, name);
00405 <span class="keywordflow">return</span> (cache && cache->valid);
00406 }
00407
00411 <span class="keywordtype">int</span>
<a name="l00412" id="l00412"></a><a class="code" href="group__cache__handler.html#ga17">00412</a> <a class="code" href=
"group__cache__handler.html#ga17">netsnmp_is_cache_valid</a>(<a class="code" href=
"structnetsnmp__agent__request__info__s.html">netsnmp_agent_request_info</a> * reqinfo)
00413 {
00414 <span class="keywordflow">return</span> <a class="code" href=
"group__cache__handler.html#ga16">netsnmp_cache_is_valid</a>(reqinfo, CACHE_NAME);
00415 }
00416
00418 <span class="keywordtype">int</span>
<a name="l00419" id="l00419"></a><a class="code" href="group__cache__handler.html#ga18">00419</a> <a class="code" href=
"group__cache__handler.html#ga18">netsnmp_cache_helper_handler</a>(<a class="code" href=
"structnetsnmp__mib__handler__s.html">netsnmp_mib_handler</a> * handler,
00420 <a class="code" href=
"structnetsnmp__handler__registration__s.html">netsnmp_handler_registration</a> * reginfo,
00421 <a class="code" href=
"structnetsnmp__agent__request__info__s.html">netsnmp_agent_request_info</a> * reqinfo,
00422 <a class="code" href=
"structnetsnmp__request__info__s.html">netsnmp_request_info</a> * requests)
00423 {
00424 netsnmp_cache *cache = NULL;
00425 netsnmp_handler_args cache_hint;
00426
00427 DEBUGMSGTL((<span class="stringliteral">"helper:cache_handler"</span>, <span class=
"stringliteral">"Got request (%d) for %s: "</span>,
00428 reqinfo-><a class="code" href=
"structnetsnmp__agent__request__info__s.html#o0">mode</a>, reginfo-><a class="code" href=
"structnetsnmp__handler__registration__s.html#o0">handlerName</a>));
00429 DEBUGMSGOID((<span class="stringliteral">"helper:cache_handler"</span>, reginfo-><a class="code" href=
"structnetsnmp__handler__registration__s.html#o2">rootoid</a>,
00430 reginfo-><a class="code" href="structnetsnmp__handler__registration__s.html#o3">rootoid_len</a>));
00431 DEBUGMSG((<span class="stringliteral">"helper:cache_handler"</span>, <span class="stringliteral">"\n"</span>));
00432
00433 netsnmp_assert(handler-><a class="code" href=
"structnetsnmp__mib__handler__s.html#o2">flags</a> & MIB_HANDLER_AUTO_NEXT);
00434
00435 cache = (netsnmp_cache *) handler-><a class="code" href="structnetsnmp__mib__handler__s.html#o1">myvoid</a>;
00436 <span class="keywordflow">if</span> (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
00437 NETSNMP_DS_AGENT_NO_CACHING) ||
00438 !cache || !cache->enabled || !cache->load_cache) {
00439 DEBUGMSG((<span class="stringliteral">"helper:cache_handler"</span>, <span class=
"stringliteral">" caching disabled or "</span>
00440 <span class="stringliteral">"cache not found, disabled or had no load method\n"</span>));
00441 <span class="keywordflow">return</span> SNMP_ERR_NOERROR;
00442 }
00443
00444 <span class="comment">/*</span>
00445 <span class="comment"> * Make the handler-chain parameters available to</span>
00446 <span class="comment"> * the cache_load hook routine.</span>
00447 <span class="comment"> */</span>
00448 cache_hint.handler = handler;
00449 cache_hint.reginfo = reginfo;
00450 cache_hint.reqinfo = reqinfo;
00451 cache_hint.requests = requests;
00452 cache->cache_hint = &cache_hint;
00453
00454 <span class="keywordflow">switch</span> (reqinfo-><a class="code" href=
"structnetsnmp__agent__request__info__s.html#o0">mode</a>) {
00455
00456 <span class="keywordflow">case</span> MODE_GET:
00457 <span class="keywordflow">case</span> MODE_GETNEXT:
00458 <span class="keywordflow">case</span> MODE_GETBULK:
00459 <span class="keywordflow">case</span> MODE_SET_RESERVE1: {
00460
00461 <span class="comment">/*</span>
00462 <span class="comment"> * only touch cache once per pdu request, to prevent a cache</span>
00463 <span class="comment"> * reload while a module is using cached data.</span>
00464 <span class="comment"> *</span>
00465 <span class="comment"> * XXX: this won't catch a request reloading the cache while</span>
00466 <span class="comment"> * a previous (delegated) request is still using the cache.</span>
00467 <span class="comment"> * maybe use a reference counter?</span>
00468 <span class="comment"> */</span>
00469 <span class="keywordflow">if</span> (<a class="code" href=
"group__cache__handler.html#ga16">netsnmp_cache_is_valid</a>(reqinfo, reginfo-><a class="code" href=
"structnetsnmp__handler__registration__s.html#o0">handlerName</a>))
00470 <span class="keywordflow">return</span> SNMP_ERR_NOERROR;
00471
00472 <span class="comment">/*</span>
00473 <span class="comment"> * call the load hook, and update the cache timestamp.</span>
00474 <span class="comment"> * If it's not already there, add to reqinfo</span>
00475 <span class="comment"> */</span>
00476 <a class="code" href="group__cache__handler.html#ga15">netsnmp_cache_check_and_reload</a>(cache);
00477 <a class="code" href=
"group__cache__handler.html#ga11">netsnmp_cache_reqinfo_insert</a>(cache, reqinfo, reginfo-><a class="code" href=
"structnetsnmp__handler__registration__s.html#o0">handlerName</a>);
00479 }
00480 <span class="keywordflow">return</span> SNMP_ERR_NOERROR;
00481
00482 <span class="keywordflow">case</span> MODE_SET_RESERVE2:
00483 <span class="keywordflow">case</span> MODE_SET_FREE:
00484 <span class="keywordflow">case</span> MODE_SET_ACTION:
00485 <span class="keywordflow">case</span> MODE_SET_UNDO:
00486 netsnmp_assert(<a class="code" href=
"group__cache__handler.html#ga16">netsnmp_cache_is_valid</a>(reqinfo, reginfo-><a class="code" href=
"structnetsnmp__handler__registration__s.html#o0">handlerName</a>));
00488 <span class="keywordflow">return</span> SNMP_ERR_NOERROR;
00489
00490 <span class="comment">/*</span>
00491 <span class="comment"> * A (successful) SET request wouldn't typically trigger a reload of</span>
00492 <span class="comment"> * the cache, but might well invalidate the current contents.</span>
00493 <span class="comment"> * Only do this on the last pass through.</span>
00494 <span class="comment"> */</span>
00495 <span class="keywordflow">case</span> MODE_SET_COMMIT:
00496 <span class="keywordflow">if</span> (cache->valid &&
00497 ! (cache->flags & NETSNMP_CACHE_DONT_INVALIDATE_ON_SET) ) {
00498 cache->free_cache(cache, cache->magic);
00499 cache->valid = 0;
00500 }
00502 <span class="keywordflow">return</span> SNMP_ERR_NOERROR;
00503
00504 <span class="keywordflow">default</span>:
00505 <a class="code" href="group__snmp__logging.html#ga41">snmp_log</a>(LOG_WARNING, <span class=
"stringliteral">"cache_handler: Unrecognised mode (%d)\n"</span>,
00506 reqinfo-><a class="code" href="structnetsnmp__agent__request__info__s.html#o0">mode</a>);
00507 <a class="code" href="group__snmp__agent.html#ga73">netsnmp_request_set_error_all</a>(requests, SNMP_ERR_GENERR);
00508 <span class="keywordflow">return</span> SNMP_ERR_GENERR;
00509 }
00510 <a class="code" href="group__snmp__agent.html#ga73">netsnmp_request_set_error_all</a>(requests, SNMP_ERR_GENERR);
00511 <span class="keywordflow">return</span> SNMP_ERR_GENERR; <span class="comment">/* should never get here */</span>
00512 }
00513
00514 <span class="keyword">static</span> <span class="keywordtype">void</span>
00515 _cache_free( netsnmp_cache *cache )
00516 {
00517 <span class="keywordflow">if</span> (NULL != cache->free_cache) {
00518 cache->free_cache(cache, cache->magic);
00519 cache->valid = 0;
00520 }
00521 }
00522
00523 <span class="keyword">static</span> <span class="keywordtype">int</span>
00524 _cache_load( netsnmp_cache *cache )
00525 {
00526 <span class="keywordtype">int</span> ret = -1;
00527
00528 <span class="comment">/*</span>
00529 <span class="comment"> * If we've got a valid cache, then release it before reloading</span>
00530 <span class="comment"> */</span>
00531 <span class="keywordflow">if</span> (cache->valid &&
00532 (! (cache->flags & NETSNMP_CACHE_DONT_FREE_BEFORE_LOAD)))
00533 _cache_free(cache);
00534
00535 <span class="keywordflow">if</span> ( cache->load_cache)
00536 ret = cache->load_cache(cache, cache->magic);
00537 <span class="keywordflow">if</span> (ret < 0) {
00538 DEBUGMSG((<span class="stringliteral">"helper:cache_handler"</span>, <span class=
"stringliteral">" load failed (%d)\n"</span>,
00539 ret));
00540 cache->valid = 0;
00541 <span class="keywordflow">return</span> ret;
00542 }
00543 cache->valid = 1;
00544 cache->expired = 0;
00545
00546 <span class="comment">/*</span>
00547 <span class="comment"> * If we didn't previously have any valid caches outstanding,</span>
00548 <span class="comment"> * then schedule a pass of the auto-release routine.</span>
00549 <span class="comment"> */</span>
00550 <span class="keywordflow">if</span> ((!cache_outstanding_valid) &&
00551 (! (cache->flags & NETSNMP_CACHE_DONT_FREE_EXPIRED))) {
00552 <a class="code" href="group__snmp__alarm.html#ga14">snmp_alarm_register</a>(CACHE_RELEASE_FREQUENCY,
00553 0, release_cached_resources, NULL);
00554 cache_outstanding_valid = 1;
00555 }
00556 <span class="keywordflow">if</span> (cache->timestamp)
00557 <a class="code" href="group__util.html#ga16">atime_setMarker</a>(cache->timestamp);
00558 <span class="keywordflow">else</span>
00559 cache->timestamp = <a class="code" href="group__util.html#ga15">atime_newMarker</a>();
00560 DEBUGMSG((<span class="stringliteral">"helper:cache_handler"</span>, <span class=
"stringliteral">" loaded (%d)\n"</span>,
00561 cache->timeout));
00562
00563 <span class="keywordflow">return</span> ret;
00564 }
00565
00566
00567
00575 <span class="keywordtype">void</span>
<a name="l00576" id="l00576"></a><a class="code" href="group__cache__handler.html#ga21">00576</a> <a class="code" href=
"group__cache__handler.html#ga21">release_cached_resources</a>(<span class="keywordtype">unsigned</span> <span class=
"keywordtype">int</span> regNo, <span class="keywordtype">void</span> *clientargs)
00577 {
00578 netsnmp_cache *cache = NULL;
00579
00580 cache_outstanding_valid = 0;
00581 DEBUGMSGTL((<span class="stringliteral">"helper:cache_handler"</span>, <span class=
"stringliteral">"running auto-release\n"</span>));
00582 <span class="keywordflow">for</span> (cache = cache_head; cache; cache = cache->next) {
00583 DEBUGMSGTL((<span class="stringliteral">"helper:cache_handler"</span>,<span class=
"stringliteral">" checking %p (flags 0x%x)\n"</span>,
00584 cache, cache->flags));
00585 <span class="keywordflow">if</span> (cache->valid &&
00586 ! (cache->flags & NETSNMP_CACHE_DONT_AUTO_RELEASE)) {
00587 DEBUGMSGTL((<span class="stringliteral">"helper:cache_handler"</span>,<span class=
"stringliteral">" releasing %p\n"</span>, cache));
00588 <span class="comment">/*</span>
00589 <span class="comment"> * Check to see if this cache has timed out.</span>
00590 <span class="comment"> * If so, release the cached resources.</span>
00591 <span class="comment"> * Otherwise, note that we still have at</span>
00592 <span class="comment"> * least one active cache.</span>
00593 <span class="comment"> */</span>
00594 <span class="keywordflow">if</span> (<a class="code" href=
"group__cache__handler.html#ga14">netsnmp_cache_check_expired</a>(cache)) {
00595 <span class="keywordflow">if</span>(! (cache->flags & NETSNMP_CACHE_DONT_FREE_EXPIRED))
00596 _cache_free(cache);
00597 } <span class="keywordflow">else</span> {
00598 cache_outstanding_valid = 1;
00599 }
00600 }
00601 }
00602 <span class="comment">/*</span>
00603 <span class="comment"> * If there are any caches still valid & active,</span>
00604 <span class="comment"> * then schedule another pass.</span>
00605 <span class="comment"> */</span>
00606 <span class="keywordflow">if</span> (cache_outstanding_valid) {
00607 <a class="code" href="group__snmp__alarm.html#ga14">snmp_alarm_register</a>(CACHE_RELEASE_FREQUENCY,
00608 0, <a class="code" href="group__cache__handler.html#ga21">release_cached_resources</a>, NULL);
00609 }
00610 }
</pre>
</div>
<hr size="1" />
<address style="align: right;">
<small>Generated on Fri Dec 30 13:47:44 2005 for net-snmp by <a href="http://www.doxygen.org/index.html"><img src=
"doxygen.png" alt="doxygen" align="middle" border="0" /></a> 1.3.9.1</small>
</address>
<!-- CONTENT END -->
<!--#include virtual="/page-bottom.html" -->
See more files for this project here