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 {
373#define SLB_SRV_COMPUTED 0x02 /* Expression has been computed */ 373#define SLB_SRV_COMPUTED 0x02 /* Expression has been computed */
374#define SLB_SRV_TAB_REFERENCED 0x04 /* Variables refer to SNMP tables */ 374#define SLB_SRV_TAB_REFERENCED 0x04 /* Variables refer to SNMP tables */
375#define SLB_SRV_TAB_RESOLVED 0x08 /* Table references resolved */ 375#define SLB_SRV_TAB_RESOLVED 0x08 /* Table references resolved */
376#define SLB_SRV_DEBUG_OUTPUT 0x10 /* Suppress further debugging output
377 about received NEXT responses. */
376 378
377struct slb_server { 379struct slb_server {
378 char *id; /* Server ID */ 380 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)
388 return clos.result; 388 return clos.result;
389} 389}
390 390
391static int
392resolve_tabref(struct slb_varinstance *vinst, struct slb_server *srv)
393{
394 struct slb_tabref *ref = vinst->vi_tabref;
395 struct grecs_txtacc *acc;
396 size_t i, j;
397 unsigned char *buf;
398 size_t buf_len = 256;
399 size_t out_len = 0;
400 int ovf = 0;
401 char *mib;
402
403 acc = grecs_txtacc_create();
404 for (i = j = 0; i < vinst->vi_wordc; i++) {
405 if (i)
406 grecs_txtacc_grow_char(acc, '.');
407 if (i == ref[j].tr_idxpos) {
408 struct slb_idxnum *ent =
409 idxnum_lookupz(ref[j].tr_index->idx_table->tab_idx,
410 ref[j].tr_index->idx_tag,
411 NULL);
412 if (!ent) {
413 logmsg(LOG_NOTICE,
414 "%s:%d: cannot resolve %s (index %s); "
415 "disabling server %s",
416 vinst->vi_locus.beg.file,
417 vinst->vi_locus.beg.line,
418 vinst->vi_mib,
419 ref[j].tr_index->idx_tag,
420 srvid(srv));
421 srv->flags |= SLB_SRV_DISABLED;
422 return 1;
423 }
424 grecs_txtacc_grow(acc, ent->idxnum_strval + 1,
425 strlen(ent->idxnum_strval + 1));
426 } else {
427 grecs_txtacc_grow(acc, vinst->vi_wordv[i],
428 strlen(vinst->vi_wordv[i]));
429 }
430 }
431 grecs_txtacc_grow_char(acc, 0);
432 mib = grecs_txtacc_finish(acc, 0);
433 vinst->vi_oidlen = MAX_OID_LEN;
434 oidtab_delete(srv->oidtab, vinst);
435 if (!read_objid(mib, vinst->vi_oid, &vinst->vi_oidlen)) {
436 logmsg(LOG_NOTICE,
437 "%s:%d: cannot parse %s (MIB %s); "
438 "disabling server %s",
439 vinst->vi_locus.beg.file,
440 vinst->vi_locus.beg.line,
441 vinst->vi_mib,
442 mib,
443 ref[j].tr_index->idx_tag,
444 srvid(srv));
445 grecs_txtacc_free(acc);
446 srv->flags |= SLB_SRV_DISABLED;
447 return 1;
448 }
449
450 grecs_txtacc_free(acc);
451
452 buf = grecs_malloc(buf_len);
453 netsnmp_sprint_realloc_objid(&buf,
454 &buf_len,
455 &out_len, 1,
456 &ovf,
457 vinst->vi_oid,
458 vinst->vi_oidlen);
459
460 logmsg(LOG_INFO,
461 "%s:%d: (%s) %s resolved to %s",
462 vinst->vi_locus.beg.file,
463 vinst->vi_locus.beg.line,
464 srvid(srv),
465 vinst->vi_mib,
466 buf);
467 free(buf);
468 oidtab_install(srv->oidtab, vinst);
469 return 0;
470}
471
472static int
473resolve_varinst_index(void *sym, void *data)
474{
475 struct slb_varinstance *vinst = sym;
476 struct slb_server *srv = data;
477
478 if (vinst->vi_tabref)
479 return resolve_tabref(vinst, srv);
480 return 0;
481}
482
483#if 0
484static int
485resolve_assertion_index(void *sym, void *data)
486{
487 struct slb_assertion *ap = sym;
488 struct slb_server *srv = data;
489 return 1;//FIXME
490}
491#endif
492
391static void 493static void
392process_next(struct slb_server *srv, struct snmp_pdu *pdu) 494process_next(struct slb_server *srv, struct snmp_pdu *pdu)
393{ 495{
@@ -396,9 +498,9 @@ process_next(struct slb_server *srv, struct snmp_pdu *pdu)
396 size_t varcnt = 0; 498 size_t varcnt = 0;
397 499
398 if (debug_level[SLB_DEBCAT_SNMP] >= 2 && 500 if (debug_level[SLB_DEBCAT_SNMP] >= 2 &&
399 !(srv->flags & SLB_SRV_COMPUTED)) { 501 !(srv->flags & SLB_SRV_DEBUG_OUTPUT)) {
400 debug_printf("%s replied", srvid(srv)); 502 debug_printf("%s replied", srvid(srv));
401 srv->flags |= SLB_SRV_COMPUTED; 503 srv->flags |= SLB_SRV_DEBUG_OUTPUT;
402 } 504 }
403 debug(SLB_DEBCAT_SNMP, 10, ("reply from %s", srvid(srv))); 505 debug(SLB_DEBCAT_SNMP, 10, ("reply from %s", srvid(srv)));
404 506
@@ -419,8 +521,19 @@ process_next(struct slb_server *srv, struct snmp_pdu *pdu)
419 521
420 if (varcnt && snmp_send(srv->sess, pdu2)) 522 if (varcnt && snmp_send(srv->sess, pdu2))
421 active_count++; 523 active_count++;
422 else 524 else {
423 snmp_free_pdu(pdu2); 525 snmp_free_pdu(pdu2);
526 debug(SLB_DEBCAT_SNMP, 2,
527 ("%s: resolving indexed variables", srvid(srv)));
528 grecs_symtab_enumerate(srv->varinst,
529 resolve_varinst_index,
530 srv);
531#if 0
532 grecs_symtab_enumerate(srv->assertions,
533 resolve_assertion_index,
534 srv);
535#endif
536 }
424} 537}
425 538
426static void 539static void
@@ -596,8 +709,8 @@ send_requests()
596 add_snmp_assertion, 709 add_snmp_assertion,
597 req); 710 req);
598 } 711 }
599 srv->flags &= ~SLB_SRV_COMPUTED; 712 srv->flags &= ~(SLB_SRV_COMPUTED|SLB_SRV_DEBUG_OUTPUT);
600 713
601 if (!(srv->sess = snmp_open(&sess))) { 714 if (!(srv->sess = snmp_open(&sess))) {
602 logmsg(LOG_ERR, 715 logmsg(LOG_ERR,
603 "server %s: snmp_open failed: %s", 716 "server %s: snmp_open failed: %s",
@@ -620,127 +733,6 @@ send_requests()
620 return refcnt; 733 return refcnt;
621} 734}
622 735
623static int
624resolve_tabref(struct slb_varinstance *vinst, struct slb_server *srv)
625{
626 struct slb_tabref *ref = vinst->vi_tabref;
627 struct grecs_txtacc *acc;
628 size_t i, j;
629 unsigned char *buf;
630 size_t buf_len = 256;
631 size_t out_len = 0;
632 int ovf = 0;
633 char *mib;
634
635 acc = grecs_txtacc_create();
636 for (i = j = 0; i < vinst->vi_wordc; i++) {
637 if (i)
638 grecs_txtacc_grow_char(acc, '.');
639 if (i == ref[j].tr_idxpos) {
640 struct slb_idxnum *ent =
641 idxnum_lookupz(ref[j].tr_index->idx_table->tab_idx,
642 ref[j].tr_index->idx_tag,
643 NULL);
644 if (!ent) {
645 logmsg(LOG_NOTICE,
646 "%s:%d: cannot resolve %s (index %s); "
647 "disabling server %s",
648 vinst->vi_locus.beg.file,
649 vinst->vi_locus.beg.line,
650 vinst->vi_mib,
651 ref[j].tr_index->idx_tag,
652 srvid(srv));
653 srv->flags |= SLB_SRV_DISABLED;
654 return 1;
655 }
656 grecs_txtacc_grow(acc, ent->idxnum_strval + 1,
657 strlen(ent->idxnum_strval + 1));
658 } else {
659 grecs_txtacc_grow(acc, vinst->vi_wordv[i],
660 strlen(vinst->vi_wordv[i]));
661 }
662 }
663 grecs_txtacc_grow_char(acc, 0);
664 mib = grecs_txtacc_finish(acc, 0);
665 vinst->vi_oidlen = MAX_OID_LEN;
666 oidtab_delete(srv->oidtab, vinst);
667 if (!read_objid(mib, vinst->vi_oid, &vinst->vi_oidlen)) {
668 logmsg(LOG_NOTICE,
669 "%s:%d: cannot parse %s (MIB %s); "
670 "disabling server %s",
671 vinst->vi_locus.beg.file,
672 vinst->vi_locus.beg.line,
673 vinst->vi_mib,
674 mib,
675 ref[j].tr_index->idx_tag,</