ALINK="#FF0000"> [ Prev ][ Table of Contents ][ Front Page ][ Talkback ][ FAQ ][ Next ]
LINUX GAZETTE
...making Linux just a little more fun!
Handling Power Status Using snmptrapd
By A B Prasad

If you are new to this topic

Refer the following if you are new to SNMP

Net-snmp

Various tools relating to the Simple Network Management Protocol including:

See the NET-SNMP site.

snmptrapd

Snmptrapd is an SNMP application that receives and logs snmp trap messages sent to the SNMP-TRAP port (162) on the local machine. It can be configured to run a specific program on receiving a snmp trap.

snmptrapd.conf

snmptrapd.conf is the configuration file(s) which define how the ucd-snmp SNMP trap receiving demon operates when it receives a trap.

ups-MIB

RFC1628 document defines the managed objects for Uninterruptible Power Supplies which are to be manageable via the Simple Network Management Protocol (SNMP).

How to use snmptrapd with powerh

Please Note: I renamed 'powerd' as 'powerh' as here it is not a daemon but only a trap handling routine

We had the powerh to handle the Power Status of the system. powerh communicates with the UPS through the serial port. However, in a networked system where a number of machines are using the same UPS it is not possible for each system to directly communicate with the UPS. Most modern high capacity UPS support the SNMP Protocol either directly or through a proxy. To handle various power status follow these steps

1. To your snmptrapd.conf add the following lines

traphandle 33.2.3 powerh b
traphandle 33.2.4 powerh p

2. Compile the following C code by entering cc powerh.c -o powerhand copy powerh to a directory in path like /usr/local/sbin/.
[Text version of this listing.]

#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <signal.h>


#define PWRSTAT "/etc/powerstatus"

void powerfail(int);

main(int argc, char* argv[]) {
    char s[1000];
    int i=0;
    while(i<7) {
        scanf("%s",s);
        i++;
    }
    scanf("%s",s);
    if (!strcmp("b",argv[1]))
        if ((!strcmp(s,"33.1.6.3.3"))||(!strcmp(s,"upsMIB.upsObjects.upsAlarm.upsWellKnownAlarms.upsAlarmLowBattery")))
            powerfail(1);
    if (!strcmp("p",argv[1]))
        if ((!strcmp(s,"33.1.6.3.3"))||(!strcmp(s,"upsMIB.upsObjects.upsAlarm.upsWellKnownAlarms.upsAlarmLowBattery")))
            powerfail(0);
}
/* As the program may be activated in the event of other alarms as well, the inner 'if' are necessary */
void powerfail(int event) {
    int fd;
    unlink(PWRSTAT);
    if ((fd = open(PWRSTAT, O_CREAT|O_WRONLY, 0644)) >= 0) {
          switch (event)
           {
           case 0:
                  write(fd, "OKWAIT\n", 7);
                   break;

             case 1:
                    write(fd, "FAIL\n", 5);
                     break;
             }
          close(fd);
       }
       kill(1, SIGPWR);
}



3. Run snmptrapd on your system (you can configure it in the init scripts)

The system will shutdown 2 minutes after receiving a 'battery low alarm' from the UPS. Then if power is OK before the shutdown it will cancel shutdown or as configured in the powerfail and powerokwait lines in /etc/inittab

Code Explanation

When received a trap 33.2.3 (upsMIB.upsTraps.upsTrapAlarmEntryAdded) the program is executed with a 'b' option. Program checks for the 'upsAlarmId' send by the trap and if it is 33.1.6.3.3 (upsMIB.upsObjects.upsAlarm.upsWellKnownAlarms.upsAlarmLowBattery) it notfies init that a power failure occurred. This alarm is added to the alarm table by the UPS agent if the remaining battery run-time is less than or equal to upsConfigLowBattTime. It is removed when the power is back and is acknowledged by trap 33.2.4. The program then sends init a powerokwait message.

Drawbacks

TODO

I would like to see this few lines of code grow into a complete general purpose UPS managing software capable of:

All Suggestions, Criticisms,Contibutions (code and idea only - no cash please ;) ) etc. are welcome. You can contact me at prasad_ab@yahoo.com. See also my home page .


Copyright © 2002, A B Prasad. Copying license http://www.linuxgazette.net/copying.html
Published in Issue 83 of Linux Gazette, October 2002

[ Prev ][ Table of Contents ][ Front Page ][ Talkback ][ FAQ ][ Next ]