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:
Compile source files to generate a shared library object that implements a module
Set up the agent to dynamically load the module
Test the module with snmp commands to show that the module is functioning as expected
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:
Stores data for me4SystemLoadAvg1min
Stores data for me4SystemLoadAvg5min
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:
int get_me4SystemLoadAvg1min()
int get_me4SystemLoadAvg5min()
int get_me4SystemLoadAvg15min()
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.
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.
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); }
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:
check_loadavg1_state()
check_loadavg5_state()
check_loadavg15_state()
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.