mfd-access-container-cached-defines.m2i
上传用户:wxp200602
上传日期:2007-10-30
资源大小:4028k
文件大小:15k
源码类别:

SNMP编程

开发平台:

Unix_Linux

  1. ############################################################  -*- c -*-
  2. ###generic include for XXX. Do not use directly.
  3. ###
  4. ### $Id: mfd-access-container-cached-defines.m2i,v 1.16.2.1 2005/01/06 14:51:52 rstory Exp $
  5. ########################################################################
  6. @if $m2c_mark_boundary == 1@
  7. /** START code generated by $RCSfile: mfd-access-container-cached-defines.m2i,v $ $Revision: 1.16.2.1 $ */
  8. @end@
  9. ##//####################################################################
  10. ##//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  11. ##//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  12. @if $m2c_processing_type eq 'h'@
  13. /*
  14.  * TODO:180:o: Review $context cache timeout.
  15.  * The number of seconds before the cache times out
  16.  */
  17. #define $context.uc_CACHE_TIMEOUT   60
  18. void ${context}_container_init(netsnmp_container **container_ptr_ptr,
  19.                              netsnmp_cache *cache);
  20. int ${context}_cache_load(netsnmp_container *container);
  21. void ${context}_cache_free(netsnmp_container *container);
  22. @   if $m2c_include_examples == 1@
  23. $example_start
  24. /* *********************************************************************
  25.  * Since we have no idea how you really access your data, we'll go with
  26.  * a worst case example: a flat text file.
  27.  @   if $m2c_data_transient != 2@
  28.  @      print Example code is for fully transient data. Either turn off@
  29.  @      print m2c_include_examples or set m2c_data_transient to 2.@
  30.  @      exit@
  31.  @   end@
  32.  */
  33. #define MAX_LINE_SIZE 256
  34. $example_end
  35. @   end@ // example
  36. @end@ // m2c_processing_type eq 'h'
  37. ##//####################################################################
  38. ##//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  39. ##//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  40. @if $m2c_processing_type eq 'c'@
  41. /**
  42.  * container-cached overview
  43.  *
  44.  */
  45. /***********************************************************************
  46.  *
  47.  * cache
  48.  *
  49.  ***********************************************************************/
  50. /**
  51.  * container initialization
  52.  *
  53.  * @param container_ptr_ptr A pointer to a container pointer. If you
  54.  *        create a custom container, use this parameter to return it
  55.  *        to the MFD helper. If set to NULL, the MFD helper will
  56.  *        allocate a container for you.
  57.  * @param  cache A pointer to a cache structure. You can set the timeout
  58.  *         and other cache flags using this pointer.
  59.  *
  60.  *  This function is called at startup to allow you to customize certain
  61.  *  aspects of the access method. For the most part, it is for advanced
  62.  *  users. The default code should suffice for most cases. If no custom
  63.  *  container is allocated, the MFD code will create one for your.
  64.  *
  65.  *  This is also the place to set up cache behavior. The default, to
  66.  *  simply set the cache timeout, will work well with the default
  67.  *  container. If you are using a custom container, you may want to
  68.  *  look at the cache helper documentation to see if there are any
  69.  *  flags you want to set.
  70.  *
  71.  * @remark
  72.  *  This would also be a good place to do any initialization needed
  73.  *  for you data source. For example, opening a connection to another
  74.  *  process that will supply the data, opening a database, etc.
  75.  */
  76. void
  77. ${context}_container_init(netsnmp_container **container_ptr_ptr,
  78.                         netsnmp_cache *cache)
  79. {
  80.     DEBUGMSGTL(("verbose:${context}:${context}_container_init","calledn"));
  81.     
  82.     if((NULL == cache) || (NULL == container_ptr_ptr)) {
  83.         snmp_log(LOG_ERR,"bad params to ${context}_container_initn");
  84.         return;
  85.     }
  86.     /*
  87.      * For advanced users, you can use a custom container. If you
  88.      * do not create one, one will be created for you.
  89.      */
  90.     *container_ptr_ptr = NULL;
  91.     /*
  92.      * TODO:345:A: Set up $context cache properties.
  93.      *
  94.      * Also for advanced users, you can set parameters for the
  95.      * cache. Do not change the magic pointer, as it is used
  96.      * by the MFD helper. To completely disable caching, set
  97.      * cache->enabled to 0.
  98.      */
  99.     cache->timeout = $context.uc_CACHE_TIMEOUT; /* seconds */
  100. } /* ${context}_container_init */
  101. /**
  102.  * load cache data
  103.  *
  104.  * TODO:350:M: Implement $context cache load
  105.  *
  106.  * @param container container to which items should be inserted
  107.  *
  108.  * @retval MFD_SUCCESS              : success.
  109.  * @retval MFD_RESOURCE_UNAVAILABLE : Can't access data source
  110.  * @retval MFD_ERROR                : other error.
  111.  *
  112.  *  This function is called to cache the index(es) (and data, optionally)
  113.  *  for the every row in the data set.
  114.  *
  115.  * @remark
  116.  *  While loading the cache, the only important thing is the indexes.
  117.  *  If access to your data is cheap/fast (e.g. you have a pointer to a
  118.  *  structure in memory), it would make sense to update the data here.
  119.  *  If, however, the accessing the data invovles more work (e.g. parsing
  120.  *  some other existing data, or peforming calculations to derive the data),
  121.  *  then you can limit yourself to setting the indexes and saving any
  122.  *  information you will need later. Then use the saved information in
  123.  *  ${context}_row_prep() for populating data.
  124.  *
  125.  * @note
  126.  *  If you need consistency between rows (like you want statistics
  127.  *  for each row to be from the same time frame), you should set all
  128.  *  data here.
  129.  *
  130.  */
  131. int
  132. ${context}_cache_load(netsnmp_container *container)
  133. {
  134.     ${context}_rowreq_ctx *rowreq_ctx;
  135.     size_t                 count = 0;
  136. @if $m2c_include_examples == 1@
  137.     
  138.     /*
  139.      * this example code is based on a data source that is a
  140.      * text file to be read and parsed.
  141.      */
  142.     FILE *filep;
  143.     char line[MAX_LINE_SIZE];
  144.     /*
  145.      * temporary storage for index values
  146.      */
  147. @  foreach $node index@
  148. @    include m2c_setup_node.m2i@
  149.         /*
  150.          * $m2c_node_summary
  151.          */
  152. @    if $m2c_node_needlength == 1@
  153. @        eval $m2c_gi_maxlen = (126 - $node.oidlength - $m2c_gi_others)@
  154. @        if $m2c_node_maxlen > $m2c_gi_maxlen@
  155. @            eval $m2c_node_maxlen = $m2c_gi_maxlen@
  156.         /** 128 - 1(entry) - 1(col) - $m2c_gi_others(other indexes) = $m2c_node_maxlen */
  157. @        end@
  158. @    end@ # needlength
  159. @    include node-storage.m2i@
  160. @  end@ // foreach
  161. @end@ // examples
  162.     DEBUGMSGTL(("verbose:${context}:${context}_cache_load","calledn"));
  163. @if $m2c_include_examples == 1@
  164. $example_start
  165.     /*
  166.      * open our data file.
  167.      */
  168.     filep = fopen("/etc/dummy.conf", "r");
  169.     if(NULL ==  filep) {
  170.         return MFD_RESOURCE_UNAVAILABLE;
  171.     }
  172. $example_end
  173. @end@ // example
  174.     /*
  175.      * TODO:351:M: |-> Load/update data in the $context container.
  176.      * loop over your $context data, allocate a rowreq context,
  177.      * set the index(es) [and data, optionally] and insert into
  178.      * the container.
  179.      */
  180.     while( 1 ) {
  181. @   if $m2c_include_examples == 0@
  182.         /*
  183.          * check for end of data; bail out if there is no more data
  184.          */
  185.         if( 1 )
  186.             break;
  187. @   else@
  188. $example_start
  189.     /*
  190.      * get a line (skip blank lines)
  191.      */
  192.     do {
  193.         if (!fgets(line, sizeof(line), filep)) {
  194.             /* we're done */
  195.             fclose(filep);
  196.             filep = NULL;
  197.         }
  198.     } while (filep && (line[0] == 'n'));
  199.     /*
  200.      * check for end of data
  201.      */
  202.     if(NULL == filep)
  203.         break;
  204.     /*
  205.      * parse line into variables
  206.      */
  207. $example_end
  208. @    end@ # example
  209.         /*
  210.          * TODO:352:M: |   |-> set indexes in new $context rowreq context.
  211. @   eval $m2c_tmp = ""@
  212. @   if ($m2c_data_allocate == 1) || ($m2c_data_init == 1)@
  213. @      eval $m2c_tmp = "NULL"@
  214. @      if ($m2c_data_allocate == 1) && ($m2c_data_init == 1)@
  215. @         eval $m2c_tmp = "$m2c_tmp, NULL"@
  216.          * data context will be set from the first param (unless NULL,
  217.          *      in which case a new data context will be allocated)
  218.          * the second param will be passed, with the row context, to
  219.          *      ${context}rowreq_ctx_init.
  220. @      else@
  221.          * data context will be set from the param (unless NULL,
  222.          *      in which case a new data context will be allocated)
  223. @      @end@
  224. @   end@
  225.          */
  226.         rowreq_ctx = ${context}_allocate_rowreq_ctx($m2c_tmp);
  227.         if (NULL == rowreq_ctx) {
  228.             snmp_log(LOG_ERR, "memory allocation failedn");
  229.             return MFD_RESOURCE_UNAVAILABLE;
  230.         }
  231.         if(MFD_SUCCESS != ${context}_indexes_set(rowreq_ctx
  232. @   foreach $node index@
  233. @      include m2c_setup_node.m2i@
  234. @        if $m2c_node_needlength == 1@
  235.                                , $node, ${node}_len
  236. @        else@
  237.                                , $node
  238. @        end@
  239. @   end@ # foreach index
  240.                )) {
  241.             snmp_log(LOG_ERR,"error setting index while loading "
  242.                      "${context} cache.n");
  243.             ${context}_release_rowreq_ctx(rowreq_ctx);
  244.             continue;
  245.         }
  246.         /*
  247.          * TODO:352:r: |   |-> populate $context data context.
  248.          * Populate data context here. (optionally, delay until row prep)
  249.          */
  250. @if $m2c_data_transient == 0@ # persistent
  251.     /* non-TRANSIENT data: no need to copy. set pointer to data */
  252. @else@
  253.     /*
  254.      * TRANSIENT or semi-TRANSIENT data:
  255.      * copy data or save any info needed to do it in row_prep.
  256.      */
  257. @   foreach $node nonindex@
  258. @      include m2c_setup_node.m2i@
  259.     /*
  260.      * setup/save data for $node
  261.      * $m2c_node_summary
  262.      */
  263. @      if "$m2c_data_context" eq "generated"@
  264. @         eval $m2c_ctx_lh = "$m2c_ctx_rh"@
  265. @         eval $m2c_ctx_lhs = "$m2c_ctx_rhs"@
  266. @         eval $m2c_ctx_rh = "$node"@
  267. @         eval $m2c_ctx_rhs = "${node}_len"@
  268. @         include generic-value-map.m2i@
  269.     
  270. @      end@ # data_context ! generated
  271. @   end@ // for each
  272. @end@ # transient
  273.         
  274.         /*
  275.          * insert into table container
  276.          */
  277.         CONTAINER_INSERT(container, rowreq_ctx);
  278.         ++count;
  279.     }
  280. @if $m2c_include_examples == 1@
  281. $example_start
  282.     if(NULL != filep)
  283.         fclose(filep);
  284. $example_end
  285. @end@ # example
  286.     DEBUGMSGT(("verbose:${context}:${context}_cache_load",
  287.                "inserted %d recordsn", count));
  288.     return MFD_SUCCESS;
  289. } /* ${context}_cache_load */
  290. /**
  291.  * cache clean up
  292.  *
  293.  * @param container container with all current items
  294.  *
  295.  *  This optional callback is called prior to all
  296.  *  item's being removed from the container. If you
  297.  *  need to do any processing before that, do it here.
  298.  *
  299.  * @note
  300.  *  The MFD helper will take care of releasing all the row contexts.
  301. @   if ($m2c_data_allocate == 1) && ($m2c_data_transient == 0)@
  302.  *  If you did not pass a data context pointer when allocating
  303.  *  the rowreq context, the one that was allocated will be deleted.
  304.  *  If you did pass one in, it will not be deleted and that memory
  305.  *  is your responsibility.
  306. @   end@
  307.  *
  308.  */
  309. void
  310. ${context}_cache_free(netsnmp_container *container)
  311. {
  312.     DEBUGMSGTL(("verbose:${context}:${context}_cache_free","calledn"));
  313.     /*
  314.      * TODO:380:M: Free $context cache.
  315.      */
  316. } /* ${context}_cache_free */
  317. @end@ // m2c_processing_type eq 'c'
  318. ########################################################################
  319. ##//####################################################################
  320. ##//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  321. ##//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  322. @if $m2c_processing_type eq 'i'@
  323. /**
  324.  * @internal
  325.  */
  326. static int
  327. _cache_load(netsnmp_cache *cache, void *vmagic)
  328. {
  329.     DEBUGMSGTL(("internal:${context}:_cache_load","calledn"));
  330.     if((NULL == cache) || (NULL == cache->magic)) {
  331.         snmp_log(LOG_ERR, "invalid cache for ${context}_cache_loadn");
  332.         return -1;
  333.     }
  334.     /** should only be called for an invalid or expired cache */
  335.     netsnmp_assert((0 == cache->valid) || (1 == cache->expired));
  336.     
  337.     /*
  338.      * call user code
  339.      */
  340.     return ${context}_cache_load((netsnmp_container*)cache->magic);
  341. } /* _cache_load */
  342. /**
  343.  * @internal
  344.  */
  345. static void
  346. _cache_item_free(${context}_rowreq_ctx *rowreq_ctx, void *context)
  347. {
  348.     DEBUGMSGTL(("internal:${context}:_cache_item_free","calledn"));
  349.     if(NULL == rowreq_ctx)
  350.         return;
  351.     ${context}_release_rowreq_ctx(rowreq_ctx);
  352. } /* _cache_item_free */
  353. /**
  354.  * @internal
  355.  */
  356. static void
  357. _cache_free(netsnmp_cache *cache, void *magic)
  358. {
  359.     netsnmp_container *container;
  360.     DEBUGMSGTL(("internal:${context}:_cache_free","calledn"));
  361.     if((NULL == cache) || (NULL == cache->magic)) {
  362.         snmp_log(LOG_ERR, "invalid cache in ${context}_cache_freen");
  363.         return;
  364.     }
  365.     container = (netsnmp_container*)cache->magic;
  366.     /*
  367.      * call user code
  368.      */
  369.     ${context}_cache_free(container);
  370.     
  371.     /*
  372.      * free all items. inefficient, but easy.
  373.      */
  374.     CONTAINER_CLEAR(container,
  375.                     (netsnmp_container_obj_func *)_cache_item_free,
  376.                     NULL);
  377. } /* _cache_free */
  378. /**
  379.  * @internal
  380.  * initialize the iterator container with functions or wrappers
  381.  */
  382. void
  383. _${context}_container_init(${context}_interface_ctx *if_ctx)
  384. {
  385.     DEBUGMSGTL(("internal:${context}:_${context}_container_init","calledn"));
  386.     
  387. @    if 0@
  388.     /*
  389.      * find cache
  390.      */
  391.     if_ctx->cache =
  392.         netsnmp_cache_find_by_oid(PARTNER_oid, OID_LENGTH(PARTNER_oid));
  393. @    else@
  394.     /*
  395.      * set up the cache
  396.      */
  397.     if_ctx->cache = netsnmp_cache_create(30, /* timeout in seconds */
  398.                                          _cache_load, _cache_free,
  399.                                          ${context}_oid,
  400.                                          ${context}_oid_size);
  401. @    end@ // shared cache
  402.     if(NULL == if_ctx->cache) {
  403.         snmp_log(LOG_ERR, "error creating cache for ${context}n");
  404.         return;
  405.     }
  406.     if_ctx->cache->flags = NETSNMP_CACHE_DONT_INVALIDATE_ON_SET;
  407.     ${context}_container_init(&if_ctx->container, if_ctx->cache);
  408.     if(NULL == if_ctx->container)
  409.         if_ctx->container = netsnmp_container_find("${context}:table_container");
  410.     if(NULL == if_ctx->container) {
  411.         snmp_log(LOG_ERR,"error creating container in "
  412.                  "${context}_container_initn");
  413.         return;
  414.     }
  415.     if_ctx->cache->magic = (void*)if_ctx->container;
  416. } /* _${context}_container_init */
  417. @end@ // m2c_processing_type eq 'i'
  418. ########################################################################
  419. ##//####################################################################
  420. ##//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  421. ##//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  422. @if $m2c_processing_type eq 'r'@
  423. ##
  424.   container-cached summary
  425.   ------------------------
  426.     The container-cached data access code is for cases when you want to
  427.     cache your data in the agent/sub-agent.
  428.     ... to be continued...
  429. ########################################################################
  430.   Updating the Index
  431.   ------------------
  432.     TODO : update index for the raw data
  433.     FUNC : ${context}_indexes_set
  434.     WHERE: ${context}_data_access.c
  435.     This is a convenience function for setting the index context from
  436.     the native C data. Where necessary, value mapping should be done.
  437.     @if $mfd_readme_verbose == 1@
  438.     This function should update the table index values (found in
  439.     tbl_idx) for the given raw data.
  440.     @end@
  441. @end@ // m2c_processing_type eq 'r'
  442. ########################################################################
  443. ##//####################################################################
  444. @if $m2c_mark_boundary == 1@
  445. /** END code generated by $RCSfile: mfd-access-container-cached-defines.m2i,v $ $Revision: 1.16.2.1 $ */
  446. @end@