home *** CD-ROM | disk | FTP | other *** search
-
- Luminated Software Group Presents
-
- HOWTO use Back-UPS (by APC)
- (to keep your linux box from frying)
-
-
- Document by: Christian G. Holtje <docwhat@uiuc.edu>
- Cabling info and help: Ben Galliart <bgallia@orion.it.luc.edu>
-
-
-
-
- This document, under one condition, is placed in Public Domain. The
- one condition is that credit is given where credit is due. Modify this as
- much as you want, just give some credit to us who worked.
-
- *******************************************************************************
- Warning!
- I, nor any of us who have written or helped with this document, make
- and guarantees or claims for this text/source/hints. If anything is damaged,
- we take NO RESPONSIBILITY! This works to the BEST OF OUR KNOWLEDGE, but
- we may have made mistakes. So be careful!
- *******************************************************************************
-
- Al right, you just bought (or are going to buy) a Back-UPS from APC.
- (Other brands might be able to use this info, with little or no modification,
- but we don't know) You've looked at the price of the Power-Chute
- software/cabling, and just are not sure it's worth the price. Well, I made my
- own cable, and my own software and am using it to automatically shut off the
- power to my linux box when a power failure hits. Guess what? You can too!
-
- *** The Cable ***
-
-
- This was the hardest part to figure out (I know little about hardware,
- so Ben did the most work for this). To build one, you need to buy from your
- local radio shack (or other part supplier) this stuff:
- 1 male 9-pin rs-232 plug
- 1 female 9-pin rs-232 plug
- 2 casings for the above plugs (they are usually sold separately)
- Some wire
- You also need, but may be able to borrow:
- 1 soldering iron
- solder
-
- Okay...this is how you connect it up!
-
- These diagrams are looking into the REVERSE SIDE (the side where you solder
- the wire onto the plugs) The letters G, R, and B represent the colors of the
- wires I used, and help to distinguish one line from the next.
- (NOTE: I'm use standard rs-232 (as near as we can tell) numbering. The APC
- book uses different numbers. Ignore them! Use ours...I already changed the
- numbers for you!)
-
- --------------------- Male Side! (This goes into the UPS)
- \ B R * * * /
- \ * * * G /
- ------------
-
-
- --------------------- Female Side! (This goes into your COM port)
- \ R * * * G /
- \ * B * * /
- ------------
-
-
- For those who like the numbers better:
- Male Female
- ---------------------------------------
- 1 7 Black
- 2 1 Red
- 9 5 Green
-
-
- ---------Aside: What the rs-232 pins are for!-----------
- Since we had to dig this info up anyway:
-
- >From the REAR (the soldering side) the pins are numbered so:
-
- ---------------------
- \ 1 2 3 4 5 /
- \ 6 7 8 9 /
- ------------
-
- The pins mean:
- Number Name Abbr. (Sometimes written with D prefix)
- 1 Carrier Detect CD
- 2 Receive Data RD
- 3 Transmit Data TD(?)
- 4 Data Terminal Ready DTR
- 5 Signal Ground Gnd
- 6 Data Set Ready DSR
- 7 Request to Send RTS(?)
- 8 Clear to Send CS
- 9 Ring Indicator RI
-
- What we did is connect the UPS's RS-232 Line Fail Output to the CD, the UPS's
- chassis to Gnd, and the UPS's RS-232 Shut Down Input to RTS.
- Easy now that we told you, no?
-
- I have no idea if the software below will work, if you purchase the cable
- from APC. It might, and it might not.
-
-
- *** The Software ***
-
- Okay, I use the SysVInit package by Miquel van Smoorenburg for Linux.
- (see end for file locations, credits, email addresses, etc.) I don't know
- what would have to be changed to use someone elses init, but I know this code
- (following) will work with Miquel's stuff.
- Just so I give credit where credit's due. I looked at Miquel's code
- to figure out how ioctl()'s worked. If I didn't have that example, I'd have
- been in trouble. I also used the powerfail() routine (verbatim, I think),
- since it must interact with his init, I thought that he should know best.
- The .c file is at the end of this document, and just needs to be
- clipped off. To clip the file, edit away and extra '.sigs' and junk. This
- document should end on the line /* End of File */.....cut the rest.
- Then type:
- tail -n 116 backups.HOWTO > backupsd.c
-
- This may need a little editing, but it works!
-
- This program can either be run as a daemon to check the status of the
- UPS and report it to init, or it can be run to send the kill-power command
- to the UPS. The power will only be killed if there is a power problem, and
- the UPS is running off the battery. Once the power is restored, it turns back
- on.
-
- To run as a daemon, just type:
- backupsd /dev/backups
-
- /dev/backups is a link to /dev/cua0 at the moment (COM 1, for you DOSers).
- The niceness of the link is that I can just re-link the device if I change
- to com 2 or 3.
-
- Then, if the power dies init will run the commands for the powerwait.
- An example (This is from my /etc/inittab):
-
- # Here are the actions for powerfailure.
- pf::powerwait:/etc/rc.d/rc.power start
- po::powerokwait:/etc/rc.d/rc.power stop
-
- The powerwait will run, if the power goes down, and powerokwait will
- run if the power comes back up.
-
- Here is my entire rc.power:
- ----------------------------------------------------------------------------
- #! /bin/sh
- #
- # rc.power This file is executed by init when there is a powerfailure.
- #
- # Version: @(#)/etc/rc.d/rc.power 1.50 1994-08-10
- #
- # Author: Christian Holtje, <docwhat@uiuc.edu>
- #
-
- # Set the path.
- PATH=/sbin:/etc:/bin:/usr/bin:/sbin/dangerous
-
- # Find out how we were called.
- case "$1" in
- start)
- echo "Warning there is Power problems." | wall
- # Save current Run Level
- ps | gawk '{ if (($5 == "init") && ($1 == "1")) print $6 }' \
- | cut -f2 -d[ | cut -f1 -d] \
- > /tmp/run.level.power
- /sbin/shutdown -h +1m
- ;;
- stop)
- echo "Power is back up. Attempting to halt shutdown." | wall
- shutdown -c
- ;;
- *)
- echo "Usage: $0 [start|stop]"
- exit 1
- ;;
- esac
- #End of File
- ------------------------------------------------------------------------------
-
- Pretty nifty, no?
-
- There is one little detail left, that is having the UPS turn off the power if
- it was halted with the power out. This is accomplished by adding this line
- into the end of your halt script:
-
- /sbin/backupsd /dev/backups killpower
-
- This will only kill the power if there is no power being supplied to your
- UPS.
-
-
- *** Testing the stuff ***
-
- This is just a short section saying this:
-
- BE CAREFUL!
-
- I recommend backing up your linux partitions, syncing several times
- before testing and just being careful in general. Of course, I'm just
- recommending this. I wasn't careful at all, and had to clean my partition
- several times testing my config. But it works. :)
-
-
- *** Where to Get It ***
-
- Miquel van Smoorenburg's SysVInit can be gotten at:
- sunsite.unc.edu:/pub/Linux/system/Daemons/SysVinit-2.50.tgz
-
- and a fix for some bash shells is right next-door as:
- sunsite.unc.edu:/pub/Linux/system/Daemons/SysVinit-2.50.patch1
-
- As to getting this HOWTO, you can email me.
- docwhat@uiuc.edu with the subject saying 'request'
- and the keyword 'backups' in body of the letter.
- (I may automate this, and other stuff)
-
- *** Credit Where Credit's Due Dept. ***
-
- Thanks to Miquel van Smoorenburg <miquels@drinkel.nl.mugnet.org>
- for his wonderful SysVInit package and his powerd.c which helped me very much.
-
- Christian Holtje <docwhat@uiuc.edu>
- Documentation
- backupsd.c (what wasn't Miquel's)
- rc.power
-
- Ben Galliart <bgallia@orion.it.luc.edu>
- The cable
- Information for the RS-232 standard
- Lousy Jokes (none quoted here)
-
- ------------------>8-------------CUT HERE--------8<---------------------------
-
-
-
-
-
- /* backupsd.c -- Simple Daemon to catch power failure signals from a
- * Back-UPS (from APC).
- *
- * Parts of the code are from Miquel van Smoorenburg's powerd.c
- * Other parts are original from Christian Holtje <docwhat@uiuc.edu>
- * I believe that it is okay to say that this is Public Domain, just
- * give credit, where credit is due.
- *
- * Disclaimer: We make NO claims to this software, and take no
- * resposibility for it's use/misuse.
- */
-
- #include <sys/types.h>
- #include <sys/ioctl.h>
- #include <fcntl.h>
- #include <errno.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <stdio.h>
- #include <signal.h>
-
- /* This is the file needed by SysVInit */
- #define PWRSTAT "/etc/powerstatus"
-
- void powerfail(int fail);
-
- /* Main program. */
- int main(int argc, char **argv)
- {
- int fd;
- int killpwr_bit = TIOCM_RTS;
- int flags;
- int status, oldstat = -1;
- int count = 0;
-
- if (argc < 2) {
- fprintf(stderr, "Usage: %s <device> [killpower]\n", argv[0]);
- exit(1);
- }
-
- /* Open the the device */
- if ((fd = open(argv[1], O_RDWR | O_NDELAY)) < 0) {
- fprintf(stderr, "%s: %s: %s\n", argv[0], argv[1], sys_errlist[errno]);
- exit(1);
- }
-
- if ( argc >= 3 && (strcmp(argv[2], "killpower")==0) )
- {
- /* Let's kill the power! */
- fprintf(stderr, "%s: Attempting to kill the power!\n",argv[0] );
- ioctl(fd, TIOCMBIS, &killpwr_bit);
- /* Hmmm..... If you have a power outtage, you won't make it! */
- exit(0);
- }
- else
- /* Since we don't want to kill the power, clear the RTS. (killpwr_bit) */
- ioctl(fd, TIOCMBIC, &killpwr_bit);
-
- /* Become a daemon. */
- switch(fork()) {
- case 0: /* I am the child. */
- setsid();
- break;
- case -1: /* Failed to become daemon. */
- fprintf(stderr, "%s: can't fork.\n", argv[0]);
- exit(1);
- default: /* I am the parent. */
- exit(0);
- }
-
-
- /* Now sample the DCD line. */
- while(1) {
- ioctl(fd, TIOCMGET, &flags);
- status = (flags & TIOCM_CD);
- /* Did DCD jumps to high? Then the power has failed. */
- if (oldstat == 0 && status != 0) {
- count++;
- if (count > 3) powerfail(0);
- else { sleep(1); continue; }
- }
- /* Did DCD go down again? Then the power is back. */
- if (oldstat > 0 && status == 0) {
- count++;
- if (count > 3) powerfail(1);
- else { sleep(1); continue; }
- }
- /* Reset count, remember status and sleep 2 seconds. */
- count = 0;
- oldstat = status;
- sleep(2);
- }
- /* Error! (shouldn't happen) */
- return(1);
- }
-
-
- /* Tell init the power has either gone or is back. */
- void powerfail(ok)
- int ok;
- {
- int fd;
-
- /* Create an info file needed by init to shutdown/cancel shutdown */
- unlink(PWRSTAT);
- if ((fd = open(PWRSTAT, O_CREAT|O_WRONLY, 0644)) >= 0) {
- if (ok)
- write(fd, "OK\n", 3);
- else
- write(fd, "FAIL\n", 5);
- close(fd);
- }
- kill(1, SIGPWR);
- }
-
- /* End of File */
- LocalWords: rc
-
-
-