diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2012-02-22 14:05:09 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2012-02-22 14:05:09 +0200 |
commit | cd24fcb21c1a6f33e5154819e141cbd29edf9e55 (patch) | |
tree | fad47aa46dbeaab5dcb5c886d02fede9102d5b93 | |
parent | 6a24cb04edcc1978d18185167b5203522b078caa (diff) | |
download | slb-cd24fcb21c1a6f33e5154819e141cbd29edf9e55.tar.gz slb-cd24fcb21c1a6f33e5154819e141cbd29edf9e55.tar.bz2 |
Fix resolving of indexed variables.
* src/slb.h (SLB_SRV_DEBUG_OUTPUT): New flag.
* src/snmploop.c (process_next): Use SLB_SRV_DEBUG_OUTPUT
to suppress unnecessary debugging output.
Resolve table entries immediately after obtaining the entire
tree.
(send_requests): Clear SLB_SRV_DEBUG_OUTPUT flag before
sending the request.
(resolve_tables): Remove. All callers updated.
-rw-r--r-- | src/slb.h | 2 | ||||
-rw-r--r-- | src/snmploop.c | 249 |
2 files changed, 122 insertions, 129 deletions
@@ -373,6 +373,8 @@ struct slb_snmp_v3 { #define SLB_SRV_COMPUTED 0x02 /* Expression has been computed */ #define SLB_SRV_TAB_REFERENCED 0x04 /* Variables refer to SNMP tables */ #define SLB_SRV_TAB_RESOLVED 0x08 /* Table references resolved */ +#define SLB_SRV_DEBUG_OUTPUT 0x10 /* Suppress further debugging output + about received NEXT responses. */ struct slb_server { char *id; /* Server ID */ diff --git a/src/snmploop.c b/src/snmploop.c index 3ce638f..10c378f 100644 --- a/src/snmploop.c +++ b/src/snmploop.c @@ -388,6 +388,108 @@ oid_to_table(struct slb_server *srv, oid *oid, size_t oidlen) return clos.result; } +static int +resolve_tabref(struct slb_varinstance *vinst, struct slb_server *srv) +{ + struct slb_tabref *ref = vinst->vi_tabref; + struct grecs_txtacc *acc; + size_t i, j; + unsigned char *buf; + size_t buf_len = 256; + size_t out_len = 0; + int ovf = 0; + char *mib; + + acc = grecs_txtacc_create(); + for (i = j = 0; i < vinst->vi_wordc; i++) { + if (i) + grecs_txtacc_grow_char(acc, '.'); + if (i == ref[j].tr_idxpos) { + struct slb_idxnum *ent = + idxnum_lookupz(ref[j].tr_index->idx_table->tab_idx, + ref[j].tr_index->idx_tag, + NULL); + if (!ent) { + logmsg(LOG_NOTICE, + "%s:%d: cannot resolve %s (index %s); " + "disabling server %s", + vinst->vi_locus.beg.file, + vinst->vi_locus.beg.line, + vinst->vi_mib, + ref[j].tr_index->idx_tag, + srvid(srv)); + srv->flags |= SLB_SRV_DISABLED; + return 1; + } + grecs_txtacc_grow(acc, ent->idxnum_strval + 1, + strlen(ent->idxnum_strval + 1)); + } else { + grecs_txtacc_grow(acc, vinst->vi_wordv[i], + strlen(vinst->vi_wordv[i])); + } + } + grecs_txtacc_grow_char(acc, 0); + mib = grecs_txtacc_finish(acc, 0); + vinst->vi_oidlen = MAX_OID_LEN; + oidtab_delete(srv->oidtab, vinst); + if (!read_objid(mib, vinst->vi_oid, &vinst->vi_oidlen)) { + logmsg(LOG_NOTICE, + "%s:%d: cannot parse %s (MIB %s); " + "disabling server %s", + vinst->vi_locus.beg.file, + vinst->vi_locus.beg.line, + vinst->vi_mib, + mib, + ref[j].tr_index->idx_tag, + srvid(srv)); + grecs_txtacc_free(acc); + srv->flags |= SLB_SRV_DISABLED; + return 1; + } + + grecs_txtacc_free(acc); + + buf = grecs_malloc(buf_len); + netsnmp_sprint_realloc_objid(&buf, + &buf_len, + &out_len, 1, + &ovf, + vinst->vi_oid, + vinst->vi_oidlen); + + logmsg(LOG_INFO, + "%s:%d: (%s) %s resolved to %s", + vinst->vi_locus.beg.file, + vinst->vi_locus.beg.line, + srvid(srv), + vinst->vi_mib, + buf); + free(buf); + oidtab_install(srv->oidtab, vinst); + return 0; +} + +static int +resolve_varinst_index(void *sym, void *data) +{ + struct slb_varinstance *vinst = sym; + struct slb_server *srv = data; + + if (vinst->vi_tabref) + return resolve_tabref(vinst, srv); + return 0; +} + +#if 0 +static int +resolve_assertion_index(void *sym, void *data) +{ + struct slb_assertion *ap = sym; + struct slb_server *srv = data; + return 1;//FIXME +} +#endif + static void process_next(struct slb_server *srv, struct snmp_pdu *pdu) { @@ -396,9 +498,9 @@ process_next(struct slb_server *srv, struct snmp_pdu *pdu) size_t varcnt = 0; if (debug_level[SLB_DEBCAT_SNMP] >= 2 && - !(srv->flags & SLB_SRV_COMPUTED)) { + !(srv->flags & SLB_SRV_DEBUG_OUTPUT)) { debug_printf("%s replied", srvid(srv)); - srv->flags |= SLB_SRV_COMPUTED; + srv->flags |= SLB_SRV_DEBUG_OUTPUT; } debug(SLB_DEBCAT_SNMP, 10, ("reply from %s", srvid(srv))); @@ -419,8 +521,19 @@ process_next(struct slb_server *srv, struct snmp_pdu *pdu) if (varcnt && snmp_send(srv->sess, pdu2)) active_count++; - else + else { snmp_free_pdu(pdu2); + debug(SLB_DEBCAT_SNMP, 2, + ("%s: resolving indexed variables", srvid(srv))); + grecs_symtab_enumerate(srv->varinst, + resolve_varinst_index, + srv); +#if 0 + grecs_symtab_enumerate(srv->assertions, + resolve_assertion_index, + srv); +#endif + } } static void @@ -596,8 +709,8 @@ send_requests() add_snmp_assertion, req); } - srv->flags &= ~SLB_SRV_COMPUTED; - + srv->flags &= ~(SLB_SRV_COMPUTED|SLB_SRV_DEBUG_OUTPUT); + if (!(srv->sess = snmp_open(&sess))) { logmsg(LOG_ERR, "server %s: snmp_open failed: %s", @@ -620,127 +733,6 @@ send_requests() return refcnt; } -static int -resolve_tabref(struct slb_varinstance *vinst, struct slb_server *srv) -{ - struct slb_tabref *ref = vinst->vi_tabref; - struct grecs_txtacc *acc; - size_t i, j; - unsigned char *buf; - size_t buf_len = 256; - size_t out_len = 0; - int ovf = 0; - char *mib; - - acc = grecs_txtacc_create(); - for (i = j = 0; i < vinst->vi_wordc; i++) { - if (i) - grecs_txtacc_grow_char(acc, '.'); - if (i == ref[j].tr_idxpos) { - struct slb_idxnum *ent = - idxnum_lookupz(ref[j].tr_index->idx_table->tab_idx, - ref[j].tr_index->idx_tag, - NULL); - if (!ent) { - logmsg(LOG_NOTICE, - "%s:%d: cannot resolve %s (index %s); " - "disabling server %s", - vinst->vi_locus.beg.file, - vinst->vi_locus.beg.line, - vinst->vi_mib, - ref[j].tr_index->idx_tag, - srvid(srv)); - srv->flags |= SLB_SRV_DISABLED; - return 1; - } - grecs_txtacc_grow(acc, ent->idxnum_strval + 1, - strlen(ent->idxnum_strval + 1)); - } else { - grecs_txtacc_grow(acc, vinst->vi_wordv[i], - strlen(vinst->vi_wordv[i])); - } - } - grecs_txtacc_grow_char(acc, 0); - mib = grecs_txtacc_finish(acc, 0); - vinst->vi_oidlen = MAX_OID_LEN; - oidtab_delete(srv->oidtab, vinst); - if (!read_objid(mib, vinst->vi_oid, &vinst->vi_oidlen)) { - logmsg(LOG_NOTICE, - "%s:%d: cannot parse %s (MIB %s); " - "disabling server %s", - vinst->vi_locus.beg.file, - vinst->vi_locus.beg.line, - vinst->vi_mib, - mib, - ref[j].tr_index->idx_tag, - srvid(srv)); - grecs_txtacc_free(acc); - srv->flags |= SLB_SRV_DISABLED; - return 1; - } - - grecs_txtacc_free(acc); - - buf = grecs_malloc(buf_len); - netsnmp_sprint_realloc_objid(&buf, - &buf_len, - &out_len, 1, - &ovf, - vinst->vi_oid, - vinst->vi_oidlen); - - logmsg(LOG_INFO, - "%s:%d: (%s) %s resolved to %s", - vinst->vi_locus.beg.file, - vinst->vi_locus.beg.line, - srvid(srv), - vinst->vi_mib, - buf); - free(buf); - oidtab_install(srv->oidtab, vinst); - return 0; -} - -static int -resolve_varinst_index(void *sym, void *data) -{ - struct slb_varinstance *vinst = sym; - struct slb_server *srv = data; - - if (vinst->vi_tabref) - return resolve_tabref(vinst, srv); - return 0; -} - -#if 0 -static int -resolve_assertion_index(void *sym, void *data) -{ - struct slb_assertion *ap = sym; - struct slb_server *srv = data; - return 1;//FIXME -} -#endif - -static void -resolve_tables() -{ - struct slb_server *srv; - for (srv = srv_head; srv; srv = srv->next) { - if (srv->flags & SLB_SRV_DISABLED || - !(srv->flags & SLB_SRV_TAB_RESOLVED)) - continue; - grecs_symtab_enumerate(srv->varinst, - resolve_varinst_index, - srv); -#if 0 - grecs_symtab_enumerate(srv->assertions, - resolve_assertion_index, - srv); -#endif - } -} - static void recv_loop() { @@ -795,9 +787,10 @@ sort() if (!srvtab) srvtab = grecs_calloc(srv_count, sizeof(*srv)); - for (srv = srv_head, i = 0; srv; srv = srv->next) + for (srv = srv_head, i = 0; srv; srv = srv->next) { if (srv->flags & SLB_SRV_COMPUTED) srvtab[i++] = srv; + } srvtab_count = i; qsort(srvtab, srvtab_count, sizeof(srvtab[0]), srvcmp); @@ -823,8 +816,6 @@ snmploop() /* Process tables */ debug(SLB_DEBCAT_SNMP, 2, ("getting subtrees")); recv_loop(); - debug(SLB_DEBCAT_SNMP, 2, ("resolving indexed variables")); - resolve_tables(); send_requests(); } slb_loop_ts = time(NULL); |