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 { | |||
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 | ||
377 | struct slb_server { | 379 | struct 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 | ||
391 | static int | ||
392 | resolve_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 | |||
472 | static int | ||
473 | resolve_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 | ||
484 | static int | ||
485 | resolve_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 | |||
391 | static void | 493 | static void |
392 | process_next(struct slb_server *srv, struct snmp_pdu *pdu) | 494 | process_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 | ||
426 | static void | 539 | static 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 | ||
623 | static int | ||
624 | resolve_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, |