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