Table iterator problem

"suresh khemka" <[email protected]>
Newsgroups gmane.network.net-snmp.user
Message-ID <[email protected]>
Hi All,

i am facing an issue regarding implementation of tables using
mib2c.iterate.conf. i have created code using this config file. I have added
my function to get data from kernel into a link list. I need to set up the
my_loop_context and my_data_context to handle rows. The rows corresponds to
number of processor on the machine and returns time ticks value for
kernel,user,idle mode etc.

I don't know if i am doing it correct. I have seen nscaching.c
,nslogging.cand other files and also searched a lot in the mailing
list but I am not
able to make out how it works.Please let me know if I am doing it correctly
or there is some problem with my code.

The subagent is getting compiled but it is not returning anything. The
problem is that table_info structure is returning NULL. I think I am not
setting the contexts correctly. or should i initialise the table context
else where?
Please Help me.
My code is as follows.

/*
 * Note: this file originally auto-generated by mib2c using
 *  : mib2c.iterate.conf,v 5.14 2004/10/14 12:57:33 dts12 Exp $
 */

#include <net-snmp/net- snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include "cpuTable.h"
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/param.h>
#include <sys/pstat.h>
/** Initializes the cpuTable module */
void
init_cpuTable(void)
{
    /*
     * here we initialize all the tables we're planning on supporting
     */
    initialize_table_cpuTable();
}

/** Initialize the cpuTable table by defining its contents and how it's
structured */
void
initialize_table_cpuTable(void)
{
    static oid      cpuTable_oid[] =
        { 1, 3, 6, 1, 4, 1, 15797, 999, 2, 1 };
    size_t          cpuTable_oid_len = OID_LENGTH(cpuTable_oid);
    netsnmp_handler_registration *reg;
    netsnmp_iterator_info *iinfo;
    netsnmp_table_registration_info *table_info;

    reg = netsnmp_create_handler_registration("cpuTable", cpuTable_handler,
                                              cpuTable_oid,
                                              cpuTable_oid_len,
                                              HANDLER_CAN_RONLY);

    table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
    if (!table_info)
      printf(" le lo kuch nahi hua\n");
    netsnmp_table_helper_add_indexes(table_info, ASN_INTEGER,   /* index:
cpuIndex */
                                     0);
    table_info->min_column = 1;
    table_info->min_column = 5;

    iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info);
    iinfo->get_first_data_point = cpuTable_get_first_data_point;
    iinfo->get_next_data_point = cpuTable_get_next_data_point;
    iinfo->table_reginfo = table_info;

    netsnmp_register_table_iterator(reg, iinfo);
    printf(" i have done all this register stuff\n");

    /*
     * Initialise the contents of the table here
     */
     inittable();
}

  void inittable(){
   struct cpuTable_entry *myentry;
   myentry =getData();
  }


    /*
     * Typical data structure for a row entry
     */
struct cpuTable_entry {
    /*
     * Index values
     */
    long            cpuIndex;

    /*
     * Column values
     */
    u_long          userRAw;
    u_long          nice;
    u_long          sysRaw;
    u_long          idelRaw;

    /*
     * Illustrate using a simple linked list
     */
     int valid;
    struct cpuTable_entry *next;
};

struct cpuTable_entry *cpuTable_head;



struct cpuTable_entry *getData(){

 struct pst_dynamic      psd;
  struct pst_processor    *psp;
   int i,  cpu;
    struct cpuTable_entry *entry;
     if (pstat_getdynamic(&psd,sizeof(psd),(size_t)1,0)<0) {
    perror("pstat_getdynamic");
     exit(1);
     }
 printf("Number of active processors     %d\n", psd.psd_proc_cnt);
  printf("Max active processors           %d\n",psd.psd_max_proc_cnt);
   psp = (struct pst_processor *)malloc(psd.psd_proc_cnt*sizeof(*psp));
    if (pstat_getprocessor(psp,sizeof(*psp), psd.psd_proc_cnt,0)<0) {
         perror("pstat_getprocessor");
      exit(1);
       }
    entry = NULL;
    i=0;
      printf("befor while loop\n");
   while (i<psd.psd_proc_cnt ){

   struct cpuTable_entry *temp,*newnode;

   if (entry  == NULL){
   printf("first cpu\n");



 /*******************************************************************************

   temp = ( struct cpuTable_entry *)malloc (sizeof( struct cpuTable_entry));
   temp->cpuIndex = i+1;
   temp->userRAw =psp[i].psp_cpu_time[0];
   temp->nice =psp[i].psp_cpu_time[1];
  temp->sysRaw = psp[i].psp_cpu_time[2];
   temp->idelRaw = psp[i].psp_cpu_time[3];
   temp->valid =1;
   temp->next=NULL;

******************************************************************************/

temp=cpuTable_createEntry(i+1,psp[i].psp_cpu_time[0],psp[i].psp_cpu_time[1],psp[i].psp_cpu_time[2],psp[i].psp_cpu_time[3]);

  temp->valid =1;


   entry = temp;
   printf("Entry->cpuIndex = %d, entry->userRaw= %d \n",
entry->cpuIndex,entry->userRAw);
   }
   else {
   printf("new cpu entry\n");
     temp = entry;
    while (temp->next !=NULL)
    temp =temp->next;
 /**********************************************************************************
   newnode = (struct cpuTable_entry *) malloc (sizeof( struct
cpuTable_entry));
   newnode->cpuIndex = i;
   newnode->userRAw =psp[i].psp_cpu_time[0];
   newnode->nice =psp[i].psp_cpu_time[1];
   newnode->sysRaw = psp[i].psp_cpu_time[2];
   newnode->idelRaw = psp[i].psp_cpu_time[3];
   newnode->valid =1;
   newnode->next =NULL;
************************************************************************/
    newnode =
cpuTable_createEntry(i+1,psp[i].psp_cpu_time[0],psp[i].psp_cpu_time[1],psp[i].psp_cpu_time[2],psp[i].psp_cpu_time[3]

    );
    temp->next=newnode;
}
       i++;
     printf(" value of i: %d\n",i);
   }
      return entry;
      }



/*
 * create a new row in the (unsorted) table
*/
struct cpuTable_entry *
cpuTable_createEntry(long cpuIndex,u_long userRAw,u_long nice,u_long
sysRaw,u_long idelRaw)
{
    struct cpuTable_entry *entry;

    entry = SNMP_MALLOC_TYPEDEF(struct cpuTable_entry);
    if (!entry)
        return NULL;

    entry->cpuIndex = cpuIndex;
    entry->userRAw =userRAw;
    entry->nice=nice;
     entry->sysRaw;
     entry->idelRaw;
    entry->next = cpuTable_head;
    cpuTable_head = entry;
    return entry;
}

/*
 * remove a row from the table

void
cpuTable_removeEntry(struct cpuTable_entry *entry)
{
    struct cpuTable_entry *ptr, *prev;

    if (!entry)
        return;

    for (ptr = cpuTable_head, prev = NULL;
         ptr != NULL; prev = ptr, ptr = ptr->next) {
        if (ptr == entry)
            break;
    }
    if (!ptr)
        return;

    if (prev == NULL)
        cpuTable_head = ptr->next;
    else
        prev->next = ptr->next;

    SNMP_FREE(entry);
}
*/
/*
 * Example iterator hook routines - using 'get_next' to do most of the work
 */
netsnmp_variable_list *
cpuTable_get_first_data_point(void **my_loop_context,
                              void **my_data_context,
                              netsnmp_variable_list * put_index_data,
                              netsnmp_iterator_info *mydata)
{
    netsnmp_variable_list *vptr;
    cpuTable_head = getData();
    if (!cpuTable_head)
       return NULL;
    printf(" cpuTable_head : %d\n", cpuTable_head->userRAw);
    *my_loop_context = cpuTable_head;
    printf(" I have set the my loop context \n");
    *my_data_context = cpuTable_head;

   vptr = put_index_data;
    snmp_set_var_value(vptr,(u_char *)&cpuTable_head,
sizeof(cpuTable_head));
                       return put_index_data;

    //return cpuTable_get_next_data_point(my_loop_context, my_data_context,
                                      //  put_index_data, mydata);
}

netsnmp_variable_list *
cpuTable_get_next_data_point(void **my_loop_context,
                             void **my_data_context,
                             netsnmp_variable_list * put_index_data,
                             netsnmp_iterator_info *mydata)
{
  printf(" i aa in get next data pint\n");
      struct cpuTable_entry *entry =
        (struct cpuTable_entry *) *my_loop_context;
      netsnmp_variable_list *idx = put_index_data;
       printf(" example test: %d", entry->cpuIndex);
     /* if (entry) {
    printf(" in if entry\n");
        snmp_set_var_value(idx,(u_char *) &entry->next,
sizeof(entry->next));
        idx = idx->next_variable;
        *my_data_context = (void *) entry;
        *my_loop_context = (void *) entry->next;
     printf(" again setting contexts\n");
    } else {
      printf(" returning Null from else\n");
        return NULL;
    }*/
   if (!entry->next)
       return NULL;
       entry = entry->next;
       *my_loop_context= (void *)entry;
       *my_data_context = (void *)entry;
    snmp_set_var_value(idx,(u_char *) &entry->cpuIndex,
sizeof(entry->cpuIndex));

         return put_index_data;

}


/** handles requests for the cpuTable table */
int
cpuTable_handler(netsnmp_mib_handler *handler,
                 netsnmp_handler_registration *reginfo,
                 netsnmp_agent_request_info *reqinfo,
                 netsnmp_request_info *requests)
{

    netsnmp_request_info *request;
    netsnmp_table_request_info *table_info;
    struct cpuTable_entry *table_entry;
    netsnmp_variable_list *var;
    switch (reqinfo->mode) {
        /*
         * Read-support (also covers GetNext requests)
         */
    case MODE_GET:
      printf("in case mode get\n");
        for (request = requests; request; request = request->next) {
       printf(" in for loop\n");
       var = request->requestvb;
/*       if (request->processed != 0){
           printf("request processed not zero\n");
               continue;
               }*/
      table_entry = (struct cpuTable_entry *)
                netsnmp_extract_iterator_context(request);
        if (! table_entry){
             printf(" table entry is NULl\n");
             continue;
             }
        printf("Table Entry : \n" );
            table_info = netsnmp_extract_table_info(request);
        if (table_info==NULL) {
        printf("table_info is Nil\n");
        continue;
                }
            printf(" hoi i am here\n");
            switch (table_info->colnum) {
            case COLUMN_USERRAW:
        printf ( " case : COLUMN_USERRAW\n");
                snmp_set_var_typed_value(var, ASN_TIMETICKS,
                                         (u_char *)&table_entry->userRAw,
                                         sizeof(table_entry->userRAw));
                break;
            case COLUMN_NICE:
           printf ( " case :COLUMN_NICE\n");
                snmp_set_var_typed_value(var, ASN_TIMETICKS,
                                         (u_char *)&table_entry->nice,
                                         sizeof(table_entry->nice));
                break;
            case COLUMN_SYSRAW:
         printf ( " case :COLUMN_SYSRAW\n");
                snmp_set_var_typed_value(var, ASN_TIMETICKS,
                                         (u_char *)&table_entry->sysRaw,
                                         sizeof(table_entry->sysRaw));
                break;
            case COLUMN_IDELRAW:
         printf ( " case :  COLUMN_IDELRAW\n");
                snmp_set_var_typed_value(var, ASN_TIMETICKS,
                                         (u_char *)&table_entry->idelRaw,
                                         sizeof(table_entry->idelRaw));
                break;
            }
        }
        break;

    }
    return SNMP_ERR_NOERROR;
}





The MIB is

cpu   OBJECT IDENTIFIER
                   ::=  {  snmpagent  2 }

    cpuTable    OBJECT-TYPE
        SYNTAX        SEQUENCE  OF  CpuEntry
        ACCESS        not-accessible
        STATUS        mandatory
        DESCRIPTION    "Description"
        ::=  { cpu 1 }

    cpuEntry    OBJECT-TYPE
        SYNTAX        CpuEntry
        ACCESS        not-accessible
        STATUS        mandatory
        DESCRIPTION    "Row Description"
        INDEX        {  cpuIndex  }
        ::=  { cpuTable 1 }

    CpuEntry  ::=  SEQUENCE {
        cpuIndex  INTEGER,
        userRAw  TimeTicks,
        nice  TimeTicks,
        sysRaw  TimeTicks,
        idelRaw  TimeTicks
        }


    cpuIndex    OBJECT-TYPE
        SYNTAX            INTEGER
        ACCESS            not-accessible
        STATUS            mandatory
        DESCRIPTION        "Column Description"
        ::=  {  cpuEntry  1  }


    userRAw    OBJECT-TYPE
        SYNTAX            TimeTicks
        ACCESS            read-only
        STATUS            mandatory
        DESCRIPTION        "Column Description"
        ::=  {  cpuEntry  2  }


    nice    OBJECT-TYPE
        SYNTAX            TimeTicks
        ACCESS            read-only
        STATUS            mandatory
        DESCRIPTION        "Column Description"
        ::=  {  cpuEntry  3  }


    sysRaw    OBJECT-TYPE
        SYNTAX            TimeTicks
        ACCESS            read-only
        STATUS            mandatory
        DESCRIPTION        "Column Description"
        ::=  {  cpuEntry  4  }


    idelRaw    OBJECT-TYPE
        SYNTAX            TimeTicks
        ACCESS            read-only
        STATUS            mandatory
        DESCRIPTION        "Column Description"
        ::=  {  cpuEntry  5  }

-- 
Regards
Suresh Kumar Khemka

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

_______________________________________________
Net-snmp-users mailing list
[email protected]
Please see the following page to unsubscribe or change other options:
https://lists.sourceforge.net/lists/listinfo/net-snmp-users
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.