pota...@gmail.com
unread,Mar 31, 2014, 9:01:05 AM3/31/14You do not have permission to delete messages in this group
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to
Hi All,
I built the last version of the net-snmp-5.7.2.1 using the arm-linux-gcc compiler with the following flags:
CC=arm-linux-gcc ./configure --target=arm-linux --host=arm-linux --build=x86 \.
--program-prefix=/usr --prefix=/usr --exec-prefix=/usr --with-endianness=big \.
--enable-privacy --enable-des --enable-md5 --without-rpm --enable-shared \
--with-cflags="-O2 -fsigned-char -I$WORKSPACE/Build/target/usr/include" \
--with-persistent-directory=/var/net-snmp --with-copy-persistent-files="no" \
--with-out-mib-modules="ucd_snmp notification notification-log-mib target utilities disman/event disman/schedule host" \.
--sysconfdir=/conf --with-openssl=internal --disable-embedded-perl \.
--disable-perl-cc-checks --with-perl-modules=no --with-sys-contact=root@localhost \
--disable-manuals --disable-scripts --disable-applications --disable-mibs --disable-mib-loading \
--disable-deprecated --enable-ipv6 --with-default-snmp-version="3" \.
--with-sys-location="Unknown" --with-logfile=/var/log/snmpd.log --with-security-modules="usm tsm"
The cross-compiled net-snmp libraries I use in my sub-agent implementation.
And it seems that the cache helper doesn't work in my case.
Before I decided to use the net-snmp-5.7.2 I use the net-snmp-5.4.3 and everything works fine.
My sub-agent uses the cache mechanism to update the particular MIB table before the GET/GETNEXT request comes.
In my case the first calling of the cache load works fine but after the cache timeout expires the sub-agents crashes with segmentation fault and the snmpwalk command gets the message: "Error in packet. Reason: (genError) A general failure occured Failed object: iso.3.6.1.4.1.231.2.10.2.2.10.3.1."
I analyzed the core dump of my application with gdb and it shows, that sub-agent crashes in the _cache_load () when it tries to call the _cache_free().
Maybe somebody can help me and explain what is wrong?
I have the following code:
struct ManagementNodeTable_entry {
long mnUnitId;
long mnNodeNr;
...
};
#define MANAGEMENTNODETABLE_TIMEOUT 10
initialize_table_ManagementNodeTable(void)
{
oid ManagementNodeTable_oid[] = { 1, 3, 6, 1, 4, 1, 231, 2, 10, 2, 2, 10, 3, 1 };
size_t ManagementNodeTable_oid_len = OID_LENGTH(ManagementNodeTable_oid);
netsnmp_tdata *table_data = NULL;
netsnmp_handler_registration *reg;
netsnmp_table_registration_info *table_info;
netsnmp_cache *cache;
reg = netsnmp_create_handler_registration("ManagementNodeTable",
ManagementNodeTable_handler,
ManagementNodeTable_oid,
ManagementNodeTable_oid_len,
HANDLER_CAN_RONLY);
table_data = netsnmp_tdata_create_table("ManagementNodeTable", 0);
if (NULL == table_data) {
snmp_log(LOG_ERR,
"error creating tdata table for ManagementNodeTable\n");
return;
}
cache = netsnmp_cache_create(MANAGEMENTNODETABLE_TIMEOUT,
ManagementNodeTable_load,
ManagementNodeTable_free,
ManagementNodeTable_oid,
ManagementNodeTable_oid_len);
if (NULL == cache) {
snmp_log(LOG_ERR,
"error creating cache for ManagementNodeTable\n");
return;
}
else {
cache->magic = (void *) table_data;
cache->flags |= (NETSNMP_CACHE_DONT_FREE_BEFORE_LOAD | NETSNMP_CACHE_DONT_FREE_EXPIRED | NETSNMP_CACHE_DONT_AUTO_RELEASE);
}
table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
if (NULL == table_info) {
snmp_log(LOG_ERR,
"error creating table info for ManagementNodeTable\n");
return;
}
netsnmp_table_helper_add_indexes(table_info,
ASN_INTEGER, /* index: mnUnitId */
ASN_INTEGER, /* index: mnNodeNr */
0);
table_info->min_column = COLUMN_MNUNITID;
table_info->max_column = COLUMN_UNITNODECONTROLLERFWVERSION;
netsnmp_tdata_register(reg, table_data, table_info);
if (cache) {
netsnmp_inject_handler (reg,
netsnmp_cache_handler_get(cache)
);
}
}
/** Create a new row in the table */
netsnmp_tdata_row *
ManagementNodeTable_createEntry (netsnmp_tdata *table_data,
struct ManagementNodeTable_entry *srcEntry)
{
struct ManagementNodeTable_entry *destEntry;
netsnmp_tdata_row *row;
destEntry = SNMP_MALLOC_TYPEDEF (struct ManagementNodeTable_entry);
if (!destEntry)
return NULL;
row = netsnmp_tdata_create_row();
if (!row) {
SNMP_FREE (destEntry);
return NULL;
}
memcpy (destEntry, srcEntry, sizeof (struct ManagementNodeTable_entry));
row->data = destEntry;
netsnmp_tdata_row_add_index (row, ASN_INTEGER,
&(destEntry->mnUnitId),
sizeof(destEntry->mnUnitId));
netsnmp_tdata_row_add_index (row, ASN_INTEGER,
&(destEntry->mnNodeNr),
sizeof(destEntry->mnNodeNr));
if (table_data) {
netsnmp_tdata_add_row( table_data, row );
}
return row;
}
/** Cache handling */
int
ManagementNodeTable_load(netsnmp_cache * cache, void *vmagic)
{
//don't work!!!
//netsnmp_tdata *table = (netsnmp_tdata *) vmagic;
netsnmp_tdata *table = (netsnmp_tdata *) cache->magic;
struct ManagementNodeTable_entry mnNodeEntry;
if (table != NULL) {
netsnmp_tdata_row *row;
// Update ManagementNodeTable table
....
row = ManagementNodeTable_createEntry (table, &mnNodeEntry);
}
return 0;
}
void
ManagementNodeTable_free(netsnmp_cache * cache, void *vmagic)
{
netsnmp_tdata *table = (netsnmp_tdata *) cache->magic;
netsnmp_tdata_row *row;
// remove all existing rows
while ( netsnmp_tdata_row_count(table) > 0 )
{
struct ManagementNodeTable_entry *entry;
row = netsnmp_tdata_row_first( table );
entry = (struct ManagementNodeTable_entry *) row->data;
SNMP_FREE(entry);
netsnmp_tdata_remove_and_delete_row( table, row );
}
}
/** Handles requests for the ManagementNodeTable table */
int
ManagementNodeTable_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 ManagementNodeTable_entry *table_entry;
DEBUGMSGTL(("ManagementNodeTable:handler",
"Processing request (%d)\n", reqinfo->mode));
switch (reqinfo->mode) {
/* Read-support (also covers GetNext requests) */
case MODE_GET:
for (request = requests; request; request = request->next) {
if (request->processed)
continue;
table_entry = (struct ManagementNodeTable_entry *) netsnmp_tdata_extract_entry(request);
table_info = netsnmp_extract_table_info(request);
switch (table_info->colnum) {
case COLUMN_MNUNITID:
if (!table_entry) {
netsnmp_set_request_error(reqinfo, request,
SNMP_NOSUCHINSTANCE);
continue;
}
snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER,
table_entry->mnUnitId);
break;
case COLUMN_MNNODENR:
if (!table_entry) {
netsnmp_set_request_error(reqinfo, request,
SNMP_NOSUCHINSTANCE);
continue;
}
snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER,
table_entry->mnNodeNr);
break;
....
default:
netsnmp_set_request_error(reqinfo, request,
SNMP_NOSUCHOBJECT);
break;
}
}
break;
}
return SNMP_ERR_NOERROR;
}
Thanks,
Ekaterina