Good Morning Dave,
Thanks for your most excellent suggestion (and code review), the change becomes
a bit more complicated as the container from the ifTable iterates over the row
context not the netsnmp_interface_entry structure. However, each row context
has
a data pointer to a present netsnmp_interface_entry structure. In addition, I
had to re-organize some of the headers b/c of the inclusion of ifTable.h.
The patch below works for me on both X86 and ARM platforms. With the
appropriate
-D tokens, I can verify appropriate behavior and that the abusive behavior is
gone.
Cheers,
- Eivind
--- /tmp/tmp.8255.83 2011-02-11 19:56:08.000000000 -0800
+++
/work/enaess/neptune-mainline/tps/net-snmp/5.6.1/mainline/src/agent/mibgroup/if-mib/data_access/interface.c
2011-02-11 16:11:45.000000000 -0800
@@ -5,14 +5,14 @@
*/
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
-#include "mibII/mibII_common.h"
-#include "if-mib/ifTable/ifTable_constants.h"
-#include "if-mib/data_access/interface.h"
-
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include <net-snmp/library/snmp_enum.h>
#include <net-snmp/data_access/interface.h>
+#include "mibII/mibII_common.h"
+#include "if-mib/ifTable/ifTable.h"
+#include "if-mib/data_access/interface.h"
+
/**---------------------------------------------------------------------*/
/*
@@ -346,42 +346,45 @@
! defined( NETSNMP_NO_BACKWARDS_COMPATABILITY )
static netsnmp_iterator *it = NULL;
-static netsnmp_container *c = NULL;
-static netsnmp_interface_entry *e = NULL;
+static ifTable_rowreq_ctx *row = NULL;
/**
- *
+ * Setup an iterator for scanning the interfaces using the cached entry
+ * from if-mib/ifTable.
*/
void
Interface_Scan_Init(void)
{
- /*
- * ifTable container shouldn't change, so we shouldn' have to
- * re-fetch it every time.
- */
- if (NULL != c)
- netsnmp_access_interface_container_free(c, 0);
+ netsnmp_container *cont = NULL;
+ netsnmp_cache *cache = NULL;
- c = netsnmp_access_interface_container_load(NULL, 0);
+ cache = netsnmp_cache_find_by_oid(ifTable_oid, ifTable_oid_size);
+ if (NULL != cache) {
+ netsnmp_cache_check_and_reload(cache);
+ cont = (netsnmp_container*) cache->magic;
+ }
- if (NULL != c) {
+ if (NULL != cont) {
if (NULL != it)
ITERATOR_RELEASE(it);
- it = CONTAINER_ITERATOR(c);
+ it = CONTAINER_ITERATOR(cont);
}
if (NULL != it)
- e = (netsnmp_interface_entry*)ITERATOR_FIRST(it);
+ row = (ifTable_rowreq_ctx*)ITERATOR_FIRST(it);
}
int
Interface_Scan_Next(short *index, char *name, netsnmp_interface_entry **entry,
void *dc)
{
- if (NULL == e)
+ netsnmp_interface_entry* e = NULL;
+
+ if (NULL == row)
return 0;
+ e = row->data.ifentry;
if(index)
*index = e->index;
@@ -391,7 +394,7 @@
if (entry)
*entry = e;
- e = (netsnmp_interface_entry*)ITERATOR_NEXT(it);
+ row = (ifTable_rowreq_ctx*) ITERATOR_NEXT(it);
return 1;
}
----- Original Message ----
From: Dave Shield <[email protected]>
To: Eivind Naess <[email protected]>
Cc: [email protected]
Sent: Fri, February 11, 2011 9:59:09 AM
Subject: Re: Constant polling of the interface stats in if-mib
On 11 February 2011 17:37, Eivind Naess <[email protected]> wrote:
> If you pay careful attention to the Interface_Scan_Init, it will dispose of
the
> container for interface statistics and create a new container which in case
> triggers a full table re-load. Looking at the code for if-mib/ifTable, it uses
> the cache api which prevents this abuse when browsing the IF-MIB.
> I don't know of any API calls to cache a container in net-snmp. But a simple
> guard (see patch below) did prevent the condition that I am seeing and the
> snmpwalk finished without a problem. I am sure there are better ways to solve
> this, but I really hope that there's a possibility resolving this issue with
> this or an improved patch in future versions of net-snmp.
My main concern with this patch is that it completely ignores the existing
cache that is currently being used by ifTable (and _also_ by the ifXTable code).
A better approach would probably be to share the same cache here as well
(perhaps retrieving it using
netsnmp_cache_find_by_oid(ifTable_oid, ifTable_oid_size);
)
and inject this into the handler chain (as is done for ifTable/ifXTable)
That way you've got a consistent view of the interface statistics and
how quickly the cache times out.
Dave
------------------------------------------------------------------------------
The ultimate all-in-one performance toolkit: Intel(R) Parallel Studio XE:
Pinpoint memory and threading errors before they happen.
Find and fix more than 250 security defects in the development cycle.
Locate bottlenecks in serial and parallel code that limit performance.
http://p.sf.net/sfu/intel-dev2devfeb
_______________________________________________
Net-snmp-coders mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/net-snmp-coders