aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2012-02-22 14:05:09 +0200
committerSergey Poznyakoff <gray@gnu.org.ua>2012-02-22 14:05:09 +0200
commitcd24fcb21c1a6f33e5154819e141cbd29edf9e55 (patch)
treefad47aa46dbeaab5dcb5c886d02fede9102d5b93
parent6a24cb04edcc1978d18185167b5203522b078caa (diff)
downloadslb-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.h2
-rw-r--r--src/snmploop.c249
2 files changed, 122 insertions, 129 deletions
diff --git a/src/slb.h b/src/slb.h
index a2739fb..3cff6d4 100644
--- a/src/slb.h
+++ b/src/slb.h
@@ -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);

Return to:

Send suggestions and report system problems to the System administrator.