RE: Problem with dynamic row creation and free inside the table.
"Graeme Wilson" <[email protected]>
| Newsgroups | gmane.network.net-snmp.user |
|---|---|
| Message-ID | <[email protected]> |
Hi, Not sure if you ever found a solution/workaround to this, but I had a similar problem a while ago (with the free functions not getting called correctly, or getting called too many times) - and posted a email or 2 on the list as well - I suspect there is a bug. In the end I moved to using the MFD-iterator style code. Regards Graeme ________________________________ From: [email protected] [mailto:[email protected]] On Behalf Of Sreenath S Sent: 10 August 2007 10:33 To: [email protected] Subject: Problem with dynamic row creation and free inside the table. Hi All, In my table implementation, I am creating a row inside the "xxx_get_first_data_point" function using "xxx_createEntry" till it reaches the maximum allowed count, as the row creation needs to be dynamic. But I don't know the correct way to free these allocated rows. The function "xxx_free_loop_context_at_end" is not getting called even if it is given in the function pointer like this, "iinfo->free_loop_context_at_end = xxx_free_loop_context_at_end". But "xxx_free_data_context" will gets called if it is given in "iinfo->free_data_context = xxx_free_data_context_at_end". Even this "xxx_free_data_context_at_end" doesn't help, as it is called on every time "xxx_get_next_data_point" returns NULL. On a "snmpwalk" the "net-snmp handler" is called in a column wise order, so traversal through same row happens multiple times for each column value and "xxx_get_next_data_point" returns NULL on each occasion. So I am getting only the first column values for each row after "snmpwalk". This is because after the traversal for first column the entire row gets freed. If anybody knows the solution for this please reply back. Please find the source code and "snmpwalk" output below for the reference. Best Regards, Sreenath SOURCE CODE =========== /* * Note: this file originally auto-generated by mib2c using * : mib2c.iterate.conf,v 1.4 2004/10/14 19:48:52 slozovsk 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 "dot1xPaePortTable.h" struct dot1xPaePortTable_entry *dot1xPaePortTable_head = NULL; static int rowCount = 0; /** Initializes the dot1xPaePortTable module */ void init_dot1xPaePortTable(void) { /* * here we initialize all the tables we're planning on supporting */ initialize_table_dot1xPaePortTable(); } /** Initialize the dot1xPaePortTable table by defining its contents and how it's * structured */ void initialize_table_dot1xPaePortTable(void) { static oid dot1xPaePortTable_oid[] = { 1, 0, 8802, 1, 1, 1, 1, 1, 2 }; size_t dot1xPaePortTable_oid_len = OID_LENGTH(dot1xPaePortTable_oid); netsnmp_handler_registration *reg; netsnmp_iterator_info *iinfo; netsnmp_table_registration_info *table_info; reg = netsnmp_create_handler_registration("dot1xPaePortTable", dot1xPaePortTable_handler, dot1xPaePortTable_oid, dot1xPaePortTable_oid_len, HANDLER_CAN_RWRITE); table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info); netsnmp_table_helper_add_indexes(table_info, ASN_INTEGER, /* index: dot1xPaePortNumber */ 0); table_info->min_column = 2; table_info->max_column = 5; iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info); iinfo->get_first_data_point = dot1xPaePortTable_get_first_data_point; iinfo->get_next_data_point = dot1xPaePortTable_get_next_data_point; iinfo->table_reginfo = table_info; iinfo->free_loop_context = NULL; iinfo->free_data_context = dot1xPaePortTable_free_loop_context_at_end; iinfo->free_loop_context_at_end = dot1xPaePortTable_free_loop_context_at_end; netsnmp_register_table_iterator(reg, iinfo); /* * Initialise the contents of the table here */ } /* * create a new row in the (unsorted) table */ struct dot1xPaePortTable_entry * dot1xPaePortTable_createEntry(long dot1xPaePortNumber) { struct dot1xPaePortTable_entry *entry = NULL; entry = SNMP_MALLOC_TYPEDEF(struct dot1xPaePortTable_entry); if (!entry) return NULL; entry->dot1xPaePortNumber = dot1xPaePortNumber; entry->valid = 1; entry->next = dot1xPaePortTable_head; dot1xPaePortTable_head = entry; return entry; } /* * remove a row from the table */ void dot1xPaePortTable_removeEntry(struct dot1xPaePortTable_entry *entry) { struct dot1xPaePortTable_entry *ptr, *prev; if (!entry) return; /* Nothing to remove */ for (ptr = dot1xPaePortTable_head, prev = NULL; ptr != NULL; prev = ptr, ptr = ptr->next) { if (ptr == entry) break; } if (!ptr) return; /* Can't find it */ if (prev == NULL) dot1xPaePortTable_head = ptr->next; else prev->next = ptr->next; SNMP_FREE(entry); /* XXX - release any other internal resources */ } void dot1xPaePortTable_free_loop_context_at_end(void *my_loop_context, netsnmp_iterator_info *iinfo) { struct dot1xPaePortTable_entry *ptr; ptr = (struct dot1xPaePortTable_entry *) my_loop_context; dot1xPaePortTable_removeEntry(ptr); } /* * Example iterator hook routines - using 'get_next' to do most of the work */ netsnmp_variable_list * dot1xPaePortTable_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 * ret_val = NULL; if (rowCount < MAX_ROW_COUNT) dot1xPaePortTable_createEntry(++rowCount); *my_loop_context = dot1xPaePortTable_head; ret_val = dot1xPaePortTable_get_next_data_point(my_loop_context, my_data_context, put_index_data, mydata); return ret_val; } netsnmp_variable_list * dot1xPaePortTable_get_next_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list * put_index_data, netsnmp_iterator_info *mydata) { struct dot1xPaePortTable_entry *entry = (struct dot1xPaePortTable_entry *) *my_loop_context; netsnmp_variable_list *idx = put_index_data; if (NULL != entry) { snmp_set_var_value(idx, (u_char *)&(entry->dot1xPaePortNumber), sizeof(entry->dot1xPaePortNumber)); idx = idx->next_variable; *my_data_context = (void *) entry; *my_loop_context = (void *) entry->next; return put_index_data; } else { return NULL; } } /** handles requests for the dot1xPaePortTable table */ int dot1xPaePortTable_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 dot1xPaePortTable_entry *table_entry; switch (reqinfo->mode) { /* * Read-support (also covers GetNext requests) */ case MODE_GET: for (request = requests; request; request = request->next) { if (request->processed != 0) { continue; } table_entry = (struct dot1xPaePortTable_entry *) netsnmp_extract_iterator_context(request); if (table_entry == NULL) { continue; } table_info = netsnmp_extract_table_info(request); if (table_info == NULL) { continue; } switch (table_info->colnum) { case COLUMN_DOT1XPAEPORTPROTOCOLVERSION: table_entry->dot1xPaePortProtocolVersion = 1; snmp_set_var_typed_value(request->requestvb, ASN_UNSIGNED, (u_char *)&(table_entry-> dot1xPaePortProtocolVersion), sizeof(table_entry-> dot1xPaePortProtocolVersion)); break; case COLUMN_DOT1XPAEPORTCAPABILITIES: table_entry->dot1xPaePortCapabilities = 2; snmp_set_var_typed_value(request->requestvb, ASN_BIT_STR, (u_char *)&(table_entry-> dot1xPaePortCapabilities), sizeof(table_entry-> dot1xPaePortCapabilities)); break; case COLUMN_DOT1XPAEPORTINITIALIZE: table_entry->dot1xPaePortInitialize = 3; snmp_set_var_typed_value(request->requestvb, ASN_INTEGER, (u_char *)&(table_entry-> dot1xPaePortInitialize), sizeof(table_entry-> dot1xPaePortInitialize)); break; case COLUMN_DOT1XPAEPORTREAUTHENTICATE: table_entry->dot1xPaePortReauthenticate = 4; snmp_set_var_typed_value(request->requestvb, ASN_INTEGER, (u_char *)&(table_entry-> dot1xPaePortReauthenticate), sizeof(table_entry-> dot1xPaePortReauthenticate)); break; } } break; /* * Write-support */ case MODE_SET_RESERVE1: #if 0 for (request = requests; request; request = request->next) { table_entry = (struct dot1xPaePortTable_entry *) netsnmp_extract_iterator_context(request); table_info = netsnmp_extract_table_info(request); switch (table_info->colnum) { case COLUMN_DOT1XPAEPORTINITIALIZE: if (request->requestvb->type != ASN_INTEGER) { netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGTYPE); return SNMP_ERR_WRONGTYPE; } /* * Also may need to check size/value */ break; case COLUMN_DOT1XPAEPORTREAUTHENTICATE: if (request->requestvb->type != ASN_INTEGER) { netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGTYPE); return SNMP_ERR_WRONGTYPE; } /* * Also may need to check size/value */ break; default: netsnmp_set_request_error(reqinfo, request, SNMP_ERR_NOTWRITABLE); return SNMP_ERR_NOTWRITABLE; } } #endif break; case MODE_SET_RESERVE2: break; case MODE_SET_FREE: break; case MODE_SET_ACTION: #if 0 for (request = requests; request; request = request->next) { table_entry = (struct dot1xPaePortTable_entry *) netsnmp_extract_iterator_context(request); table_info = netsnmp_extract_table_info(request); switch (table_info->colnum) { case COLUMN_DOT1XPAEPORTINITIALIZE: /* * Need to save old 'table_entry->dot1xPaePortInitialize' value. * May need to use 'memcpy' */ table_entry->old_dot1xPaePortInitialize = table_entry->dot1xPaePortInitialize; table_entry->dot1xPaePortInitialize = request->requestvb->val.integer; break; case COLUMN_DOT1XPAEPORTREAUTHENTICATE: /* * Need to save old 'table_entry->dot1xPaePortReauthenticate' * value. * May need to use 'memcpy' */ table_entry->old_dot1xPaePortReauthenticate = table_entry->dot1xPaePortReauthenticate; table_entry->dot1xPaePortReauthenticate = request->requestvb->val.integer; break; } } #endif break; case MODE_SET_UNDO: #if 0 for (request = requests; request; request = request->next) { table_entry = (struct dot1xPaePortTable_entry *) netsnmp_extract_iterator_context(request); table_info = netsnmp_extract_table_info(request); switch (table_info->colnum) { case COLUMN_DOT1XPAEPORTINITIALIZE: /* * Need to restore old 'table_entry->dot1xPaePortInitialize' * value. * May need to use 'memcpy' */ table_entry->dot1xPaePortInitialize = table_entry->old_dot1xPaePortInitialize; break; case COLUMN_DOT1XPAEPORTREAUTHENTICATE: /* * Need to restore old 'table_entry->dot1xPaePortReauthenticate' * value. * May need to use 'memcpy' */ table_entry->dot1xPaePortReauthenticate = table_entry->old_dot1xPaePortReauthenticate; break; } } #endif break; case MODE_SET_COMMIT: break; } return SNMP_ERR_NOERROR; } "snmpwalk" OUTPUT ================= iso.0.8802.1.1.1.1.1.2.1.2.1 = Gauge32: 11 iso.0.8802.1.1.1.1.1.2.1.2.2 = Gauge32: 21 iso.0.8802.1.1.1.1.1.2.1.2.3 = Gauge32: 31 ------------------------------------------------------------------------- This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/ _______________________________________________ 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