Hi, I haven't managed to find the reason why the cache helper implementation of the net-snmp-5.7.2.1 doesn't work properly in my application.
I've cross-compiled the net-snmp-5.6.2.1 version, using the arm-linux-gcc 4.5.1, and my sub-agent works fine. When I compared the code of the cache helper implementation in the net-snmp 5.7.2.1 with 5.6.2.1 I found out that the netsnmp_cache structure of the net-snmp 5.7.2.1 contains a new variable: int refcnt. This variable is used in the netsnmp_cache_handler_owns_cache() function. Does anybody can explain me how should I use this function in the source code which I mentioned in my previous message? I don't exactly understand why, but when I simply add the "refcnt" variable into the netsnmp_cache structure definition (cache_handler.h) of the net-snmp 5.6.2.1 (with which my application works) and recompiled it, the sub-agent crashed. Does the net-snmp support the cross-compilation with arm-linux-gcc? Maybe somebody knows which kind of tests from the net-snmp have to show the result of the correct cache helper work? Thanks in advance, Ekaterina On 3/31/14, Ekaterina Potachits <potach...@gmail.com> wrote: > 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 analysed 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) > { > netsnmp_tdata *table = (netsnmp_tdata *) cache->magic; > struct ManagementNodeTable_entry mnNodeEntry; > > if (table != NULL) { > netsnmp_tdata_row *row; > > // Call functions to fill the ManagementNodeTable_entry structure. > // 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 > ------------------------------------------------------------------------------ _______________________________________________ Net-snmp-coders mailing list Net-snmp-coders@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/net-snmp-coders