|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* DisMan Event MIB:
|
|
Packit |
fcad23 |
* Core implementation of the trigger handling behaviour
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#include <net-snmp/net-snmp-config.h>
|
|
Packit |
fcad23 |
#include <net-snmp/net-snmp-features.h>
|
|
Packit |
fcad23 |
#include <net-snmp/net-snmp-includes.h>
|
|
Packit |
fcad23 |
#include <net-snmp/agent/net-snmp-agent-includes.h>
|
|
Packit |
fcad23 |
#include "agent_global_vars.h"
|
|
Packit |
fcad23 |
#include "disman/event/mteTrigger.h"
|
|
Packit |
fcad23 |
#include "disman/event/mteEvent.h"
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
netsnmp_feature_child_of(disman_debugging, libnetsnmpmibs)
|
|
Packit |
fcad23 |
netsnmp_feature_child_of(mtetrigger, libnetsnmpmibs)
|
|
Packit |
fcad23 |
netsnmp_feature_child_of(mtetrigger_removeentry, mtetrigger)
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
netsnmp_tdata *trigger_table_data;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
oid _sysUpTime_instance[] = { 1, 3, 6, 1, 2, 1, 1, 3, 0 };
|
|
Packit |
fcad23 |
size_t _sysUpTime_inst_len = OID_LENGTH(_sysUpTime_instance);
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
long mteTriggerFailures;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Initialize the container for the (combined) mteTrigger*Table,
|
|
Packit |
fcad23 |
* regardless of which table initialisation routine is called first.
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
void
|
|
Packit |
fcad23 |
init_trigger_table_data(void)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
DEBUGMSGTL(("disman:event:init", "init trigger container\n"));
|
|
Packit |
fcad23 |
if (!trigger_table_data) {
|
|
Packit |
fcad23 |
trigger_table_data = netsnmp_tdata_create_table("mteTriggerTable", 0);
|
|
Packit |
fcad23 |
if (!trigger_table_data) {
|
|
Packit |
fcad23 |
snmp_log(LOG_ERR, "failed to create mteTriggerTable");
|
|
Packit |
fcad23 |
return;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
DEBUGMSGTL(("disman:event:init", "create trigger container (%p)\n",
|
|
Packit |
fcad23 |
trigger_table_data));
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
mteTriggerFailures = 0;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/** Initializes the mteTrigger module */
|
|
Packit |
fcad23 |
void
|
|
Packit |
fcad23 |
init_mteTrigger(void)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
init_trigger_table_data();
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/* ===================================================
|
|
Packit |
fcad23 |
*
|
|
Packit |
fcad23 |
* APIs for maintaining the contents of the (combined)
|
|
Packit |
fcad23 |
* mteTrigger*Table container.
|
|
Packit |
fcad23 |
*
|
|
Packit |
fcad23 |
* =================================================== */
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#ifndef NETSNMP_FEATURE_REMOVE_DISMAN_DEBUGGING
|
|
Packit |
fcad23 |
void
|
|
Packit |
fcad23 |
_mteTrigger_dump(void)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
struct mteTrigger *entry;
|
|
Packit |
fcad23 |
netsnmp_tdata_row *row;
|
|
Packit |
fcad23 |
int i = 0;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
for (row = netsnmp_tdata_row_first(trigger_table_data);
|
|
Packit |
fcad23 |
row;
|
|
Packit |
fcad23 |
row = netsnmp_tdata_row_next(trigger_table_data, row)) {
|
|
Packit |
fcad23 |
entry = (struct mteTrigger *)row->data;
|
|
Packit |
fcad23 |
DEBUGMSGTL(("disman:event:dump", "TriggerTable entry %d: ", i));
|
|
Packit |
fcad23 |
DEBUGMSGOID(("disman:event:dump", row->oid_index.oids, row->oid_index.len));
|
|
Packit |
fcad23 |
DEBUGMSG(("disman:event:dump", "(%s, %s)",
|
|
Packit |
fcad23 |
row->indexes->val.string,
|
|
Packit |
fcad23 |
row->indexes->next_variable->val.string));
|
|
Packit |
fcad23 |
DEBUGMSG(("disman:event:dump", ": %p, %p\n", row, entry));
|
|
Packit |
fcad23 |
i++;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
DEBUGMSGTL(("disman:event:dump", "TriggerTable %d entries\n", i));
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
#endif /* NETSNMP_FEATURE_REMOVE_DISMAN_DEBUGGING */
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Create a new row in the trigger table
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
netsnmp_tdata_row *
|
|
Packit |
fcad23 |
mteTrigger_createEntry(const char *mteOwner, char *mteTName, int fixed)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
struct mteTrigger *entry;
|
|
Packit |
fcad23 |
netsnmp_tdata_row *row;
|
|
Packit |
fcad23 |
size_t mteOwner_len = (mteOwner) ? strlen(mteOwner) : 0;
|
|
Packit |
fcad23 |
size_t mteTName_len = (mteTName) ? strlen(mteTName) : 0;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
DEBUGMSGTL(("disman:event:table", "Create trigger entry (%s, %s)\n",
|
|
Packit |
fcad23 |
mteOwner, mteTName));
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Create the mteTrigger entry, and the
|
|
Packit |
fcad23 |
* (table-independent) row wrapper structure...
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
entry = SNMP_MALLOC_TYPEDEF(struct mteTrigger);
|
|
Packit |
fcad23 |
if (!entry)
|
|
Packit |
fcad23 |
return NULL;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
row = netsnmp_tdata_create_row();
|
|
Packit |
fcad23 |
if (!row) {
|
|
Packit |
fcad23 |
SNMP_FREE(entry);
|
|
Packit |
fcad23 |
return NULL;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
row->data = entry;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* ... initialize this row with the indexes supplied
|
|
Packit |
fcad23 |
* and the default values for the row...
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
if (mteOwner)
|
|
Packit |
fcad23 |
memcpy(entry->mteOwner, mteOwner, mteOwner_len);
|
|
Packit |
fcad23 |
netsnmp_table_row_add_index(row, ASN_OCTET_STR,
|
|
Packit |
fcad23 |
entry->mteOwner, mteOwner_len);
|
|
Packit |
fcad23 |
if (mteTName)
|
|
Packit |
fcad23 |
memcpy(entry->mteTName, mteTName, mteTName_len);
|
|
Packit |
fcad23 |
netsnmp_table_row_add_index(row, ASN_PRIV_IMPLIED_OCTET_STR,
|
|
Packit |
fcad23 |
entry->mteTName, mteTName_len);
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/* entry->mteTriggerTest = MTE_TRIGGER_BOOLEAN; */
|
|
Packit |
fcad23 |
entry->mteTriggerValueID_len = 2; /* .0.0 */
|
|
Packit |
fcad23 |
entry->mteTriggerFrequency = 600;
|
|
Packit |
fcad23 |
memcpy(entry->mteDeltaDiscontID, _sysUpTime_instance,
|
|
Packit |
fcad23 |
sizeof(_sysUpTime_instance));
|
|
Packit |
fcad23 |
entry->mteDeltaDiscontID_len = _sysUpTime_inst_len;
|
|
Packit |
fcad23 |
entry->mteDeltaDiscontIDType = MTE_DELTAD_TTICKS;
|
|
Packit |
fcad23 |
entry->flags |= MTE_TRIGGER_FLAG_SYSUPT;
|
|
Packit |
fcad23 |
entry->mteTExTest = (MTE_EXIST_PRESENT | MTE_EXIST_ABSENT);
|
|
Packit |
fcad23 |
entry->mteTExStartup = (MTE_EXIST_PRESENT | MTE_EXIST_ABSENT);
|
|
Packit |
fcad23 |
entry->mteTBoolComparison = MTE_BOOL_UNEQUAL;
|
|
Packit |
fcad23 |
entry->flags |= MTE_TRIGGER_FLAG_BSTART;
|
|
Packit |
fcad23 |
entry->mteTThStartup = MTE_THRESH_START_RISEFALL;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (fixed)
|
|
Packit |
fcad23 |
entry->flags |= MTE_TRIGGER_FLAG_FIXED;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* ... and insert the row into the (common) table container
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
netsnmp_tdata_add_row(trigger_table_data, row);
|
|
Packit |
fcad23 |
DEBUGMSGTL(("disman:event:table", "Trigger entry created\n"));
|
|
Packit |
fcad23 |
return row;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#ifndef NETSNMP_FEATURE_REMOVE_MTETRIGGER_REMOVEENTRY
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Remove a row from the trigger table
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
void
|
|
Packit |
fcad23 |
mteTrigger_removeEntry(netsnmp_tdata_row *row)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
struct mteTrigger *entry;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (!row)
|
|
Packit |
fcad23 |
return; /* Nothing to remove */
|
|
Packit |
fcad23 |
entry = (struct mteTrigger *)
|
|
Packit |
fcad23 |
netsnmp_tdata_remove_and_delete_row(trigger_table_data, row);
|
|
Packit |
fcad23 |
if (entry) {
|
|
Packit |
fcad23 |
mteTrigger_disable( entry );
|
|
Packit |
fcad23 |
SNMP_FREE(entry);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
#endif /* NETSNMP_FEATURE_REMOVE_MTETRIGGER_REMOVEENTRY */
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/* ===================================================
|
|
Packit |
fcad23 |
*
|
|
Packit |
fcad23 |
* APIs for evaluating a trigger,
|
|
Packit |
fcad23 |
* and firing the appropriate event
|
|
Packit |
fcad23 |
*
|
|
Packit |
fcad23 |
* =================================================== */
|
|
Packit |
fcad23 |
const char *_ops[] = { "",
|
|
Packit |
fcad23 |
"!=", /* MTE_BOOL_UNEQUAL */
|
|
Packit |
fcad23 |
"==", /* MTE_BOOL_EQUAL */
|
|
Packit |
fcad23 |
"<", /* MTE_BOOL_LESS */
|
|
Packit |
fcad23 |
"<=", /* MTE_BOOL_LESSEQUAL */
|
|
Packit |
fcad23 |
">", /* MTE_BOOL_GREATER */
|
|
Packit |
fcad23 |
">=" /* MTE_BOOL_GREATEREQUAL */ };
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
void
|
|
Packit |
fcad23 |
_mteTrigger_failure( /* int error, */ const char *msg )
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* XXX - Send an mteTriggerFailure trap
|
|
Packit |
fcad23 |
* (if configured to do so)
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
mteTriggerFailures++;
|
|
Packit |
fcad23 |
snmp_log(LOG_ERR, "%s\n", msg );
|
|
Packit |
fcad23 |
return;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
void
|
|
Packit |
fcad23 |
mteTrigger_run( unsigned int reg, void *clientarg)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
struct mteTrigger *entry = (struct mteTrigger *)clientarg;
|
|
Packit |
fcad23 |
netsnmp_variable_list *var, *vtmp;
|
|
Packit |
fcad23 |
netsnmp_variable_list *vp1, *vp1_prev;
|
|
Packit |
fcad23 |
netsnmp_variable_list *vp2, *vp2_prev;
|
|
Packit |
fcad23 |
netsnmp_variable_list *dvar = NULL;
|
|
Packit |
fcad23 |
netsnmp_variable_list *dv1 = NULL, *dv2 = NULL;
|
|
Packit |
fcad23 |
netsnmp_variable_list sysUT_var;
|
|
Packit |
fcad23 |
int cmp = 0, n, n2;
|
|
Packit |
fcad23 |
long value;
|
|
Packit |
fcad23 |
const char *reason;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (!entry) {
|
|
Packit |
fcad23 |
snmp_alarm_unregister( reg );
|
|
Packit |
fcad23 |
return;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
if (!(entry->flags & MTE_TRIGGER_FLAG_ENABLED ) ||
|
|
Packit |
fcad23 |
!(entry->flags & MTE_TRIGGER_FLAG_ACTIVE ) ||
|
|
Packit |
fcad23 |
!(entry->flags & MTE_TRIGGER_FLAG_VALID )) {
|
|
Packit |
fcad23 |
return;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
if (netsnmp_processing_set) {
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* netsnmp_handle_request will not be responsive to our efforts to
|
|
Packit |
fcad23 |
* Retrieve the requested MIB value(s)...
|
|
Packit |
fcad23 |
* so we will skip it.
|
|
Packit |
fcad23 |
* https://sourceforge.net/tracker/
|
|
Packit |
fcad23 |
* index.php?func=detail&aid=1557406&group_id=12694&atid=112694
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
DEBUGMSGTL(("disman:event:trigger:monitor",
|
|
Packit |
fcad23 |
"Skipping trigger (%s) while netsnmp_processing_set\n",
|
|
Packit |
fcad23 |
entry->mteTName));
|
|
Packit |
fcad23 |
return;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Retrieve the requested MIB value(s)...
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
DEBUGMSGTL(( "disman:event:trigger:monitor", "Running trigger (%s)\n", entry->mteTName));
|
|
Packit |
fcad23 |
var = (netsnmp_variable_list *)SNMP_MALLOC_TYPEDEF( netsnmp_variable_list );
|
|
Packit |
fcad23 |
if (!var) {
|
|
Packit |
fcad23 |
_mteTrigger_failure("failed to create mteTrigger query varbind");
|
|
Packit |
fcad23 |
return;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
snmp_set_var_objid( var, entry->mteTriggerValueID,
|
|
Packit |
fcad23 |
entry->mteTriggerValueID_len );
|
|
Packit |
fcad23 |
if ( entry->flags & MTE_TRIGGER_FLAG_VWILD ) {
|
|
Packit |
fcad23 |
n = netsnmp_query_walk( var, entry->session );
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
n = netsnmp_query_get( var, entry->session );
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
if ( n != SNMP_ERR_NOERROR ) {
|
|
Packit |
fcad23 |
DEBUGMSGTL(( "disman:event:trigger:monitor", "Trigger query (%s) failed: %d\n",
|
|
Packit |
fcad23 |
(( entry->flags & MTE_TRIGGER_FLAG_VWILD ) ? "walk" : "get"), n));
|
|
Packit |
fcad23 |
_mteTrigger_failure( "failed to run mteTrigger query" );
|
|
Packit |
fcad23 |
snmp_free_varbind(var);
|
|
Packit |
fcad23 |
return;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* ... canonicalise the results (to simplify later comparisons)...
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
vp1 = var; vp1_prev = NULL;
|
|
Packit |
fcad23 |
vp2 = entry->old_results; vp2_prev = NULL;
|
|
Packit |
fcad23 |
entry->count=0;
|
|
Packit |
fcad23 |
while (vp1) {
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Flatten various missing values/exceptions into a single form
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
switch (vp1->type) {
|
|
Packit |
fcad23 |
case SNMP_NOSUCHINSTANCE:
|
|
Packit |
fcad23 |
case SNMP_NOSUCHOBJECT:
|
|
Packit |
fcad23 |
case ASN_PRIV_RETRY: /* Internal only ? */
|
|
Packit |
fcad23 |
vp1->type = ASN_NULL;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Keep track of how many entries have been retrieved.
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
entry->count++;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Ensure previous and current result match
|
|
Packit |
fcad23 |
* (with corresponding entries in both lists)
|
|
Packit |
fcad23 |
* and set the flags indicating which triggers are armed
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
if (vp2) {
|
|
Packit |
fcad23 |
cmp = snmp_oid_compare(vp1->name, vp1->name_length,
|
|
Packit |
fcad23 |
vp2->name, vp2->name_length);
|
|
Packit |
fcad23 |
if ( cmp < 0 ) {
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* If a new value has appeared, insert a matching
|
|
Packit |
fcad23 |
* dummy entry into the previous result list.
|
|
Packit |
fcad23 |
*
|
|
Packit |
fcad23 |
* XXX - check how this is best done.
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
vtmp = SNMP_MALLOC_TYPEDEF( netsnmp_variable_list );
|
|
Packit |
fcad23 |
if (!vtmp) {
|
|
Packit |
fcad23 |
_mteTrigger_failure(
|
|
Packit |
fcad23 |
"failed to create mteTrigger temp varbind");
|
|
Packit |
fcad23 |
snmp_free_varbind(var);
|
|
Packit |
fcad23 |
return;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
vtmp->type = ASN_NULL;
|
|
Packit |
fcad23 |
snmp_set_var_objid( vtmp, vp1->name, vp1->name_length );
|
|
Packit |
fcad23 |
vtmp->next_variable = vp2;
|
|
Packit |
fcad23 |
if (vp2_prev) {
|
|
Packit |
fcad23 |
vp2_prev->next_variable = vtmp;
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
entry->old_results = vtmp;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
vp2_prev = vtmp;
|
|
Packit |
fcad23 |
vp1->index = MTE_ARMED_ALL; /* XXX - plus a new flag */
|
|
Packit |
fcad23 |
vp1_prev = vp1;
|
|
Packit |
fcad23 |
vp1 = vp1->next_variable;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
else if ( cmp == 0 ) {
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* If it's a continuing entry, just copy across the armed flags
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
vp1->index = vp2->index;
|
|
Packit |
fcad23 |
vp1_prev = vp1;
|
|
Packit |
fcad23 |
vp1 = vp1->next_variable;
|
|
Packit |
fcad23 |
vp2_prev = vp2;
|
|
Packit |
fcad23 |
vp2 = vp2->next_variable;
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* If a value has just disappeared, insert a
|
|
Packit |
fcad23 |
* matching dummy entry into the current result list.
|
|
Packit |
fcad23 |
*
|
|
Packit |
fcad23 |
* XXX - check how this is best done.
|
|
Packit |
fcad23 |
*
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
if ( vp2->type != ASN_NULL ) {
|
|
Packit |
fcad23 |
vtmp = SNMP_MALLOC_TYPEDEF( netsnmp_variable_list );
|
|
Packit |
fcad23 |
if (!vtmp) {
|
|
Packit |
fcad23 |
_mteTrigger_failure(
|
|
Packit |
fcad23 |
"failed to create mteTrigger temp varbind");
|
|
Packit |
fcad23 |
snmp_free_varbind(var);
|
|
Packit |
fcad23 |
return;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
vtmp->type = ASN_NULL;
|
|
Packit |
fcad23 |
snmp_set_var_objid( vtmp, vp2->name, vp2->name_length );
|
|
Packit |
fcad23 |
vtmp->next_variable = vp1;
|
|
Packit |
fcad23 |
if (vp1_prev) {
|
|
Packit |
fcad23 |
vp1_prev->next_variable = vtmp;
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
var = vtmp;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
vp1_prev = vtmp;
|
|
Packit |
fcad23 |
vp2_prev = vp2;
|
|
Packit |
fcad23 |
vp2 = vp2->next_variable;
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* But only if this entry has *just* disappeared. If the
|
|
Packit |
fcad23 |
* entry from the last run was a dummy too, then remove it.
|
|
Packit |
fcad23 |
* (leaving vp2_prev unchanged)
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
vtmp = vp2;
|
|
Packit |
fcad23 |
if (vp2_prev) {
|
|
Packit |
fcad23 |
vp2_prev->next_variable = vp2->next_variable;
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
entry->old_results = vp2->next_variable;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
vp2 = vp2->next_variable;
|
|
Packit |
fcad23 |
vtmp->next_variable = NULL;
|
|
Packit |
fcad23 |
snmp_free_varbind( vtmp );
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* No more old results to compare.
|
|
Packit |
fcad23 |
* Either all remaining values have only just been created ...
|
|
Packit |
fcad23 |
* (and we need to create dummy 'old' entries for them)
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
if ( vp2_prev ) {
|
|
Packit |
fcad23 |
vtmp = SNMP_MALLOC_TYPEDEF( netsnmp_variable_list );
|
|
Packit |
fcad23 |
if (!vtmp) {
|
|
Packit |
fcad23 |
_mteTrigger_failure(
|
|
Packit |
fcad23 |
"failed to create mteTrigger temp varbind");
|
|
Packit |
fcad23 |
snmp_free_varbind(var);
|
|
Packit |
fcad23 |
return;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
vtmp->type = ASN_NULL;
|
|
Packit |
fcad23 |
snmp_set_var_objid( vtmp, vp1->name, vp1->name_length );
|
|
Packit |
fcad23 |
vtmp->next_variable = vp2_prev->next_variable;
|
|
Packit |
fcad23 |
vp2_prev->next_variable = vtmp;
|
|
Packit |
fcad23 |
vp2_prev = vtmp;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* ... or this is the first run through
|
|
Packit |
fcad23 |
* (and there were no old results at all)
|
|
Packit |
fcad23 |
*
|
|
Packit |
fcad23 |
* In either case, mark the current entry as armed and new.
|
|
Packit |
fcad23 |
* Note that we no longer need to maintain 'vp1_prev'
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
vp1->index = MTE_ARMED_ALL; /* XXX - plus a new flag */
|
|
Packit |
fcad23 |
vp1 = vp1->next_variable;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* ... and then work through these result(s), deciding
|
|
Packit |
fcad23 |
* whether or not to trigger the corresponding event.
|
|
Packit |
fcad23 |
*
|
|
Packit |
fcad23 |
* Note that there's no point in evaluating Existence or
|
|
Packit |
fcad23 |
* Boolean tests if there's no corresponding event.
|
|
Packit |
fcad23 |
* (Even if the trigger matched, nothing would be done anyway).
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
if ((entry->mteTriggerTest & MTE_TRIGGER_EXISTENCE) &&
|
|
Packit |
fcad23 |
(entry->mteTExEvent[0] != '\0' )) {
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* If we don't have a record of previous results,
|
|
Packit |
fcad23 |
* this must be the first time through, so consider
|
|
Packit |
fcad23 |
* the mteTriggerExistenceStartup tests.
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
if ( !entry->old_results ) {
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* With the 'present(0)' test, the trigger should fire
|
|
Packit |
fcad23 |
* for each value in the varbind list returned
|
|
Packit |
fcad23 |
* (whether the monitored value is wildcarded or not).
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
if (entry->mteTExTest & entry->mteTExStartup & MTE_EXIST_PRESENT) {
|
|
Packit |
fcad23 |
for (vp1 = var; vp1; vp1=vp1->next_variable) {
|
|
Packit |
fcad23 |
DEBUGMSGTL(( "disman:event:trigger:fire",
|
|
Packit |
fcad23 |
"Firing initial existence test: "));
|
|
Packit |
fcad23 |
DEBUGMSGOID(("disman:event:trigger:fire",
|
|
Packit |
fcad23 |
vp1->name, vp1->name_length));
|
|
Packit |
fcad23 |
DEBUGMSG(( "disman:event:trigger:fire",
|
|
Packit |
fcad23 |
" (present)\n"));
|
|
Packit |
fcad23 |
entry->mteTriggerXOwner = entry->mteTExObjOwner;
|
|
Packit |
fcad23 |
entry->mteTriggerXObjects = entry->mteTExObjects;
|
|
Packit |
fcad23 |
entry->mteTriggerFired = vp1;
|
|
Packit |
fcad23 |
n = entry->mteTriggerValueID_len;
|
|
Packit |
fcad23 |
mteEvent_fire(entry->mteTExEvOwner, entry->mteTExEvent,
|
|
Packit |
fcad23 |
entry, vp1->name+n, vp1->name_length-n);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* An initial 'absent(1)' test only makes sense when
|
|
Packit |
fcad23 |
* monitoring a non-wildcarded OID (how would we know
|
|
Packit |
fcad23 |
* which rows of the table "ought" to exist, but don't?)
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
if (entry->mteTExTest & entry->mteTExStartup & MTE_EXIST_ABSENT) {
|
|
Packit |
fcad23 |
if (!(entry->flags & MTE_TRIGGER_FLAG_VWILD) &&
|
|
Packit |
fcad23 |
var->type == ASN_NULL ) {
|
|
Packit |
fcad23 |
DEBUGMSGTL(( "disman:event:trigger:fire",
|
|
Packit |
fcad23 |
"Firing initial existence test: "));
|
|
Packit |
fcad23 |
DEBUGMSGOID(("disman:event:trigger:fire",
|
|
Packit |
fcad23 |
var->name, var->name_length));
|
|
Packit |
fcad23 |
DEBUGMSG(( "disman:event:trigger:fire",
|
|
Packit |
fcad23 |
" (absent)\n"));
|
|
Packit |
fcad23 |
entry->mteTriggerXOwner = entry->mteTExObjOwner;
|
|
Packit |
fcad23 |
entry->mteTriggerXObjects = entry->mteTExObjects;
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* It's unclear what value the 'mteHotValue' payload
|
|
Packit |
fcad23 |
* should take when a monitored instance does not
|
|
Packit |
fcad23 |
* exist on startup. The only sensible option is
|
|
Packit |
fcad23 |
* to report a NULL value, but this clashes with
|
|
Packit |
fcad23 |
* the syntax of the mteHotValue MIB object.
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
entry->mteTriggerFired = var;
|
|
Packit |
fcad23 |
n = entry->mteTriggerValueID_len;
|
|
Packit |
fcad23 |
mteEvent_fire(entry->mteTExEvOwner, entry->mteTExEvent,
|
|
Packit |
fcad23 |
entry, var->name+n, var->name_length-n);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
} /* !old_results */
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Otherwise, compare the current set of results with
|
|
Packit |
fcad23 |
* the previous ones, looking for changes. We can
|
|
Packit |
fcad23 |
* assume that the two lists match (see above).
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
else {
|
|
Packit |
fcad23 |
for (vp1 = var, vp2 = entry->old_results;
|
|
Packit |
fcad23 |
vp1;
|
|
Packit |
fcad23 |
vp1=vp1->next_variable, vp2=vp2->next_variable) {
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/* Use this field to indicate that the trigger should fire */
|
|
Packit |
fcad23 |
entry->mteTriggerFired = NULL;
|
|
Packit |
fcad23 |
reason = NULL;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if ((entry->mteTExTest & MTE_EXIST_PRESENT) &&
|
|
Packit |
fcad23 |
(vp1->type != ASN_NULL) &&
|
|
Packit |
fcad23 |
(vp2->type == ASN_NULL)) {
|
|
Packit |
fcad23 |
/* A new instance has appeared */
|
|
Packit |
fcad23 |
entry->mteTriggerFired = vp1;
|
|
Packit |
fcad23 |
reason = "(present)";
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
} else if ((entry->mteTExTest & MTE_EXIST_ABSENT) &&
|
|
Packit |
fcad23 |
(vp1->type == ASN_NULL) &&
|
|
Packit |
fcad23 |
(vp2->type != ASN_NULL)) {
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* A previous instance has disappeared.
|
|
Packit |
fcad23 |
*
|
|
Packit |
fcad23 |
* It's unclear what value the 'mteHotValue' payload
|
|
Packit |
fcad23 |
* should take when this happens - the previous
|
|
Packit |
fcad23 |
* value (vp2), or a NULL value (vp1) ?
|
|
Packit |
fcad23 |
* NULL makes more sense logically, but clashes
|
|
Packit |
fcad23 |
* with the syntax of the mteHotValue MIB object.
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
entry->mteTriggerFired = vp2;
|
|
Packit |
fcad23 |
reason = "(absent)";
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
} else if ((entry->mteTExTest & MTE_EXIST_CHANGED) &&
|
|
Packit |
fcad23 |
((vp1->val_len != vp2->val_len) ||
|
|
Packit |
fcad23 |
(memcmp( vp1->val.string, vp2->val.string,
|
|
Packit |
fcad23 |
vp1->val_len) != 0 ))) {
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* This comparison detects changes in *any* type
|
|
Packit |
fcad23 |
* of value, numeric or string (or even OID).
|
|
Packit |
fcad23 |
*
|
|
Packit |
fcad23 |
* Unfortunately, the default 'mteTriggerFired'
|
|
Packit |
fcad23 |
* notification payload can't report non-numeric
|
|
Packit |
fcad23 |
* changes properly (see syntax of 'mteHotValue')
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
entry->mteTriggerFired = vp1;
|
|
Packit |
fcad23 |
reason = "(changed)";
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
if ( entry->mteTriggerFired ) {
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* One of the above tests has matched,
|
|
Packit |
fcad23 |
* so fire the trigger.
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
DEBUGMSGTL(( "disman:event:trigger:fire",
|
|
Packit |
fcad23 |
"Firing existence test: "));
|
|
Packit |
fcad23 |
DEBUGMSGOID(("disman:event:trigger:fire",
|
|
Packit |
fcad23 |
vp1->name, vp1->name_length));
|
|
Packit |
fcad23 |
DEBUGMSG(( "disman:event:trigger:fire",
|
|
Packit |
fcad23 |
" %s\n", reason));
|
|
Packit |
fcad23 |
entry->mteTriggerXOwner = entry->mteTExObjOwner;
|
|
Packit |
fcad23 |
entry->mteTriggerXObjects = entry->mteTExObjects;
|
|
Packit |
fcad23 |
n = entry->mteTriggerValueID_len;
|
|
Packit |
fcad23 |
mteEvent_fire(entry->mteTExEvOwner, entry->mteTExEvent,
|
|
Packit |
fcad23 |
entry, vp1->name+n, vp1->name_length-n);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
} /* !old_results - end of else block */
|
|
Packit |
fcad23 |
} /* MTE_TRIGGER_EXISTENCE */
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* We'll need sysUpTime.0 regardless...
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
DEBUGMSGTL(("disman:event:delta", "retrieve sysUpTime.0\n"));
|
|
Packit |
fcad23 |
memset( &sysUT_var, 0, sizeof( netsnmp_variable_list ));
|
|
Packit |
fcad23 |
snmp_set_var_objid( &sysUT_var, _sysUpTime_instance, _sysUpTime_inst_len );
|
|
Packit |
fcad23 |
netsnmp_query_get( &sysUT_var, entry->session );
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (( entry->mteTriggerTest & MTE_TRIGGER_BOOLEAN ) ||
|
|
Packit |
fcad23 |
( entry->mteTriggerTest & MTE_TRIGGER_THRESHOLD )) {
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Although Existence tests can work with any syntax values,
|
|
Packit |
fcad23 |
* Boolean and Threshold tests are integer-only. Ensure that
|
|
Packit |
fcad23 |
* the returned value(s) are appropriate.
|
|
Packit |
fcad23 |
*
|
|
Packit |
fcad23 |
* Note that we only need to check the first value, since all
|
|
Packit |
fcad23 |
* instances of a given object should have the same syntax.
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
switch (var->type) {
|
|
Packit |
fcad23 |
case ASN_INTEGER:
|
|
Packit |
fcad23 |
case ASN_COUNTER:
|
|
Packit |
fcad23 |
case ASN_GAUGE:
|
|
Packit |
fcad23 |
case ASN_TIMETICKS:
|
|
Packit |
fcad23 |
case ASN_UINTEGER:
|
|
Packit |
fcad23 |
case ASN_COUNTER64:
|
|
Packit |
fcad23 |
#ifdef NETSNMP_WITH_OPAQUE_SPECIAL_TYPES
|
|
Packit |
fcad23 |
case ASN_OPAQUE_COUNTER64:
|
|
Packit |
fcad23 |
case ASN_OPAQUE_U64:
|
|
Packit |
fcad23 |
case ASN_OPAQUE_I64:
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
/* OK */
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
default:
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Other syntax values can't be used for Boolean/Theshold
|
|
Packit |
fcad23 |
* tests. Report this as an error, and then rotate the
|
|
Packit |
fcad23 |
* results ready for the next run, (which will presumably
|
|
Packit |
fcad23 |
* also detect this as an error once again!)
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
DEBUGMSGTL(( "disman:event:trigger:fire",
|
|
Packit |
fcad23 |
"Returned non-integer result(s): "));
|
|
Packit |
fcad23 |
DEBUGMSGOID(("disman:event:trigger:fire",
|
|
Packit |
fcad23 |
var->name, var->name_length));
|
|
Packit |
fcad23 |
DEBUGMSG(( "disman:event:trigger:fire",
|
|
Packit |
fcad23 |
" (boolean/threshold) %d\n", var->type));
|
|
Packit |
fcad23 |
snmp_free_varbind( entry->old_results );
|
|
Packit |
fcad23 |
entry->old_results = var;
|
|
Packit |
fcad23 |
return;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Retrieve the discontinuity markers for delta-valued samples.
|
|
Packit |
fcad23 |
* (including sysUpTime.0 if not specified explicitly).
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
if ( entry->flags & MTE_TRIGGER_FLAG_DELTA ) {
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (!(entry->flags & MTE_TRIGGER_FLAG_SYSUPT)) {
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* ... but only retrieve the configured discontinuity
|
|
Packit |
fcad23 |
* marker(s) if they refer to something different.
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
DEBUGMSGTL(( "disman:event:delta",
|
|
Packit |
fcad23 |
"retrieve discontinuity marker(s): "));
|
|
Packit |
fcad23 |
DEBUGMSGOID(("disman:event:delta", entry->mteDeltaDiscontID,
|
|
Packit |
fcad23 |
entry->mteDeltaDiscontID_len ));
|
|
Packit |
fcad23 |
DEBUGMSG(( "disman:event:delta", " %s\n",
|
|
Packit |
fcad23 |
(entry->flags & MTE_TRIGGER_FLAG_DWILD ? " (wild)" : "")));
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
dvar = (netsnmp_variable_list *)
|
|
Packit |
fcad23 |
SNMP_MALLOC_TYPEDEF( netsnmp_variable_list );
|
|
Packit |
fcad23 |
if (!dvar) {
|
|
Packit |
fcad23 |
_mteTrigger_failure(
|
|
Packit |
fcad23 |
"failed to create mteTrigger delta query varbind");
|
|
Packit |
fcad23 |
return;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
snmp_set_var_objid( dvar, entry->mteDeltaDiscontID,
|
|
Packit |
fcad23 |
entry->mteDeltaDiscontID_len );
|
|
Packit |
fcad23 |
if ( entry->flags & MTE_TRIGGER_FLAG_DWILD ) {
|
|
Packit |
fcad23 |
n = netsnmp_query_walk( dvar, entry->session );
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
n = netsnmp_query_get( dvar, entry->session );
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
if ( n != SNMP_ERR_NOERROR ) {
|
|
Packit |
fcad23 |
_mteTrigger_failure( "failed to run mteTrigger delta query" );
|
|
Packit |
fcad23 |
snmp_free_varbind( dvar );
|
|
Packit |
fcad23 |
return;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* We can't calculate delta values the first time through,
|
|
Packit |
fcad23 |
* so there's no point in evaluating the remaining tests.
|
|
Packit |
fcad23 |
*
|
|
Packit |
fcad23 |
* Save the results (and discontinuity markers),
|
|
Packit |
fcad23 |
* ready for the next run.
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
if ( !entry->old_results ) {
|
|
Packit |
fcad23 |
entry->old_results = var;
|
|
Packit |
fcad23 |
entry->old_deltaDs = dvar;
|
|
Packit |
fcad23 |
entry->sysUpTime = *sysUT_var.val.integer;
|
|
Packit |
fcad23 |
return;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* If the sysUpTime marker has been reset (or strictly,
|
|
Packit |
fcad23 |
* has advanced by less than the monitor frequency),
|
|
Packit |
fcad23 |
* there's no point in trying the remaining tests.
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (*sysUT_var.val.integer < entry->sysUpTime) {
|
|
Packit |
fcad23 |
DEBUGMSGTL(( "disman:event:delta",
|
|
Packit |
fcad23 |
"single discontinuity: (sysUT)\n"));
|
|
Packit |
fcad23 |
snmp_free_varbind( entry->old_results );
|
|
Packit |
fcad23 |
snmp_free_varbind( entry->old_deltaDs );
|
|
Packit |
fcad23 |
entry->old_results = var;
|
|
Packit |
fcad23 |
entry->old_deltaDs = dvar;
|
|
Packit |
fcad23 |
entry->sysUpTime = *sysUT_var.val.integer;
|
|
Packit |
fcad23 |
return;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Similarly if a separate (non-wildcarded) discontinuity
|
|
Packit |
fcad23 |
* marker has changed, then there's no
|
|
Packit |
fcad23 |
* point in trying to evaluate these tests either.
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
if (!(entry->flags & MTE_TRIGGER_FLAG_DWILD) &&
|
|
Packit |
fcad23 |
!(entry->flags & MTE_TRIGGER_FLAG_SYSUPT) &&
|
|
Packit |
fcad23 |
(!entry->old_deltaDs ||
|
|
Packit |
fcad23 |
(entry->old_deltaDs->val.integer != dvar->val.integer))) {
|
|
Packit |
fcad23 |
DEBUGMSGTL(( "disman:event:delta", "single discontinuity: ("));
|
|
Packit |
fcad23 |
DEBUGMSGOID(( "disman:event:delta", entry->mteDeltaDiscontID,
|
|
Packit |
fcad23 |
entry->mteDeltaDiscontID_len));
|
|
Packit |
fcad23 |
DEBUGMSG(( "disman:event:delta", ")\n"));
|
|
Packit |
fcad23 |
snmp_free_varbind( entry->old_results );
|
|
Packit |
fcad23 |
snmp_free_varbind( entry->old_deltaDs );
|
|
Packit |
fcad23 |
entry->old_results = var;
|
|
Packit |
fcad23 |
entry->old_deltaDs = dvar;
|
|
Packit |
fcad23 |
entry->sysUpTime = *sysUT_var.val.integer;
|
|
Packit |
fcad23 |
return;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Ensure that the list of (wildcarded) discontinuity
|
|
Packit |
fcad23 |
* markers matches the list of monitored values
|
|
Packit |
fcad23 |
* (inserting/removing discontinuity varbinds as needed)
|
|
Packit |
fcad23 |
*
|
|
Packit |
fcad23 |
* XXX - An alternative approach would be to use the list
|
|
Packit |
fcad23 |
* of monitored values (instance subidentifiers) to build
|
|
Packit |
fcad23 |
* the exact list of delta markers to retrieve earlier.
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
if (entry->flags & MTE_TRIGGER_FLAG_DWILD) {
|
|
Packit |
fcad23 |
vp1 = var;
|
|
Packit |
fcad23 |
vp2 = dvar;
|
|
Packit |
fcad23 |
vp2_prev = NULL;
|
|
Packit |
fcad23 |
n = entry->mteTriggerValueID_len;
|
|
Packit |
fcad23 |
n2 = entry->mteDeltaDiscontID_len;
|
|
Packit |
fcad23 |
while (vp1) {
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* For each monitored instance, check whether
|
|
Packit |
fcad23 |
* there's a matching discontinuity entry.
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
cmp = snmp_oid_compare(vp1->name+n, vp1->name_length-n,
|
|
Packit |
fcad23 |
vp2->name+n2, vp2->name_length-n2 );
|
|
Packit |
fcad23 |
if ( cmp < 0 ) {
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* If a discontinuity entry is missing,
|
|
Packit |
fcad23 |
* insert a (dummy) varbind.
|
|
Packit |
fcad23 |
* The corresponding delta calculation will
|
|
Packit |
fcad23 |
* fail, but this simplifies the later code.
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
vtmp = (netsnmp_variable_list *)
|
|
Packit |
fcad23 |
SNMP_MALLOC_TYPEDEF( netsnmp_variable_list );
|
|
Packit |
fcad23 |
if (!vtmp) {
|
|
Packit |
fcad23 |
_mteTrigger_failure(
|
|
Packit |
fcad23 |
"failed to create mteTrigger discontinuity varbind");
|
|
Packit |
fcad23 |
snmp_free_varbind(dvar);
|
|
Packit |
fcad23 |
return;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
snmp_set_var_objid(vtmp, entry->mteDeltaDiscontID,
|
|
Packit |
fcad23 |
entry->mteDeltaDiscontID_len);
|
|
Packit |
fcad23 |
/* XXX - append instance subids */
|
|
Packit |
fcad23 |
vtmp->next_variable = vp2;
|
|
Packit |
fcad23 |
vp2_prev->next_variable = vtmp;
|
|
Packit |
fcad23 |
vp2_prev = vtmp;
|
|
Packit |
fcad23 |
vp1 = vp1->next_variable;
|
|
Packit |
fcad23 |
} else if ( cmp == 0 ) {
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Matching discontinuity entry - all OK.
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
vp2_prev = vp2;
|
|
Packit |
fcad23 |
vp2 = vp2->next_variable;
|
|
Packit |
fcad23 |
vp1 = vp1->next_variable;
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Remove unneeded discontinuity entry
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
vtmp = vp2;
|
|
Packit |
fcad23 |
vp2_prev->next_variable = vp2->next_variable;
|
|
Packit |
fcad23 |
vp2 = vp2->next_variable;
|
|
Packit |
fcad23 |
vtmp->next_variable = NULL;
|
|
Packit |
fcad23 |
snmp_free_varbind( vtmp );
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* XXX - Now need to ensure that the old list of
|
|
Packit |
fcad23 |
* delta discontinuity markers matches as well.
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
} /* delta samples */
|
|
Packit |
fcad23 |
} /* Boolean/Threshold test checks */
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Only run the Boolean tests if there's an event to be triggered
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
if ((entry->mteTriggerTest & MTE_TRIGGER_BOOLEAN) &&
|
|
Packit |
fcad23 |
(entry->mteTBoolEvent[0] != '\0' )) {
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (entry->flags & MTE_TRIGGER_FLAG_DELTA) {
|
|
Packit |
fcad23 |
vp2 = entry->old_results;
|
|
Packit |
fcad23 |
if (entry->flags & MTE_TRIGGER_FLAG_DWILD) {
|
|
Packit |
fcad23 |
dv1 = dvar;
|
|
Packit |
fcad23 |
dv2 = entry->old_deltaDs;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
for ( vp1 = var; vp1; vp1=vp1->next_variable ) {
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Determine the value to be monitored...
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
if ( !vp1->val.integer ) { /* No value */
|
|
Packit |
fcad23 |
if ( vp2 )
|
|
Packit |
fcad23 |
vp2 = vp2->next_variable;
|
|
Packit |
fcad23 |
continue;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
if (entry->flags & MTE_TRIGGER_FLAG_DELTA) {
|
|
Packit |
fcad23 |
if (entry->flags & MTE_TRIGGER_FLAG_DWILD) {
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* We've already checked any non-wildcarded
|
|
Packit |
fcad23 |
* discontinuity markers (inc. sysUpTime.0).
|
|
Packit |
fcad23 |
* Validate this particular sample against
|
|
Packit |
fcad23 |
* the relevant wildcarded marker...
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
if ((dv1->type == ASN_NULL) ||
|
|
Packit |
fcad23 |
(dv1->type != dv2->type) ||
|
|
Packit |
fcad23 |
(*dv1->val.integer != *dv2->val.integer)) {
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Bogus or changed discontinuity marker.
|
|
Packit |
fcad23 |
* Need to skip this sample.
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
DEBUGMSGTL(( "disman:event:delta", "discontinuity occurred: "));
|
|
Packit |
fcad23 |
DEBUGMSGOID(("disman:event:delta", vp1->name,
|
|
Packit |
fcad23 |
vp1->name_length ));
|
|
Packit |
fcad23 |
DEBUGMSG(( "disman:event:delta", " \n" ));
|
|
Packit |
fcad23 |
vp2 = vp2->next_variable;
|
|
Packit |
fcad23 |
continue;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* ... and check there is a previous sample to calculate
|
|
Packit |
fcad23 |
* the delta value against (regardless of whether the
|
|
Packit |
fcad23 |
* discontinuity marker was wildcarded or not).
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
if (vp2->type == ASN_NULL) {
|
|
Packit |
fcad23 |
DEBUGMSGTL(( "disman:event:delta", "missing sample: "));
|
|
Packit |
fcad23 |
DEBUGMSGOID(("disman:event:delta", vp1->name,
|
|
Packit |
fcad23 |
vp1->name_length ));
|
|
Packit |
fcad23 |
DEBUGMSG(( "disman:event:delta", " \n" ));
|
|
Packit |
fcad23 |
vp2 = vp2->next_variable;
|
|
Packit |
fcad23 |
continue;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
value = (*vp1->val.integer - *vp2->val.integer);
|
|
Packit |
fcad23 |
DEBUGMSGTL(( "disman:event:delta", "delta sample: "));
|
|
Packit |
fcad23 |
DEBUGMSGOID(("disman:event:delta", vp1->name,
|
|
Packit |
fcad23 |
vp1->name_length ));
|
|
Packit |
fcad23 |
DEBUGMSG(( "disman:event:delta", " (%ld - %ld) = %ld\n",
|
|
Packit |
fcad23 |
*vp1->val.integer, *vp2->val.integer, value));
|
|
Packit |
fcad23 |
vp2 = vp2->next_variable;
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
value = *vp1->val.integer;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* ... evaluate the comparison ...
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
switch (entry->mteTBoolComparison) {
|
|
Packit |
fcad23 |
case MTE_BOOL_UNEQUAL:
|
|
Packit |
fcad23 |
cmp = ( value != entry->mteTBoolValue );
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
case MTE_BOOL_EQUAL:
|
|
Packit |
fcad23 |
cmp = ( value == entry->mteTBoolValue );
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
case MTE_BOOL_LESS:
|
|
Packit |
fcad23 |
cmp = ( value < entry->mteTBoolValue );
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
case MTE_BOOL_LESSEQUAL:
|
|
Packit |
fcad23 |
cmp = ( value <= entry->mteTBoolValue );
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
case MTE_BOOL_GREATER:
|
|
Packit |
fcad23 |
cmp = ( value > entry->mteTBoolValue );
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
case MTE_BOOL_GREATEREQUAL:
|
|
Packit |
fcad23 |
cmp = ( value >= entry->mteTBoolValue );
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
DEBUGMSGTL(( "disman:event:delta", "Bool comparison: (%ld %s %ld) %d\n",
|
|
Packit |
fcad23 |
value, _ops[entry->mteTBoolComparison],
|
|
Packit |
fcad23 |
entry->mteTBoolValue, cmp));
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* ... and decide whether to trigger the event.
|
|
Packit |
fcad23 |
* (using the 'index' field of the varbind structure
|
|
Packit |
fcad23 |
* to remember whether the trigger has already fired)
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
if ( cmp ) {
|
|
Packit |
fcad23 |
if (vp1->index & MTE_ARMED_BOOLEAN ) {
|
|
Packit |
fcad23 |
vp1->index &= ~MTE_ARMED_BOOLEAN;
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* NB: Clear the trigger armed flag even if the
|
|
Packit |
fcad23 |
* (starting) event dosn't actually fire.
|
|
Packit |
fcad23 |
* Otherwise initially true (but suppressed)
|
|
Packit |
fcad23 |
* triggers will fire on the *second* probe.
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
if ( entry->old_results ||
|
|
Packit |
fcad23 |
(entry->flags & MTE_TRIGGER_FLAG_BSTART)) {
|
|
Packit |
fcad23 |
DEBUGMSGTL(( "disman:event:trigger:fire",
|
|
Packit |
fcad23 |
"Firing boolean test: "));
|
|
Packit |
fcad23 |
DEBUGMSGOID(("disman:event:trigger:fire",
|
|
Packit |
fcad23 |
vp1->name, vp1->name_length));
|
|
Packit |
fcad23 |
DEBUGMSG(( "disman:event:trigger:fire", "%s\n",
|
|
Packit |
fcad23 |
(entry->old_results ? "" : " (startup)")));
|
|
Packit |
fcad23 |
entry->mteTriggerXOwner = entry->mteTBoolObjOwner;
|
|
Packit |
fcad23 |
entry->mteTriggerXObjects = entry->mteTBoolObjects;
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* XXX - when firing a delta-based trigger, should
|
|
Packit |
fcad23 |
* 'mteHotValue' report the actual value sampled
|
|
Packit |
fcad23 |
* (as here), or the delta that triggered the event ?
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
entry->mteTriggerFired = vp1;
|
|
Packit |
fcad23 |
n = entry->mteTriggerValueID_len;
|
|
Packit |
fcad23 |
mteEvent_fire(entry->mteTBoolEvOwner, entry->mteTBoolEvent,
|
|
Packit |
fcad23 |
entry, vp1->name+n, vp1->name_length-n);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
vp1->index |= MTE_ARMED_BOOLEAN;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Only run the basic threshold tests if there's an event to
|
|
Packit |
fcad23 |
* be triggered. (Either rising or falling will do)
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
if (( entry->mteTriggerTest & MTE_TRIGGER_THRESHOLD ) &&
|
|
Packit |
fcad23 |
((entry->mteTThRiseEvent[0] != '\0' ) ||
|
|
Packit |
fcad23 |
(entry->mteTThFallEvent[0] != '\0' ))) {
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* The same delta-sample validation from Boolean
|
|
Packit |
fcad23 |
* tests also applies here too.
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
if (entry->flags & MTE_TRIGGER_FLAG_DELTA) {
|
|
Packit |
fcad23 |
vp2 = entry->old_results;
|
|
Packit |
fcad23 |
if (entry->flags & MTE_TRIGGER_FLAG_DWILD) {
|
|
Packit |
fcad23 |
dv1 = dvar;
|
|
Packit |
fcad23 |
dv2 = entry->old_deltaDs;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
for ( vp1 = var; vp1; vp1=vp1->next_variable ) {
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Determine the value to be monitored...
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
if ( !vp1->val.integer ) { /* No value */
|
|
Packit |
fcad23 |
if ( vp2 )
|
|
Packit |
fcad23 |
vp2 = vp2->next_variable;
|
|
Packit |
fcad23 |
continue;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
if (entry->flags & MTE_TRIGGER_FLAG_DELTA) {
|
|
Packit |
fcad23 |
if (entry->flags & MTE_TRIGGER_FLAG_DWILD) {
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* We've already checked any non-wildcarded
|
|
Packit |
fcad23 |
* discontinuity markers (inc. sysUpTime.0).
|
|
Packit |
fcad23 |
* Validate this particular sample against
|
|
Packit |
fcad23 |
* the relevant wildcarded marker...
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
if ((dv1->type == ASN_NULL) ||
|
|
Packit |
fcad23 |
(dv1->type != dv2->type) ||
|
|
Packit |
fcad23 |
(*dv1->val.integer != *dv2->val.integer)) {
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Bogus or changed discontinuity marker.
|
|
Packit |
fcad23 |
* Need to skip this sample.
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
vp2 = vp2->next_variable;
|
|
Packit |
fcad23 |
continue;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* ... and check there is a previous sample to calculate
|
|
Packit |
fcad23 |
* the delta value against (regardless of whether the
|
|
Packit |
fcad23 |
* discontinuity marker was wildcarded or not).
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
if (vp2->type == ASN_NULL) {
|
|
Packit |
fcad23 |
vp2 = vp2->next_variable;
|
|
Packit |
fcad23 |
continue;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
value = (*vp1->val.integer - *vp2->val.integer);
|
|
Packit |
fcad23 |
vp2 = vp2->next_variable;
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
value = *vp1->val.integer;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* ... evaluate the single-value comparisons,
|
|
Packit |
fcad23 |
* and decide whether to trigger the event.
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
cmp = vp1->index; /* working copy of 'armed' flags */
|
|
Packit |
fcad23 |
if ( value >= entry->mteTThRiseValue ) {
|
|
Packit |
fcad23 |
if (cmp & MTE_ARMED_TH_RISE ) {
|
|
Packit |
fcad23 |
cmp &= ~MTE_ARMED_TH_RISE;
|
|
Packit |
fcad23 |
cmp |= MTE_ARMED_TH_FALL;
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* NB: Clear the trigger armed flag even if the
|
|
Packit |
fcad23 |
* (starting) event dosn't actually fire.
|
|
Packit |
fcad23 |
* Otherwise initially true (but suppressed)
|
|
Packit |
fcad23 |
* triggers will fire on the *second* probe.
|
|
Packit |
fcad23 |
* Similarly for falling thresholds (see below).
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
if ( entry->old_results ||
|
|
Packit |
fcad23 |
(entry->mteTThStartup & MTE_THRESH_START_RISE)) {
|
|
Packit |
fcad23 |
DEBUGMSGTL(( "disman:event:trigger:fire",
|
|
Packit |
fcad23 |
"Firing rising threshold test: "));
|
|
Packit |
fcad23 |
DEBUGMSGOID(("disman:event:trigger:fire",
|
|
Packit |
fcad23 |
vp1->name, vp1->name_length));
|
|
Packit |
fcad23 |
DEBUGMSG(( "disman:event:trigger:fire", "%s\n",
|
|
Packit |
fcad23 |
(entry->old_results ? "" : " (startup)")));
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* If no riseEvent is configured, we need still to
|
|
Packit |
fcad23 |
* set the armed flags appropriately, but there's
|
|
Packit |
fcad23 |
* no point in trying to fire the (missing) event.
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
if (entry->mteTThRiseEvent[0] != '\0' ) {
|
|
Packit |
fcad23 |
entry->mteTriggerXOwner = entry->mteTThObjOwner;
|
|
Packit |
fcad23 |
entry->mteTriggerXObjects = entry->mteTThObjects;
|
|
Packit |
fcad23 |
entry->mteTriggerFired = vp1;
|
|
Packit |
fcad23 |
n = entry->mteTriggerValueID_len;
|
|
Packit |
fcad23 |
mteEvent_fire(entry->mteTThRiseOwner,
|
|
Packit |
fcad23 |
entry->mteTThRiseEvent,
|
|
Packit |
fcad23 |
entry, vp1->name+n, vp1->name_length-n);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if ( value <= entry->mteTThFallValue ) {
|
|
Packit |
fcad23 |
if (cmp & MTE_ARMED_TH_FALL ) {
|
|
Packit |
fcad23 |
cmp &= ~MTE_ARMED_TH_FALL;
|
|
Packit |
fcad23 |
cmp |= MTE_ARMED_TH_RISE;
|
|
Packit |
fcad23 |
/* Clear the trigger armed flag (see above) */
|
|
Packit |
fcad23 |
if ( entry->old_results ||
|
|
Packit |
fcad23 |
(entry->mteTThStartup & MTE_THRESH_START_FALL)) {
|
|
Packit |
fcad23 |
DEBUGMSGTL(( "disman:event:trigger:fire",
|
|
Packit |
fcad23 |
"Firing falling threshold test: "));
|
|
Packit |
fcad23 |
DEBUGMSGOID(("disman:event:trigger:fire",
|
|
Packit |
fcad23 |
vp1->name, vp1->name_length));
|
|
Packit |
fcad23 |
DEBUGMSG(( "disman:event:trigger:fire", "%s\n",
|
|
Packit |
fcad23 |
(entry->old_results ? "" : " (startup)")));
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Similarly, if no fallEvent is configured,
|
|
Packit |
fcad23 |
* there's no point in trying to fire it either.
|
|
Packit |
fcad23 |
*/
|
|
Packit |
74c279 |
if (entry->mteTThFallEvent[0] != '\0' ) {
|
|
Packit |
fcad23 |
entry->mteTriggerXOwner = entry->mteTThObjOwner;
|
|
Packit |
fcad23 |
entry->mteTriggerXObjects = entry->mteTThObjects;
|
|
Packit |
fcad23 |
entry->mteTriggerFired = vp1;
|
|
Packit |
fcad23 |
n = entry->mteTriggerValueID_len;
|
|
Packit |
fcad23 |
mteEvent_fire(entry->mteTThFallOwner,
|
|
Packit |
fcad23 |
entry->mteTThFallEvent,
|
|
Packit |
fcad23 |
entry, vp1->name+n, vp1->name_length-n);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
vp1->index = cmp;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* The same processing also works for delta-threshold tests (if configured)
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
if (( entry->mteTriggerTest & MTE_TRIGGER_THRESHOLD ) &&
|
|
Packit |
fcad23 |
((entry->mteTThDRiseEvent[0] != '\0' ) ||
|
|
Packit |
fcad23 |
(entry->mteTThDFallEvent[0] != '\0' ))) {
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Delta-threshold tests can only be used with
|
|
Packit |
fcad23 |
* absolute valued samples.
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
vp2 = entry->old_results;
|
|
Packit |
fcad23 |
if (entry->flags & MTE_TRIGGER_FLAG_DELTA) {
|
|
Packit |
fcad23 |
DEBUGMSGTL(( "disman:event:trigger",
|
|
Packit |
fcad23 |
"Delta-threshold on delta-sample\n"));
|
|
Packit |
fcad23 |
} else if ( vp2 != NULL ) {
|
|
Packit |
fcad23 |
for ( vp1 = var; vp1; vp1=vp1->next_variable ) {
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Determine the value to be monitored...
|
|
Packit |
fcad23 |
* (similar to previous delta-sample processing,
|
|
Packit |
fcad23 |
* but without the discontinuity marker checks)
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
if (!vp2) {
|
|
Packit |
fcad23 |
break; /* Run out of 'old' values */
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
if (( !vp1->val.integer ) ||
|
|
Packit |
fcad23 |
(vp2->type == ASN_NULL)) {
|
|
Packit |
fcad23 |
vp2 = vp2->next_variable;
|
|
Packit |
fcad23 |
continue;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
value = (*vp1->val.integer - *vp2->val.integer);
|
|
Packit |
fcad23 |
vp2 = vp2->next_variable;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* ... evaluate the single-value comparisons,
|
|
Packit |
fcad23 |
* and decide whether to trigger the event.
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
cmp = vp1->index; /* working copy of 'armed' flags */
|
|
Packit |
fcad23 |
if ( value >= entry->mteTThDRiseValue ) {
|
|
Packit |
fcad23 |
if (vp1->index & MTE_ARMED_TH_DRISE ) {
|
|
Packit |
fcad23 |
DEBUGMSGTL(( "disman:event:trigger:fire",
|
|
Packit |
fcad23 |
"Firing rising delta threshold test: "));
|
|
Packit |
fcad23 |
DEBUGMSGOID(("disman:event:trigger:fire",
|
|
Packit |
fcad23 |
vp1->name, vp1->name_length));
|
|
Packit |
fcad23 |
DEBUGMSG(( "disman:event:trigger:fire", "\n"));
|
|
Packit |
fcad23 |
cmp &= ~MTE_ARMED_TH_DRISE;
|
|
Packit |
fcad23 |
cmp |= MTE_ARMED_TH_DFALL;
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* If no riseEvent is configured, we need still to
|
|
Packit |
fcad23 |
* set the armed flags appropriately, but there's
|
|
Packit |
fcad23 |
* no point in trying to fire the (missing) event.
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
if (entry->mteTThDRiseEvent[0] != '\0' ) {
|
|
Packit |
fcad23 |
entry->mteTriggerXOwner = entry->mteTThObjOwner;
|
|
Packit |
fcad23 |
entry->mteTriggerXObjects = entry->mteTThObjects;
|
|
Packit |
fcad23 |
entry->mteTriggerFired = vp1;
|
|
Packit |
fcad23 |
n = entry->mteTriggerValueID_len;
|
|
Packit |
fcad23 |
mteEvent_fire(entry->mteTThDRiseOwner,
|
|
Packit |
fcad23 |
entry->mteTThDRiseEvent,
|
|
Packit |
fcad23 |
entry, vp1->name+n, vp1->name_length-n);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if ( value <= entry->mteTThDFallValue ) {
|
|
Packit |
fcad23 |
if (vp1->index & MTE_ARMED_TH_DFALL ) {
|
|
Packit |
fcad23 |
DEBUGMSGTL(( "disman:event:trigger:fire",
|
|
Packit |
fcad23 |
"Firing falling delta threshold test: "));
|
|
Packit |
fcad23 |
DEBUGMSGOID(("disman:event:trigger:fire",
|
|
Packit |
fcad23 |
vp1->name, vp1->name_length));
|
|
Packit |
fcad23 |
DEBUGMSG(( "disman:event:trigger:fire", "\n"));
|
|
Packit |
fcad23 |
cmp &= ~MTE_ARMED_TH_DFALL;
|
|
Packit |
fcad23 |
cmp |= MTE_ARMED_TH_DRISE;
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Similarly, if no fallEvent is configured,
|
|
Packit |
fcad23 |
* there's no point in trying to fire it either.
|
|
Packit |
fcad23 |
*/
|
|
Packit |
74c279 |
if (entry->mteTThDFallEvent[0] != '\0' ) {
|
|
Packit |
fcad23 |
entry->mteTriggerXOwner = entry->mteTThObjOwner;
|
|
Packit |
fcad23 |
entry->mteTriggerXObjects = entry->mteTThObjects;
|
|
Packit |
fcad23 |
entry->mteTriggerFired = vp1;
|
|
Packit |
fcad23 |
n = entry->mteTriggerValueID_len;
|
|
Packit |
fcad23 |
mteEvent_fire(entry->mteTThDFallOwner,
|
|
Packit |
fcad23 |
entry->mteTThDFallEvent,
|
|
Packit |
fcad23 |
entry, vp1->name+n, vp1->name_length-n);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
vp1->index = cmp;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Finally, rotate the results - ready for the next run.
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
snmp_free_varbind( entry->old_results );
|
|
Packit |
fcad23 |
entry->old_results = var;
|
|
Packit |
fcad23 |
if ( entry->flags & MTE_TRIGGER_FLAG_DELTA ) {
|
|
Packit |
fcad23 |
snmp_free_varbind( entry->old_deltaDs );
|
|
Packit |
fcad23 |
entry->old_deltaDs = dvar;
|
|
Packit |
fcad23 |
entry->sysUpTime = *sysUT_var.val.integer;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
void
|
|
Packit |
fcad23 |
mteTrigger_enable( struct mteTrigger *entry )
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
if (!entry)
|
|
Packit |
fcad23 |
return;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (entry->alarm) {
|
|
Packit |
fcad23 |
/* XXX - or explicitly call mteTrigger_disable ?? */
|
|
Packit |
fcad23 |
snmp_alarm_unregister( entry->alarm );
|
|
Packit |
fcad23 |
entry->alarm = 0;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (entry->mteTriggerFrequency) {
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* register once to run ASAP, and another to run
|
|
Packit |
fcad23 |
* at the trigger frequency
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
snmp_alarm_register(0, 0, mteTrigger_run, entry );
|
|
Packit |
fcad23 |
entry->alarm = snmp_alarm_register(
|
|
Packit |
fcad23 |
entry->mteTriggerFrequency, SA_REPEAT,
|
|
Packit |
fcad23 |
mteTrigger_run, entry );
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
void
|
|
Packit |
fcad23 |
mteTrigger_disable( struct mteTrigger *entry )
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
if (!entry)
|
|
Packit |
fcad23 |
return;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (entry->alarm) {
|
|
Packit |
fcad23 |
snmp_alarm_unregister( entry->alarm );
|
|
Packit |
fcad23 |
entry->alarm = 0;
|
|
Packit |
fcad23 |
/* XXX - perhaps release any previous results */
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
long _mteTrigger_MaxCount = 0;
|
|
Packit |
fcad23 |
long _mteTrigger_countEntries(void)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
struct mteTrigger *entry;
|
|
Packit |
fcad23 |
netsnmp_tdata_row *row;
|
|
Packit |
fcad23 |
long count = 0;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
for (row = netsnmp_tdata_row_first(trigger_table_data);
|
|
Packit |
fcad23 |
row;
|
|
Packit |
fcad23 |
row = netsnmp_tdata_row_next(trigger_table_data, row)) {
|
|
Packit |
fcad23 |
entry = (struct mteTrigger *)row->data;
|
|
Packit |
fcad23 |
count += entry->count;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
return count;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
long mteTrigger_getNumEntries(int max)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
long count;
|
|
Packit |
fcad23 |
/* XXX - implement some form of caching ??? */
|
|
Packit |
fcad23 |
count = _mteTrigger_countEntries();
|
|
Packit |
fcad23 |
if ( count > _mteTrigger_MaxCount )
|
|
Packit |
fcad23 |
_mteTrigger_MaxCount = count;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
return ( max ? _mteTrigger_MaxCount : count);
|
|
Packit |
fcad23 |
}
|