Solaris System Management Agent Developer's Guide

Chapter 5 Implementing Alarms

This chapter explains how to implement alarms in modules. The demo_module_4 is used to illustrate techniques.

The chapter contains the following topics:

Refresh Intervals

Refresh intervals, also known as automatic refresh, can be implemented in the System Management Agent. You can use a callback mechanism that calls a specified function at regular intervals. Data refresh can be implemented by the snmp_alarm_register() function. In demo_module_4, the load data is refreshed at a configurable time interval, 60 seconds in this example, using the following callback:

snmp_alarm_register(60, SA_REPEAT, refreshLoadAvg, NULL);

void refreshLoadAvg(unsigned int clientreg, void *clientarg){

	// Refresh the load data here

}

The snmp_alarm_register() function can be included in the init_()module() function so that the refresh interval is set during the initialization of the module.

Asynchronous Trap Notification

Typically, checking for trap conditions is done in the following sequence:

  1. Get current data for a particular node.

  2. Compare the data with a threshold to check if the trap condition is met.

  3. Send a trap to the manager if the condition is met.

Steps 2 and 3 are implemented in SMA by calling an algorithm after data for a node is acquired. The algorithm determines if an alarm condition is met. The algorithm in most cases involves comparing the current data with the threshold. If the algorithm indicates that an alarm condition is met, the appropriate trap functions are called to issue a trap. In demo_module_4, steps 2 and 3 are performed in the following function:

void refreshLoadAvg(unsigned int clientreg, void *clientarg) { 

    // Refresh Load data

    // Check if Load data crossed thresholds, send trap if necessary.
    check_loadavg1_state();
    check_loadavg5_state();
    check_loadavg15_state();

}

The check_loadavg_state functions compare the current load data with thresholds. The functions also send the traps if necessary.

The module must use a trap function such as send_v2trap() to send a trap to the manager. For more information on SNMP trap APIs, see /usr/sfw/doc/sma_snmp/html/group__agent__trap.html. The SNMP trap notifications are defined in SNMP-NOTIFICATION-MIB.txt. For demo_module_4, the trap notifications are defined in SDK-DEMO4-MIB.txt.

Thresholds for Sending Traps

In the System Management Agent, any configurable data can be stored in a module-specific configuration file. Data from this file can be loaded into the module at the time of module initialization. Data is read from the configuration files into a module by registering a callback function to be called whenever an interesting token is encountered.

register_config_handler("demo_module_4", "threshold_loadavg1",
read_load_thresholds, NULL, NULL);

In this example demo_module_4, whenever a threshold_loadavg1 token is read by the agent in the demo_module_4.conf file, the read_load_thresholds() function is called, with token name and value as arguments. The read_load_thresholds() function stores the token value in appropriate variables and uses these thresholds to determine alarm conditions. For more information on the register_config_handler APIs, see the documentation in /usr/sfw/doc/sma_snmp/html/group__read__config.html.

demo_module_4 Code Example for Alarms

The demo_module_4 code example is provided to help you understand how to implement alarms. The demo is by default located in the directory /usr/demo/sma_snmp/demo_module_4. The README_demo_module_4 file in that directory contains instructions that describe how to do the following tasks:

The demo_module_4 module implements SDK-DEMO4-MIB.txt. The me4LoadGroup.c and me4LoadGroup.h files were generated with the mib2c command and then modified.

Module data is maintained in the following variables:

loadavg1

Stores data for me4SystemLoadAvg1min

loadavg5

Stores data for me4SystemLoadAvg5min

loadavg15

Stores data for me4SystemLoadAvg15min

The demo_module_4 module refreshes data every 60 seconds. During refresh intervals, the module also checks whether trap conditions are met. If trap conditions are met, an SNMPv2 trap is generated by the module. The trap condition in this module is a simple comparison of current data with a threshold value. If the threshold is crossed, a trap is generated. The threshold data can be configured through the file demo_module_4.conf, which is installed in $HOME/.snmp.

When an snmpget request for these variables arrives, the following functions are called:

These accessory functions refresh the load data by calling the refreshLoadAvg() function to return the current load value. However, the reload occurs only in response to a GET request. The load data must also be refreshed asynchronously without waiting for GET requests from the manager. Asynchronous refreshing allows trap conditions to be checked continuously in order to alert the manager of any problems. You can refresh the load data without a request from the manager by registering a callback function to be called at regular intervals. For example, you can call the function as follows:


snmp_alarm_register(60, SA_REPEAT, refreshLoadAvg, NULL)

This function causes the refreshLoadAvg() function to be called every 60 seconds. You can enable a manager to configure this interval by introducing a token to represent this value in the demo_module_4.conf file.

See the API documentation at /usr/sfw/doc/sma_snmp/html /group__snmp__alarm.html for more information on snmp_alarm_register() functions.

Reading Data From the demo_module_4.conf Configuration File

Data is read from the configuration files into a module by registering a callback function to be called whenever an appropriate token is encountered. For example, you can call the function as follows:

register_config_handler(demo_module_4, threshold_loadavg1, 
read_load_thresholds, NULL, NULL);

Whenever a threshold_loadavg1 token in the demo_module_4 file is read by the agent, the function read_load_thresholds() is called with token name and value as arguments. The read_load_thresholds() function stores the token value in appropriate variables:

void
read_load_thresholds(const char *token, char *cptr)
{

    if (strcmp(token, "threshold_loadavg1") == 0) {
        threshold_loadavg1=atof(cptr);
    } else if (strcmp(token,"threshold_loadavg5") == 0) {
        threshold_loadavg5=atof(cptr);
    } else if (strcmp(token,"threshold_loadavg15") == 0) {
        threshold_loadavg15=atof(cptr);
    } else {
        /* Do nothing */
    }

        return;

}

See the API documentation about register_config_handler() in /usr/sfw/doc/sma_snmp/html/group__read__config.html for more information.

Using SNMP_CALLBACK_POST_READ_CONFIG in demo_module_4

A few seconds elapse after agent startup while all configuration tokens are read by the module. During this interval, the module should not perform certain functions. For example, until the threshold settings are read from configuration files into the module, trap condition checks should not be performed. To handle these cases, a callback function can be set. This callback function is called when the process of reading the configuration files is complete. For example, you can call the function as follows:


snmp_register_callback(SNMP_CALLBACK_LIBRARY, 
SNMP_CALLBACK_POST_READ_CONFIG,demo_4_post_read_config, NULL);

The demo_4_post_read_config() function is called after the configuration files are read. In this example, the demo_4_post_read_config() function registers refresh callbacks:

int demo_4_post_read_config(int a, int b, void *c, void *d)
{

    /* Refresh the load data every 60 seconds */
    snmp_alarm_register(60, SA_REPEAT, refreshLoadAvg, NULL);

    /* Acquire the data first time */
    refreshLoadAvg(0,NULL);

}

Generating Traps in demo_module_4

The refreshLoadAvg() function is called at regular intervals to refresh data. Immediately after data is refreshed, the refreshLoadAvg() function checks for trap conditions by calling the following functions:

In me4LoadGroup.c, a module property could be in one of two states: OK or ERROR. When the current data value crosses the threshold, the state is set to ERROR. A trap is then generated. The check functions have the following algorithm:

check_loadavg1_state() {

	// Step-1: check condition
	if (currentData > threshold_loadavg1) new_loadavg1_state = ERROR;

	// Step-2: Generate trap if necessary
        if (new_loadavg1_state > prev_loadavg1_state) {
                // Send trap
                prev_loadavg1_state=new_loadavg1_state;
        } else if(new_loadavg1_state == prev_loadavg1_state) {
                /* No Change in state .. Do nothing */
        } else if (new_loadavg1_state < prev_loadavg1_state) {
                if (new_loadavg1_state == OK) {
                        prev_loadavg1_state=OK;
			// Send OK trap
                }
        }
}

When the check indicates that the threshold has been crossed, the send_v2trap function is used to generate an SNMPv2 trap. The trap OID and the varbinds are as specified in the SDK-DEMO4-MIB.txt MIB. For more information on SNMP trap APIs, see /usr/sfw/doc/sma_snmp/html/group__agent__trap.html.