免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2723 | 回复: 8

[C] 求助 net-snmp 自定义mib 表格式更新问题 [复制链接]

论坛徽章:
0
发表于 2015-07-14 15:23 |显示全部楼层
背景:基于net-snmp开源框架,自己定义私有MIB,这个MIB格式是table的方式,通过mib2c生成相应的源文件,在源文件的基础上修改。
问题:定义的私有MIB中,比如系统运行状态信息,如相关进程信息,这些是动态的,实时的,我的代码中只是在初始化话的时候,获取一次进程信息。不知道怎么去更新它,value的方式比较简单,但表格式就不知道怎么弄了,对net snmp的源码不熟。希望哪位大神在这方面有经验的,指导下,困恼了好多天了。

以下是部分关键代码:

//这一部分是初始化话我定义的MIB文件中的各个表,一进程table为例
  1. void
  2. init_dpiProject(void)
  3. {
  4.   /* here we initialize all the tables we're planning on supporting */
  5.     initialize_table_DevBasicInfoTable();
  6.     initialize_table_DevHardwareTable();
  7.     initialize_table_DevSoftwareTable();
  8.     initialize_table_DevProcessTable();
  9.     initialize_table_DevCpuTable();
  10.     initialize_table_DevinterAccessTable();
  11.     initialize_table_DevStatisticTable();
  12. }
复制代码
//这个代码我从系统中取出进程信息,插入到DevProcessTable_head链表中
  1. /** Initialize the DevProcessTable table by defining its contents and how it's structured */
  2. void
  3. initialize_table_DevProcessTable(void)
  4. {
  5.     const oid DevProcessTable_oid[] = {1,3,6,1,4,1,ENTERPRISE_ID,0,1,0,4};
  6.     const size_t DevProcessTable_oid_len   = OID_LENGTH(DevProcessTable_oid);
  7.     netsnmp_handler_registration    *reg;
  8.     netsnmp_iterator_info           *iinfo;
  9.     netsnmp_table_registration_info *table_info;

  10.     DEBUGMSGTL(("dpiProject:init", "initializing table DevProcessTable\n"));

  11.     reg = netsnmp_create_handler_registration(
  12.               "DevProcessTable",     DevProcessTable_handler,
  13.               DevProcessTable_oid, DevProcessTable_oid_len,
  14.               HANDLER_CAN_RONLY
  15.               );

  16.     table_info = SNMP_MALLOC_TYPEDEF( netsnmp_table_registration_info );
  17.     netsnmp_table_helper_add_indexes(table_info,
  18.                            ASN_INTEGER,  /* index: processIdx */
  19.                            0);
  20.                 //1.mod by zhouziheng                           
  21.     table_info->min_column = COLUMN_MIN;
  22.     table_info->max_column = COLUMN_MAX;
  23.    
  24.     //2.mod by zhouziheng
  25.     //获取运行时信息,DevProcess
  26.     get_runtime_devInfo(&dev_runtimeInfo);

  27.     struct DevProcessTable_entry *p_devProcessTable_entry;
  28.     int index;
  29.     for (index = 1; index < dev_runtimeInfo.processNum + 1; ++index)
  30.     {
  31.         p_devProcessTable_entry = DevProcessTable_createEntry(index, &dev_runtimeInfo);
  32.     }
  33.    
  34.     DevProcessTable_head = p_devProcessTable_entry;
  35.     //end by zhouziheng
  36.    
  37.     iinfo = SNMP_MALLOC_TYPEDEF( netsnmp_iterator_info );
  38.     iinfo->get_first_data_point = DevProcessTable_get_first_data_point;
  39.     iinfo->get_next_data_point  = DevProcessTable_get_next_data_point;
  40.     iinfo->table_reginfo        = table_info;
  41.    
  42.     netsnmp_register_table_iterator( reg, iinfo );
  43.     netsnmp_inject_handler_before( reg,
  44.         netsnmp_get_cache_handler(DEVPROCESSTABLE_TIMEOUT,
  45.                                   DevProcessTable_load, DevProcessTable_free,
  46.                                   DevProcessTable_oid, DevProcessTable_oid_len),
  47.             TABLE_ITERATOR_NAME);

  48.     /* Initialise the contents of the table here */
  49. }
复制代码
//当snmp请求过来时,会进入这个函数
  1. //add by zhouziheng
  2. static int flag = 1 ;
  3. /** handles requests for the DevProcessTable table */
  4. int
  5. DevProcessTable_handler(
  6.     netsnmp_mib_handler               *handler,
  7.     netsnmp_handler_registration      *reginfo,
  8.     netsnmp_agent_request_info        *reqinfo,
  9.     netsnmp_request_info              *requests)
  10. {

  11.     netsnmp_request_info       *request;
  12.     netsnmp_table_request_info *table_info;
  13.     struct DevProcessTable_entry          *table_entry;

  14.     DEBUGMSGTL(("dpiProject:handler", "Processing request (%d)\n", reqinfo->mode));

  15.     //mod by zhouziheng
  16.     if ( 1 == flag )
  17.     {
  18.         DevProcessTable_free_head();
  19.         DevProcessTable_load_head();
  20.         flag = 0;
  21.     }

  22.     table_entry = DevProcessTable_head;

  23.     switch (reqinfo->mode)
  24.     {
  25.         /*
  26.          * Read-support (also covers GetNext requests)
  27.          */
  28.         case MODE_GET:
  29.         for (request=requests; request; request=request->next)
  30.             {
  31. #if 0            
  32.             table_entry = (struct DevProcessTable_entry *)
  33.                               netsnmp_extract_iterator_context(request);
  34. #endif
  35.             table_info  =     netsnmp_extract_table_info(      request);
  36.    
  37.             switch (table_info->colnum) {
  38.             case COLUMN_PROCESSIDX:
  39.                 if ( !table_entry ) {
  40.                     netsnmp_set_request_error(reqinfo, request,
  41.                                               SNMP_NOSUCHINSTANCE);
  42.                     continue;
  43.                 }
  44.                 snmp_set_var_typed_integer( request->requestvb, ASN_INTEGER,
  45.                                             table_entry->processIdx);
  46.                 break;
  47.             case COLUMN_PROCESS:
  48.                 if ( !table_entry ) {
  49.                     netsnmp_set_request_error(reqinfo, request,
  50.                                               SNMP_NOSUCHINSTANCE);
  51.                     continue;
  52.                 }
  53.                 snmp_set_var_typed_value( request->requestvb, ASN_OCTET_STR,
  54.                                           table_entry->process,
  55.                                           table_entry->process_len);
  56.                 break;
  57.             default:
  58.                 netsnmp_set_request_error(reqinfo, request,
  59.                                           SNMP_NOSUCHOBJECT);
  60.                 break;
  61.             }
  62.         }
  63.         break;

  64.     }
  65. #if 0   
  66.     if (NULL != DevProcessTable_head)
  67.     {
  68.         DevProcessTable_head = DevProcessTable_head->next;
  69.     }
  70.     else
  71.     {
  72.         flag = 1;
  73.     }
  74. #endif   
  75.     return SNMP_ERR_NOERROR;
  76. }
复制代码
现在问题就是只能读取内存中第一次存的信息,如果我再启动其他进程,它查不到啊 。。。怎么解决,急急急!!

论坛徽章:
0
发表于 2015-07-14 18:58 |显示全部楼层
帮帮忙啊,各位

论坛徽章:
14
水瓶座
日期:2014-06-10 09:51:0215-16赛季CBA联赛之江苏
日期:2017-11-27 11:42:3515-16赛季CBA联赛之八一
日期:2017-04-12 14:26:2815-16赛季CBA联赛之吉林
日期:2016-08-20 10:43:1215-16赛季CBA联赛之广夏
日期:2016-06-23 09:53:58程序设计版块每日发帖之星
日期:2016-02-11 06:20:00程序设计版块每日发帖之星
日期:2016-02-09 06:20:0015-16赛季CBA联赛之上海
日期:2015-12-25 16:40:3515-16赛季CBA联赛之广夏
日期:2015-12-22 09:39:36程序设计版块每日发帖之星
日期:2015-08-24 06:20:002015亚冠之德黑兰石油
日期:2015-08-07 09:57:302015年辞旧岁徽章
日期:2015-03-03 16:54:15
发表于 2015-07-15 17:30 |显示全部楼层

    //mod by zhouziheng
    if ( 1 == flag )
    {
        DevProcessTable_free_head();
        DevProcessTable_load_head();
        flag = 0;
    }

    table_entry = DevProcessTable_head;

option 1、启动一个timer刷新这个list,这个和snmp的逻辑没有关系
option 2、每次进入这个callback的时候,刷新list

论坛徽章:
0
发表于 2015-07-16 08:34 |显示全部楼层
多谢,你以前这样搞过吗?回复 3# lxyscls


   

论坛徽章:
0
发表于 2015-07-16 09:47 |显示全部楼层
在回调函数前一步要修改源码,这个实时性要高一些,但是我不知道怎么改。定时器应该可以,我试试。回复 3# lxyscls


   

论坛徽章:
14
水瓶座
日期:2014-06-10 09:51:0215-16赛季CBA联赛之江苏
日期:2017-11-27 11:42:3515-16赛季CBA联赛之八一
日期:2017-04-12 14:26:2815-16赛季CBA联赛之吉林
日期:2016-08-20 10:43:1215-16赛季CBA联赛之广夏
日期:2016-06-23 09:53:58程序设计版块每日发帖之星
日期:2016-02-11 06:20:00程序设计版块每日发帖之星
日期:2016-02-09 06:20:0015-16赛季CBA联赛之上海
日期:2015-12-25 16:40:3515-16赛季CBA联赛之广夏
日期:2015-12-22 09:39:36程序设计版块每日发帖之星
日期:2015-08-24 06:20:002015亚冠之德黑兰石油
日期:2015-08-07 09:57:302015年辞旧岁徽章
日期:2015-03-03 16:54:15
发表于 2015-07-16 10:03 |显示全部楼层
回复 5# hubimaso

option 3. 设置一个timestamp,就不需要用timer了

    iinfo->get_first_data_point = DevProcessTable_get_first_data_point;
    iinfo->get_next_data_point  = DevProcessTable_get_next_data_point;

这是两个核心函数,数据结构不一定要组织成链表(mib2c默认生成得格式),只要能够保证顺序(index升序)得给出下一个就可以了

链表的优点是取数据简单(O(1)),但是刷新起来比较耗时(O(n*n))

如果是树的话,取后继大概是O(lgn),刷新的话应该是(O(n*lgn))

数据量灰常大的情况,可以考虑换个数据结构,一两百就算了,没所谓

   

论坛徽章:
0
发表于 2015-07-16 13:47 |显示全部楼层
在那设置时间措啊?大神能具体简单实例么?
回复 6# lxyscls


   

论坛徽章:
14
水瓶座
日期:2014-06-10 09:51:0215-16赛季CBA联赛之江苏
日期:2017-11-27 11:42:3515-16赛季CBA联赛之八一
日期:2017-04-12 14:26:2815-16赛季CBA联赛之吉林
日期:2016-08-20 10:43:1215-16赛季CBA联赛之广夏
日期:2016-06-23 09:53:58程序设计版块每日发帖之星
日期:2016-02-11 06:20:00程序设计版块每日发帖之星
日期:2016-02-09 06:20:0015-16赛季CBA联赛之上海
日期:2015-12-25 16:40:3515-16赛季CBA联赛之广夏
日期:2015-12-22 09:39:36程序设计版块每日发帖之星
日期:2015-08-24 06:20:002015亚冠之德黑兰石油
日期:2015-08-07 09:57:302015年辞旧岁徽章
日期:2015-03-03 16:54:15
发表于 2015-07-16 14:59 |显示全部楼层
回复 7# hubimaso


    在建立链表数据结构的时候就设置一个时间戳,后面读数据的时候,先检查时间戳,查看是否超时,超时就先刷新链表

get_first_xxx里面就做检查

论坛徽章:
0
发表于 2015-07-24 09:29 |显示全部楼层
最后用了比较挫的方法解决了,感觉还是不爽,我看了下源码中的if-table.c 他是用mib2c.mfd.conf回复 8# lxyscls


   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP