分类: 系统运维
2006-09-01 20:32:30
蔷
Thu, 10 Aug 2006 08:11:14 -0700
/*
* Column values
*/
//long tbModuleIndex;
u_long tbModuleID;
char tbModuleDescription;
char old_tbModuleDescription;
/*
* Illustrate using a simple linked list
*/
int valid;
struct tbModuleTable_entry *next;
};
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 -0700i 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
--
qiangRe: how to Initialise the contents of the table?
Dave Shield
Fri, 11 Aug 2006 01:32:15 -0700On 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. DaveRe: how to Initialise the contents of the table?
蔷
Fri, 11 Aug 2006 08:12:07 -0700thank 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
--
qiangRe: how to Initialise the contents of the table?
Dave Shield
Fri, 11 Aug 2006 08:24:42 -0700On 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 tableThat'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. DaveRe: how to Initialise the contents of the table?
蔷
Sun, 13 Aug 2006 10:25:58 -0700i 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
--qiangRe: how to Initialise the contents of the table?
Dave Shield
Mon, 14 Aug 2006 01:29:15 -0700On 12/08/06, 蔷<[EMAIL PROTECTED]> wrote: i created an entry as you told me.but snmpd got a segment fault when i snmpget or snmpsetRight - 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