Chinaunix首页 | 论坛 | 博客
  • 博客访问: 563916
  • 博文数量: 112
  • 博客积分: 5090
  • 博客等级: 大校
  • 技术积分: 1158
  • 用 户 组: 普通用户
  • 注册时间: 2005-08-19 22:21
文章分类

全部博文(112)

文章存档

2016年(1)

2015年(1)

2012年(1)

2011年(5)

2010年(7)

2009年(6)

2008年(18)

2007年(28)

2006年(16)

2005年(29)

我的朋友

分类: 系统运维

2006-09-01 20:32:30

how to Initialise the contents of the table?


Thu, 10 Aug 2006 08:11:14 -0700

hi,all
I generated mib2c files by mib2c.conf also with iterator option.and now i wanted to know how to Initialise the contents of the table in INIT function.take this structure of table_entry as example.
struct tbModuleTable_entry {
    /*
     * Index values
     */
    long            tbModuleIndex;

    /*
     * Column values
     */
    //long            tbModuleIndex;
    u_long          tbModuleID;
    char            tbModuleDescription;
    char            old_tbModuleDescription;

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

thanks in advance!
-- 
qiang
 

Re: how to Initialise the contents of the table?

Dave Shield
Thu, 10 Aug 2006 08:22:25 -0700

On 10/08/06, 蔷 <[EMAIL PROTECTED]> wrote:
I generated mib2c files by mib2c.conf also with iterator option.and now i
wanted to know how to Initialise the contents of the table
If you look at the generated code, you should see a routine
'tbModuleTable_createEntry()'.  Call this with the relevant values for
each row you wish to create.

The only unexpected thing is you'll need to explicitly set the 'valid'
flag for each row.
Something like:

struct tbModuleTable_entry *entry;

entry = tbModuleTable_createEntry(1, 256, "eenie");
entry->valid = 1;
entry = tbModuleTable_createEntry(3, 128, "meenie");
entry->valid = 1;
entry = tbModuleTable_createEntry(4, 64, "mynie");
entry->valid = 1;
entry = tbModuleTable_createEntry(2, 32, "mo");
entry->valid = 1;


Dave

Re: how to Initialise the contents of the table?


Fri, 11 Aug 2006 01:15:51 -0700

i saw this routine and i'm pulzzled about "table_entry = (struct tbModuleTable_entry *)netsnmp_extract_iterator_context(request);" it seems that table_entry get relevant datas from this netsnmp_extract_iterator_context;and how can i initial contents of table in iterator.i can't understand the iterator operation mechanism. i saw an exitent mib handler code of net-snmp which initials in this way as following: 
   
    iinfo->make_data_context = netSnmpHostsTable_context_convert_function;
    iinfo->free_data_context = netSnmpHostsTable_data_free;
    iinfo->free_loop_context_at_end = netSnmpHostsTable_loop_free;

is there any examples mibs for how to modify the generater code by mib2c.iterate.conf?
 
 that's my generated code for my mib(not modified),can you tell me how to set the datas of table?

/*
 * Note: this file originally auto-generated by mib2c using
 *  : mib2c.iterate.conf,v 5.17 2005/05/09 08:13:45 dts12 Exp $
 */

#include
#include
#include
#include "tb.h"

/** Initializes the tb module */
void
init_tb(void)
{
    /*
     * here we initialize all the tables we're planning on supporting
     */
    initialize_table_tbModuleTable();
    initialize_table_tbHwVersionTable();
}

/** Initialize the tbModuleTable table by defining its contents and how it's structured */
void
initialize_table_tbModuleTable(void)
{
    static oid      tbModuleTable_oid[] =
        { 1, 3, 6, 1, 4, 1, 21776, 1, 1 };
    size_t          tbModuleTable_oid_len = OID_LENGTH(tbModuleTable_oid);
    netsnmp_handler_registration *reg;
    netsnmp_iterator_info *iinfo;
    netsnmp_table_registration_info *table_info;

    reg =
        netsnmp_create_handler_registration("tbModuleTable",
                                            tbModuleTable_handler,
                                            tbModuleTable_oid,
                                            tbModuleTable_oid_len,
                                            HANDLER_CAN_RWRITE);

    table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
    netsnmp_table_helper_add_indexes(table_info, ASN_INTEGER,   /* index: tbModuleIndex */
                                     0);
    table_info->min_column = XXX;
    table_info->max_column = YYY;

    iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info);
    iinfo->get_first_data_point = tbModuleTable_get_first_data_point;
    iinfo->get_next_data_point = tbModuleTable_get_next_data_point;
    iinfo->table_reginfo = table_info;

    netsnmp_register_table_iterator(reg, iinfo);

    /*
     * Initialise the contents of the table here
     */
}

    /*
     * Typical data structure for a row entry
     */
struct tbModuleTable_entry {
    /*
     * Index values
     */
    long            tbModuleIndex;

    /*
     * Column values
     */
    long            tbModuleIndex;
    u_long          tbModuleID;
    char            tbModuleDescription;
    char            old_tbModuleDescription;

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

struct tbModuleTable_entry *tbModuleTable_head;

/*
 * create a new row in the (unsorted) table
 */
struct tbModuleTable_entry *
tbModuleTable_createEntry(long tbModuleIndex,)
{
    struct tbModuleTable_entry *entry;

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

    entry->tbModuleIndex = tbModuleIndex;
    entry->next = tbModuleTable_head;
    tbModuleTable_head = entry;
    return entry;
}

/*
 * remove a row from the table
 */
void
tbModuleTable_removeEntry(struct tbModuleTable_entry *entry)
{
    struct tbModuleTable_entry *ptr, *prev;

    if (!entry)
        return;                 /* Nothing to remove */

    for (ptr = tbModuleTable_head, prev = NULL;
         ptr != NULL; prev = ptr, ptr = ptr->next) {
        if (ptr == entry)
            break;
    }
    if (!ptr)
        return;                 /* Can't find it */

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

    SNMP_FREE(entry);           /* XXX - release any other internal resources */
}


/*
 * Example iterator hook routines - using 'get_next' to do most of the work
 */
netsnmp_variable_list *
tbModuleTable_get_first_data_point(void **my_loop_context,
                                   void **my_data_context,
                                   netsnmp_variable_list * put_index_data,
                                   netsnmp_iterator_info *mydata)
{
    *my_loop_context = tbModuleTable_head;
    return tbModuleTable_get_next_data_point(my_loop_context,
                                             my_data_context,
                                             put_index_data, mydata);
}

netsnmp_variable_list *
tbModuleTable_get_next_data_point(void **my_loop_context,
                                  void **my_data_context,
                                  netsnmp_variable_list * put_index_data,
                                  netsnmp_iterator_info *mydata)
{
    struct tbModuleTable_entry *entry =
        (struct tbModuleTable_entry *) *my_loop_context;
    netsnmp_variable_list *idx = put_index_data;

    if (entry) {
        snmp_set_var_value(idx, entry->tbModuleIndex,
                           sizeof(entry->tbModuleIndex));
        idx = idx->next_variable;
        *my_data_context = (void *) entry;
        *my_loop_context = (void *) entry->next;
    } else {
        return NULL;
    }
}


/** handles requests for the tbModuleTable table */
int
tbModuleTable_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 tbModuleTable_entry *table_entry;

    switch (reqinfo->mode) {
        /*
         * Read-support (also covers GetNext requests)
         */
    case MODE_GET:
        for (request = requests; request; request = request->next) {
            table_entry = (struct tbModuleTable_entry *)
                netsnmp_extract_iterator_context(request);
            table_info = netsnmp_extract_table_info(request);

            switch (table_info->colnum) {
            case COLUMN_TBMODULEINDEX:
                snmp_set_var_typed_value(request->requestvb, ASN_INTEGER,
                                         table_entry->tbModuleIndex,
                                         sizeof(table_entry->
                                                tbModuleIndex));
                break;
            case COLUMN_TBMODULEID:
                snmp_set_var_typed_value(request->requestvb, ASN_UNSIGNED,
                                         table_entry->tbModuleID,
                                         sizeof(table_entry->tbModuleID));
                break;
            case COLUMN_TBMODULEDESCRIPTION:
                snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR,
                                         table_entry->tbModuleDescription,
                                         sizeof(table_entry->
                                                tbModuleDescription));
                break;
            }
        }
        break;

        /*
         * Write-support
         */
    case MODE_SET_RESERVE1:
        for (request = requests; request; request = request->next) {
            table_entry = (struct tbModuleTable_entry *)
                netsnmp_extract_iterator_context(request);
            table_info = netsnmp_extract_table_info(request);

            switch (table_info->colnum) {
            case COLUMN_TBMODULEDESCRIPTION:
                if (request->requestvb->type != ASN_OCTET_STR) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_ERR_WRONGTYPE);
                    return SNMP_ERR_NOERROR;
                }
                /*
                 * Also may need to check size/value
                 */
                break;
            default:
                netsnmp_set_request_error(reqinfo, request,
                                          SNMP_ERR_NOTWRITABLE);
                return SNMP_ERR_NOERROR;
            }
        }
        break;

    case MODE_SET_RESERVE2:
        break;

    case MODE_SET_FREE:
        break;

    case MODE_SET_ACTION:
        for (request = requests; request; request = request->next) {
            table_entry = (struct tbModuleTable_entry *)
                netsnmp_extract_iterator_context(request);
            table_info = netsnmp_extract_table_info(request);

            switch (table_info->colnum) {
            case COLUMN_TBMODULEDESCRIPTION:
                /*
                 * Need to save old 'table_entry->tbModuleDescription' value.
                 * May need to use 'memcpy'
                 */
                table_entry->old_tbModuleDescription =
                    table_entry->tbModuleDescription;
                table_entry->tbModuleDescription =
                    request->requestvb-> val.YYY;
                break;
            }
        }
        break;

    case MODE_SET_UNDO:
        for (request = requests; request; request = request->next) {
            table_entry = (struct tbModuleTable_entry *)
                netsnmp_extract_iterator_context(request);
            table_info = netsnmp_extract_table_info(request);

            switch (table_info->colnum) {
            case COLUMN_TBMODULEDESCRIPTION:
                /*
                 * Need to restore old 'table_entry->tbModuleDescription' value.
                 * May need to use 'memcpy'
                 */
                table_entry->tbModuleDescription =
                    table_entry->old_tbModuleDescription;
                break;
            }
        }
        break;

    case MODE_SET_COMMIT:
        break;
    }
    return SNMP_ERR_NOERROR;
}

thanks in advance !

  

 
On 8/10/06, Dave Shield <> wrote:
On 10/08/06, qiang <> wrote:
> I generated mib2c files by mib2c.conf also with iterator option.and now i
> wanted to know how to Initialise the contents of the table

If you look at the generated code, you should see a routine
'tbModuleTable_createEntry()'.  Call this with the relevant values for
each row you wish to create.

The only unexpected thing is you'll need to explicitly set the 'valid'
flag for each row.
Something like:

struct tbModuleTable_entry *entry;

entry = tbModuleTable_createEntry(1, 256, "eenie");
entry->valid = 1;
entry = tbModuleTable_createEntry(3, 128, "meenie");
entry->valid = 1;
entry = tbModuleTable_createEntry(4, 64, "mynie");
entry->valid = 1;
entry = tbModuleTable_createEntry(2, 32, "mo");
entry->valid = 1;


Dave



-- 
qiang
 

Re: how to Initialise the contents of the table?

Dave Shield
Fri, 11 Aug 2006 01:32:15 -0700

On 11/08/06, 蔷 <[EMAIL PROTECTED]> wrote:
i saw this routine and i'm pulzzled about "table_entry = (struct
tbModuleTable_entry
*)netsnmp_extract_iterator_context(request);" it seems that
table_entry get relevant datas from this
netsnmp_extract_iterator_context;and how can i initial
contents of table in iterator.
OK - take a step back.
There are three main areas involved in handling a table (regardless of
which helper you might use to do this):

 a)  Building a internal representation of the table
 b)  Choosing the appropriate row for a given request
 c)  Returning or updating the relevant columns from that row.

With most of the helpers, these three tasks tend to be handled separately.
In the case of the iterator helper:
 a)  is done via tbModuleTable_createEntry()
          (typically invoked from the init routine)
 b)  is handled by tbModuleTable_get_{first,next}_data_point
          (plus the main iterator helper)
 c)  is the responsibility of tbModuleTable_handler()


i can't understand the iterator operation mechanism.
The get_{first,next} routines cycle through the rows of the table, in
whatever order is most natural, setting the index value(s) for each
row.  The main iterator handler keeps track of which row(s) are
relevant for this particular PDU.

Once this has been done, the iterator handler calls the
tbModuleTable_handler() routine, which extracts the relevant row for
each varbind ("request"), and works with the appropriate column from
it.

i saw an exitent mib handler code of net-snmp which initials in
this way as following:

    iinfo->make_data_context = netSnmpHostsTable_context_convert_function;
    iinfo->free_data_context = netSnmpHostsTable_data_free;
    iinfo->free_loop_context_at_end = netSnmpHostsTable_loop_free;
No - I wouldn't use that particular example as a template.  It uses
the "iterator_access" framework, which is built upon the basic
iterator helper, but has a very different model.

is there any examples mibs for how to modify the generater code by
mib2c.iterate.conf?
Try looking at agent/nsCache.c
That uses the iterator helper, in a very similar way to your code.

Dave
 

Re: how to Initialise the contents of the table?


Fri, 11 Aug 2006 08:12:07 -0700

thank you very much,it did help me a lot by the example nsCache.c. thank you.
i saw the agent/nsCache.c ,but i can't see how it initials the contents of the table,it seems that it didn't do anything to initial the contents of the table and all depent on setting request to initial contents of table?is it right or i'm wrong? and maybe because not initial,there is no information about how to create an entry by that routine called ***_CreateEntry, i still felt it difficult to know how to initial by that routine.:<

On 8/11/06, Dave Shield <> wrote: 
On 11/08/06, qiang <> wrote:
> i saw this routine and i'm pulzzled about "table_entry = (struct
> tbModuleTable_entry
> *)netsnmp_extract_iterator_context(request);" it seems that
> table_entry get relevant datas from this
> netsnmp_extract_iterator_context;and how can i initial
> contents of table in iterator.

OK - take a step back.
There are three main areas involved in handling a table (regardless of
which helper you might use to do this):

a)  Building a internal representation of the table
b)  Choosing the appropriate row for a given request
c)  Returning or updating the relevant columns from that row.

With most of the helpers, these three tasks tend to be handled separately.
In the case of the iterator helper:
a)  is done via tbModuleTable_createEntry()
          (typically invoked from the init routine)
b)  is handled by tbModuleTable_get_{first,next}_data_point
          (plus the main iterator helper)
c)  is the responsibility of tbModuleTable_handler()


>i can't understand the iterator operation mechanism.

The get_{first,next} routines cycle through the rows of the table, in
whatever order is most natural, setting the index value(s) for each
row.  The main iterator handler keeps track of which row(s) are
relevant for this particular PDU.

Once this has been done, the iterator handler calls the
tbModuleTable_handler() routine, which extracts the relevant row for
each varbind ("request"), and works with the appropriate column from
it.

> i saw an exitent mib handler code of net-snmp which initials in
> this way as following:
>
>     iinfo->make_data_context = netSnmpHostsTable_context_convert_function;
>     iinfo->free_data_context = netSnmpHostsTable_data_free;
>     iinfo->free_loop_context_at_end = netSnmpHostsTable_loop_free;

No - I wouldn't use that particular example as a template.  It uses
the "iterator_access" framework, which is built upon the basic
iterator helper, but has a very different model.

> is there any examples mibs for how to modify the generater code by
> mib2c.iterate.conf ?

Try looking at agent/nsCache.c
That uses the iterator helper, in a very similar way to your code.

Dave

thanks

-- 
qiang
 

Re: how to Initialise the contents of the table?

Dave Shield
Fri, 11 Aug 2006 08:24:42 -0700

On 11/08/06, 蔷 <[EMAIL PROTECTED]> wrote:
 i saw the agent/nsCache.c ,but i can't see how it initials the contents of
the table,it seems that it didn't do anything to initial the contents of the
table
That's correct - this particular table is responding to entries
created elsewhere in the agent.
I wouldn't suggest you try and follow this in detail - it's not
typical of most tables.

                             there is no information
about how to create an entry by that routine called ***_CreateEntry, i still
felt it difficult to know how to initial by that routine.:
Please see my first response on this thread, which described how to do this.

Dave
 

Re: how to Initialise the contents of the table?


Sun, 13 Aug 2006 10:25:58 -0700

i created an entry as you told me.but snmpd got a segment fault when i snmpget or snmpset althought i 'm sure my added codes didn't cause this fault separately ,you can understand me ?
during modifying ,i got two questions this time as following:
1,whether the routine tbModuleTable_createEntry need to modify?in my opinion,if not, it coundn't create an entry in function,because what i did as you told me is just to fill the contents of the table,but if there is no row of the table,i think filling makes no it right?
i saw the \agent\mibgroup\disman\event\mtEventTable.c~``it uses the APIs netsnmp_tdata_create_row and netsnmp_table_row_add_index,whether i should add these APIs in tbModuleTable_createEntry of my mib code?if not , i fill the contents into where? i can't understand it.
2,if i initial the contents of the table in the function "initialize_table_tbModuleTable", whether i should definit a static variable "entry" in "initialize_table_tbModuleTable" as the return of the routine tbModuleTable_createEntry.if not ,perhaps it can get the entry by the routine netsnmp_extract_iterator_context?

i'm so sorry,because i have made so much trouble on this thread.but actually,i still couldn't well understand  how the whole agent works,because it 's impossible for me to read all the codes of net-snmp.so why there is no document about how to modify the codes generated by mib2c.iterator.conf ?i saw the document called "agent" for mib2c by old api configuration.

thank you sincerely!



On 8/11/06, Dave Shield <> wrote:
On 11/08/06, qiang <> wrote:
>  i saw the agent/nsCache.c ,but i can't see how it initials the contents of
> the table,it seems that it didn't do anything to initial the contents of the
> table

That's correct - this particular table is responding to entries
created elsewhere in the agent.
I wouldn't suggest you try and follow this in detail - it's not
typical of most tables.

>                              there is no information
> about how to create an entry by that routine called ***_CreateEntry, i still
> felt it difficult to know how to initial by that routine.:

Please see my first response on this thread, which described how to do this.

Dave



-- 
qiang 
 

Re: how to Initialise the contents of the table?

Dave Shield
Mon, 14 Aug 2006 01:29:15 -0700

On 12/08/06, 蔷 <[EMAIL PROTECTED]> wrote:
i created an entry as you told me.but snmpd got a segment fault when i
snmpget or snmpset
Right - then you need to determine exactly *where* this fault is
occuring, and what is triggering it.   Try running the agent under a
debugger, starting it with "-f -Le", and then query it as before.
When the agent falls over, look at a back-trace of exactly where it
had got to, and the code on (and around) the line that caused the
fault.
  If you can identify exactly what triggered the crash, that's the
first step towards fixing it.


1,whether the routine tbModuleTable_createEntry need to modify?in my
opinion,if not, it coundn't create an entry in function,because what i did
as you told me is just to fill the contents of the table,but if there is no
row of the table,i think filling makes no sense.is it right?
I'm sorry - I don't understand what you are asking here.
The purpose of this routine is to create a new row in the table.
Looking at your code, it's possible that you might need to set values
for the tbModuleID and tbModuleDescription fields.  Is that what you
mean?


i saw the \agent\mibgroup\disman\event\mtEventTable.c~``it
uses the APIs netsnmp_tdata_create_row and
netsnmp_table_row_add_index,
That's because it uses a different helper.   This module is built
using the 'table_tdata' helper rather than the 'table_iterator'
helper, so it has a different structure.   Don't try to merge
different model together, unless you're really sure you know what you
are doing.  Much better to stick with one approach, and get that
working.


2,if i initial the contents of the table in the function
"initialize_table_tbModuleTable", whether i should definit
a static variable "entry" in
"initialize_table_tbModuleTable" as the return of the
routine tbModuleTable_createEntry.
The 'entry' variable doesn't need to be static, since it's only used
within a single routine.  But yes, you do need to declare a variable
of this name within the initialize routine, if that's where you are
setting up the initial contents of the table.

But I'm slightly confused - you said that you've already got the
module compiled and linked into the agent.  Surely you'll need this
variable defined, in order to get the code to compile in the first
place?


                                  why there is no
document about how to modify the codes generated by mib2c.iterator.conf ?i
saw the document called "agent" for mib2c by old api configuration.
Funny you should ask that.  I'm sort-of in the middle of writing a
book to cover exactly this sort of question.  However, I've recently
got sucked back into answering questions on the mailing list, and this
has eaten away at the time that would be otherwise spent on the book.
At some point, I'll need to drop out again, to blitz the book again,
and get the thing finished!
Unfortunately, you can't have both - either I'm helping people with
problems now, or I'm providing documentation to help them in the
future.  Either way, somebody loses.

Dave
 
 
阅读(1866) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~