csnmp_read_table: Change GETNEXT request behaviour (+ bugfix 235)
authorjkrabbe <jkrabbe@rot13.de>
Tue, 26 Mar 2013 14:25:02 +0000 (15:25 +0100)
committerFlorian Forster <octo@collectd.org>
Fri, 29 Mar 2013 13:44:09 +0000 (06:44 -0700)
commit080f01b95a5f6006438e2ffee6ae3d093263d148
treea2845e2b11dca47d52a1b44ec4563e084777f828
parente0552af6e56d23a027b9fdb226ee6d8217dcb36a
csnmp_read_table: Change GETNEXT request behaviour (+ bugfix 235)

This patch changes the snmp GETNEXT request behaviour implemented in snmp.c.

The old implementation requested all OIDs using GETNEXT requests until all OIDs
left their own subtree. In cases were trees in a Data template are much longer
than other trees the shorter subtrees were re-requested over and over again.

The new implementation will only request OIDs that did not already leave their
subtrees (see the oid_todo_list implementation for details). This renders the
function csnmp_check_res_left_subtree useless as the oid_todo_list keeps track
if all OIDs have finished.

During tests against Cat6500 (CatOS/IOS) as well as Nexus5k (NX-OS) it looks as
though GETNEXT requests (when requesting multiple OIDs like all 14 dot3Stats
errors from Etherlike-MIB) can take about 5-10ms (CatOS 30ms) longer if they wrap
to the next OID.

This does not sound much but when collecting data for the Etherlike-MIB (that only
has entries for physical interfaces) with a collectd "Instance" variable in IF-MIB
(that has entries for all physical as well as pseudo [SVIs, VLANs, ...] interfaces)
this can make a notable difference (e.g. for core routers that have all SVIs and
VLANs but only some switches attached):

IOS-Core-Router   ifName                 550 entries
                  dot3StatsFCSErrors      70 entries
                                        ------------
                                         480 entries * 10ms =  4.8s overhead

CatOS-Access-Sw.  ifName                 840 entries
                  dot3StatsFCSErrors     490 entries
                                        ------------
                                         350 entries * 30ms = 10.5s overhead

After refactoring csnmp_read_table "Instance" and "Value" OIDs are now handled
consistently (so no pointer-forward foo needed). It doesn't change any logic
and data structures, though - so there should not be any impact to other
functions.

The refactored code also fixes GitHub bugs #235 and #258. This bug is due to
reusing the status variable in following code section which might lead to errors
if the subtrees are of different length:

1436    /* Calculate the current suffix. This is later used to check that the
1437     * suffix is increasing. This also checks if we left the subtree */
1438    status = csnmp_oid_suffix (&suffix, &vb_name, data->values + i);

Signed-off-by: Florian Forster <octo@collectd.org>
src/snmp.c