UPS daemon
Jean-Pierre Radley
jpr at jpradley.jpr.com
Mon Apr 1 14:09:08 AEST 1991
In article <1991Mar29.195540.4760 at pilikia.pegasus.com> art at pilikia.pegasus.com (Art Neilson) writes:
>I recently purchased an American Power Conversion SmartUPS 600 and I also
>got the PowerChute UPS monitor software with it. I don't particularly
>care for the software, it doesn't come with source and it does some things
>I don't like. Does anyone have source for a UPS shutdown daemon ?
/* file: watchdog.c -- shuts down computer if a port loses power.
*
* This program checks periodically for inaccessibility of a
* specified tty and shuts down the system if the specified tty
* remains inaccessible for a specified period. This program
* is the fruit of the combined efforts of Bob Snapp, Lee Penn,
* and Fred Buck, but any defects in it should be laid squarely
* at the doorstep of Fred Buck only.
*
* The idea is that is the system be connected to an
* "uninterruptible power supply", or "UPS", which can sustain
* the system for only a limited time before the battery in the
* UPS itself fails; so therefore the system should sense a
* power loss in the outside world and bring itself down
* gracefully before the UPS battery fails. This program does
* that, and requires only that an external terminal device
* (which can be either a "real" terminal or a plain modem) be
* connected to one of the console's primary serial ports, and
* that the external terminal device (terminal or modem) show
* the console a "carrier detect" signal at all times. If a
* "real" terminal is used as the "watchdog terminal", this
* program won't interfere at all with the use of that terminal
* for unrelated tasks. If a modem is used instead of a
* terminal, the modem should be configured to show
* carrier-detect high at all times (on Hayes-compatible
* modems, set DIP switch #6 to the DOWN position). If you use
* a modem instead of a terminal to check for power-loss, you
* probably shouldn't use that modem for incoming calls to your
* system; use another modem on another serial port for those
* incoming calls instead.
*
* In either case, the terminal or modem should NOT be
* connected to the UPS. They should be connected instead to a
* standard wall power outlet so that when the wall outlets
* lose power, so do the terminal or the modem.
*
* As presently set up, this program will, when it detects a
* power loss on the "watch" terminal, send a warning message
* to the system console once a minute for five minutes and
* will then shut down the entire system. To eliminate the
* console warning messages, redefine the preprocessor variable
* BEEPCON to 0. To change the "grace" period from five
* minutes to some other number of minutes, change the
* preprocessor variable FAILMAX; note that "minutes" should
* be figured conservatively. To change the "watch" tty
* line from /dev/tty01 to some other port, redefine the
* preprocessor variable WATCHTTY. In every case, the program
* will attempt to append a distress message to
* /usr/adm/messages if the system must be shut down. Note
* that the "grace" period, if any, must be short enough to
* guard against the possibility that the UPS battery will
* run out of power before the grace period is exhausted.
*
* TEST THIS PROGRAM ON YOUR OWN SYSTEM REPEATEDLY UNTIL YOU'RE
* SATISFIED WITH ITS PERFORMANCE BEFORE YOU ENTRUST YOUR SYSTEM
* AND ITS DATA TO IT ON A REGULAR BASIS.
*
* This program was developed originally for Tandy 6000 systems
* using the 3.0 Development System.
*
* It should be compiled thus:
* cc -o watchdog watchdog.c -lx
*
* Once compiled, it should be inserted into the file
* /etc/rc.user on a line by itself and containing the full
* pathname of the compiled file. Restrict the accessibility
* of the compiled file.
*/
#include <stdio.h>
#include <signal.h>
#include <setjmp.h>
#include <sys/param.h> /* 'param.h' itself includes <sys/types.h> */
#include <sys/types.h> /* but not on the 80386 ! */
#include <sys/filsys.h>
#define EVER ;; /* makes infinite loops easier to spot */
#define FAILMAX 1 /* tolerable # of consec. mins. of powerloss */
#define BEEPCON 1 /* bother hell out of console on powerloss */
#define WATCHTTY "/dev/tty1A" /* which tty port to 'watch'... */
/* ... note '"'s are mandatory */
static int failcount; /* number of times attempted opens've failed */
static jmp_buf env; /* a stack-adjusting thingie */
wakeup() { /* what do to when an open() fails */
FILE *console, *fopen();
signal(SIGALRM,wakeup);
if ((++failcount)<FAILMAX) {
if (BEEPCON) {
if (console=fopen("/dev/console","w")) {
fprintf(console,"\007\nWARNING: %s has lost power (%d)\n",
WATCHTTY,failcount);
fclose(console);
}
}
longjmp(env,1);
}
system("echo POWER LOSS ON WATCH TTY `/bin/date` >>/usr/adm/messages");
shutdn((struct filsys *)0);
exit(1);
}
main()
{
int eyelid, wakeup();
if (fork()!=0) exit(); /* make this a daemon */
signal(SIGALRM,wakeup); /* alarm vector is now 'wakeup()' */
failcount = 0;
setjmp(env); /* for repeated wakeups, return here */
sleep(50); /* 'cause blocked open()'s wait 10 secs */
for (EVER) {
eyelid = (-1);
alarm(10);
if ((eyelid=open(WATCHTTY,2))<0) wakeup();
else failcount = 0;
alarm(0); close(eyelid); sleep(60);
}
}
--
Jean-Pierre Radley NYC Public Unix jpr at jpradley.jpr.com CIS: 72160,1341
More information about the Comp.unix.sysv386
mailing list