ifTable_data_access.c
上传用户:wxp200602
上传日期:2007-10-30
资源大小:4028k
文件大小:12k
源码类别:

SNMP编程

开发平台:

Unix_Linux

  1. /*
  2.  * Note: this file originally auto-generated by mib2c using
  3.  *       version : 1.12 $ of : mfd-data-access.m2c,v $ 
  4.  *
  5.  * $Id: ifTable_data_access.c,v 1.13 2004/10/22 18:37:45 rstory Exp $
  6.  */
  7. /*
  8.  * standard Net-SNMP includes 
  9.  */
  10. #include <net-snmp/net-snmp-config.h>
  11. #include <net-snmp/net-snmp-includes.h>
  12. #include <net-snmp/agent/net-snmp-agent-includes.h>
  13. /*
  14.  * include our parent header 
  15.  */
  16. #include "ifTable.h"
  17. #include "ifTable_data_access.h"
  18. /** @defgroup data_access data_access: Routines to access data
  19.  *
  20.  * These routines are used to locate the data used to satisfy
  21.  * requests.
  22.  * 
  23.  * @{
  24.  */
  25. /**********************************************************************
  26.  **********************************************************************
  27.  ***
  28.  *** Table ifTable
  29.  ***
  30.  **********************************************************************
  31.  **********************************************************************/
  32. /*
  33.  * ifTable is subid 2 of interfaces.
  34.  * Its status is Current.
  35.  * OID: .1.3.6.1.2.1.2.2, length: 8
  36.  */
  37. /**
  38.  * initialization for ifTable data access
  39.  *
  40.  * This function is called during startup to allow you to
  41.  * allocate any resources you need for the data table.
  42.  *
  43.  * @param ifTable_reg
  44.  *        Pointer to ifTable_registration
  45.  *
  46.  * @retval MFD_SUCCESS : success.
  47.  * @retval MFD_ERROR   : unrecoverable error.
  48.  */
  49. int
  50. ifTable_init_data(ifTable_registration_ptr ifTable_reg)
  51. {
  52.     DEBUGMSGTL(("verbose:ifTable:ifTable_init_data", "calledn"));
  53.     /*
  54.      * TODO:303:o: Initialize ifTable data.
  55.      */
  56.     return MFD_SUCCESS;
  57. }                               /* ifTable_init_data */
  58. /**
  59.  * container-cached overview
  60.  *
  61.  */
  62. /***********************************************************************
  63.  *
  64.  * cache
  65.  *
  66.  ***********************************************************************/
  67. /**
  68.  * container initialization
  69.  *
  70.  * @param container_ptr_ptr A pointer to a container pointer. If you
  71.  *        create a custom container, use this parameter to return it
  72.  *        to the MFD helper. If set to NULL, the MFD helper will
  73.  *        allocate a container for you.
  74.  * @param  cache A pointer to a cache structure. You can set the timeout
  75.  *         and other cache flags using this pointer.
  76.  *
  77.  *  This function is called at startup to allow you to customize certain
  78.  *  aspects of the access method. For the most part, it is for advanced
  79.  *  users. The default code should suffice for most cases. If no custom
  80.  *  container is allocated, the MFD code will create one for your.
  81.  *
  82.  *  This is also the place to set up cache behavior. The default, to
  83.  *  simply set the cache timeout, will work well with the default
  84.  *  container. If you are using a custom container, you may want to
  85.  *  look at the cache helper documentation to see if there are any
  86.  *  flags you want to set.
  87.  *
  88.  * @remark
  89.  *  This would also be a good place to do any initialization needed
  90.  *  for you data source. For example, opening a connection to another
  91.  *  process that will supply the data, opening a database, etc.
  92.  */
  93. void
  94. ifTable_container_init(netsnmp_container ** container_ptr_ptr,
  95.                        netsnmp_cache * cache)
  96. {
  97.     DEBUGMSGTL(("verbose:ifTable:ifTable_container_init", "calledn"));
  98.     if ((NULL == cache) || (NULL == container_ptr_ptr)) {
  99.         snmp_log(LOG_ERR, "bad params to ifTable_container_initn");
  100.         return;
  101.     }
  102.     /*
  103.      * For advanced users, you can use a custom container. If you
  104.      * do not create one, one will be created for you.
  105.      */
  106.     *container_ptr_ptr = NULL;
  107.     /*
  108.      * TODO:345:A: Set up ifTable cache properties.
  109.      *
  110.      * Also for advanced users, you can set parameters for the
  111.      * cache. Do not change the magic pointer, as it is used
  112.      * by the MFD helper.
  113.      */
  114.     cache->timeout = IFTABLE_CACHE_TIMEOUT;     /* seconds */
  115.     /*
  116.      * don't release resources
  117.      */
  118.     cache->flags |=
  119.         (NETSNMP_CACHE_DONT_AUTO_RELEASE | NETSNMP_CACHE_DONT_FREE_EXPIRED
  120.          | NETSNMP_CACHE_DONT_FREE_BEFORE_LOAD | NETSNMP_CACHE_PRELOAD |
  121.          NETSNMP_CACHE_AUTO_RELOAD | NETSNMP_CACHE_DONT_INVALIDATE_ON_SET);
  122. }                               /* ifTable_container_init */
  123. /**
  124.  * check entry for update
  125.  *
  126.  */
  127. static void
  128. _check_interface_entry_for_updates(ifTable_rowreq_ctx * rowreq_ctx,
  129.                                    netsnmp_container * ifcontainer)
  130. {
  131.     char            oper_changed = 0;
  132.     /*
  133.      * check for matching entry. We can do this directly, since
  134.      * both containers use the same index.
  135.      */
  136.     netsnmp_interface_entry *ifentry =
  137.         CONTAINER_FIND(ifcontainer, rowreq_ctx);
  138.     if (NULL == ifentry) {
  139.         /*
  140.          * if this is the first time we detected that this interface is
  141.          * missing, set admin/oper status down, and set last change.
  142.          */
  143.         if (!rowreq_ctx->known_missing) {
  144.             DEBUGMSGTL(("ifTable:access", "updating missing entryn"));
  145.             rowreq_ctx->known_missing = 1;
  146.             rowreq_ctx->data.ifAdminStatus = IFADMINSTATUS_DOWN;
  147.             if (rowreq_ctx->data.ifOperStatus != IFOPERSTATUS_DOWN)
  148.                 oper_changed = 1;
  149.             rowreq_ctx->data.ifOperStatus = IFOPERSTATUS_DOWN;
  150.         }
  151.     } else {
  152.         DEBUGMSGTL(("ifTable:access", "updating existing entryn"));
  153. #ifdef USING_IF_MIB_IFXTABLE_IFXTABLE_MODULE
  154.         netsnmp_assert(strcmp(rowreq_ctx->data.ifName,
  155.                               ifentry->name) == 0);
  156. #endif
  157.         /*
  158.          * if the interface was missing, but came back, clear the
  159.          * missing flag and set the discontinuity time. (if an os keeps
  160.          * persistent counters, tough cookies. We'll cross that 
  161.          * bridge if we come to it).
  162.          */
  163.         if (rowreq_ctx->known_missing) {
  164.             rowreq_ctx->known_missing = 0;
  165. #ifdef USING_IF_MIB_IFXTABLE_IFXTABLE_MODULE
  166.             rowreq_ctx->data.ifCounterDiscontinuityTime =
  167.                 netsnmp_get_agent_uptime();
  168. #endif
  169.         }
  170.         /*
  171.          * Check for changes, then update
  172.          */
  173.         if ((!(ifentry->ns_flags & NETSNMP_INTERFACE_FLAGS_HAS_LASTCHANGE))
  174.             && (rowreq_ctx->data.ifOperStatus != ifentry->oper_status))
  175.             oper_changed = 1;
  176.         netsnmp_access_interface_entry_copy(rowreq_ctx->data.ifentry,
  177.                                             ifentry);
  178.         /*
  179.          * remove entry from ifcontainer
  180.          */
  181.         CONTAINER_REMOVE(ifcontainer, ifentry);
  182.         netsnmp_access_interface_entry_free(ifentry);
  183.     }
  184.     /*
  185.      * if ifOperStatus changed, update ifLastChange
  186.      */
  187.     if (oper_changed)
  188.         rowreq_ctx->data.ifLastChange = netsnmp_get_agent_uptime();
  189. }
  190. /**
  191.  * add new entry
  192.  */
  193. static void
  194. _add_new_interface(netsnmp_interface_entry * ifentry,
  195.                    netsnmp_container * container)
  196. {
  197.     ifTable_rowreq_ctx *rowreq_ctx;
  198.     DEBUGMSGTL(("ifTable:access", "creating new entryn"));
  199.     /*
  200.      * allocate an row context and set the index(es), then add it to
  201.      * the container
  202.      */
  203.     rowreq_ctx = ifTable_allocate_rowreq_ctx(ifentry);
  204.     if ((NULL != rowreq_ctx) &&
  205.         (MFD_SUCCESS == ifTable_indexes_set(rowreq_ctx, ifentry->index))) {
  206.         CONTAINER_INSERT(container, rowreq_ctx);
  207.     } else {
  208.         if (rowreq_ctx) {
  209.             snmp_log(LOG_ERR, "error setting index while loading "
  210.                      "ifTable cache.n");
  211.             ifTable_release_rowreq_ctx(rowreq_ctx);
  212.         } else {
  213.             snmp_log(LOG_ERR, "memory allocation failed while loading "
  214.                      "ifTable cache.n");
  215.             netsnmp_access_interface_entry_free(ifentry);
  216.         }
  217.     }
  218. }
  219. /**
  220.  * load cache data
  221.  *
  222.  * TODO:350:M: Implement ifTable cache load
  223.  *
  224.  * @param container container to which items should be inserted
  225.  *
  226.  * @retval MFD_SUCCESS              : success.
  227.  * @retval MFD_RESOURCE_UNAVAILABLE : Can't access data source
  228.  * @retval MFD_ERROR                : other error.
  229.  *
  230.  *  This function is called to cache the index(es) (and data, optionally)
  231.  *  for the every row in the data set.
  232.  *
  233.  * @remark
  234.  *  While loading the cache, the only important thing is the indexes.
  235.  *  If access to your data is cheap/fast (e.g. you have a pointer to a
  236.  *  structure in memory), it would make sense to update the data here.
  237.  *  If, however, the accessing the data invovles more work (e.g. parsing
  238.  *  some other existing data, or peforming calculations to derive the data),
  239.  *  then you can limit yourself to setting the indexes and saving any
  240.  *  information you will need later. Then use the saved information in
  241.  *  ifTable_row_prep() for populating data.
  242.  *
  243.  * @note
  244.  *  If you need consistency between rows (like you want statistics
  245.  *  for each row to be from the same time frame), you should set all
  246.  *  data here.
  247.  *
  248.  */
  249. int
  250. ifTable_cache_load(netsnmp_container * container)
  251. {
  252.     netsnmp_container *ifcontainer;
  253.     DEBUGMSGTL(("verbose:ifTable:ifTable_cache_load", "calledn"));
  254.     /*
  255.      * TODO:351:M: |-> Load/update data in the ifTable container.
  256.      * loop over your ifTable data, allocate a rowreq context,
  257.      * set the index(es) [and data, optionally] and insert into
  258.      * the container.
  259.      */
  260.     /*
  261.      * ifTable gets its data from the netsnmp_interface API.
  262.      */
  263.     ifcontainer =
  264.         netsnmp_access_interface_container_load(NULL,
  265.                                                 NETSNMP_ACCESS_INTERFACE_INIT_NOFLAGS);
  266.     if (NULL == ifcontainer)
  267.         return MFD_RESOURCE_UNAVAILABLE;        /* msg already logged */
  268.     /*
  269.      * we just got a fresh copy of interface data. compare it to
  270.      * what we've already got, and make any adjustements...
  271.      */
  272.     CONTAINER_FOR_EACH(container, (netsnmp_container_obj_func *)
  273.                        _check_interface_entry_for_updates, ifcontainer);
  274.     /*
  275.      * now add any new interfaces
  276.      */
  277.     CONTAINER_FOR_EACH(ifcontainer,
  278.                        (netsnmp_container_obj_func *) _add_new_interface,
  279.                        container);
  280.     /*
  281.      * free the container. we've either claimed each ifentry, or released it,
  282.      * so the dal function doesn't need to clear the container.
  283.      */
  284.     netsnmp_access_interface_container_free(ifcontainer,
  285.                                             NETSNMP_ACCESS_INTERFACE_FREE_DONT_CLEAR);
  286.     DEBUGMSGT(("verbose:ifTable:ifTable_cache_load",
  287.                "%d recordsn", CONTAINER_SIZE(container)));
  288.     return MFD_SUCCESS;
  289. }                               /* ifTable_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.  *
  302.  */
  303. void
  304. ifTable_cache_free(netsnmp_container * container)
  305. {
  306.     DEBUGMSGTL(("verbose:ifTable:ifTable_cache_free", "calledn"));
  307.     /*
  308.      * TODO:380:M: Free ifTable cache.
  309.      */
  310. }                               /* ifTable_cache_free */
  311. /**
  312.  * prepare row for processing.
  313.  *
  314.  *  When the agent has located the row for a request, this function is
  315.  *  called to prepare the row for processing. If you fully populated
  316.  *  the data context during the index setup phase, you may not need to
  317.  *  do anything.
  318.  *
  319.  * @param rowreq_ctx pointer to a context.
  320.  *
  321.  * @retval MFD_SUCCESS     : success.
  322.  * @retval MFD_ERROR       : other error.
  323.  */
  324. int
  325. ifTable_row_prep(ifTable_rowreq_ctx * rowreq_ctx)
  326. {
  327.     DEBUGMSGTL(("verbose:ifTable:ifTable_row_prep", "calledn"));
  328.     netsnmp_assert(NULL != rowreq_ctx);
  329.     /*
  330.      * TODO:390:o: Prepare row for request.
  331.      * If populating row data was delayed, this is the place to
  332.      * fill in the row for this request.
  333.      */
  334.     return MFD_SUCCESS;
  335. }                               /* ifTable_row_prep */
  336. /** @} */