home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / HOWTO / BUPS-HOW < prev    next >
Encoding:
Text File  |  1995-04-20  |  10.6 KB  |  360 lines

  1.  
  2.               Luminated Software Group Presents
  3.  
  4.              HOWTO use Back-UPS (by APC)
  5.              (to keep your linux box from frying)
  6.  
  7.  
  8.          Document by: Christian G. Holtje <docwhat@uiuc.edu>
  9.     Cabling info and help: Ben Galliart <bgallia@orion.it.luc.edu>
  10.  
  11.  
  12.  
  13.  
  14.     This document, under one condition, is placed in Public Domain. The
  15. one condition is that credit is given where credit is due.  Modify this as
  16. much as you want, just give some credit to us who worked.
  17.  
  18. *******************************************************************************
  19. Warning!
  20.     I, nor any of us who have written or helped with this document, make
  21. and guarantees or claims for this text/source/hints.  If anything is damaged,
  22. we take NO RESPONSIBILITY!  This works to the BEST OF OUR KNOWLEDGE, but
  23. we may have made mistakes.  So be careful!
  24. *******************************************************************************
  25.  
  26.     Al right, you just bought (or are going to buy) a Back-UPS from APC.
  27. (Other brands might be able to use this info, with little or no modification,
  28. but we don't know)  You've looked at the price of the Power-Chute
  29. software/cabling, and just are not sure it's worth the price.  Well, I made my
  30. own cable, and my own software and am using it to automatically shut off the
  31. power to my linux box when a power failure hits.  Guess what?  You can too!
  32.  
  33. *** The Cable ***
  34.  
  35.  
  36.     This was the hardest part to figure out (I know little about hardware,
  37. so Ben did the most work for this).  To build one, you need to buy from your
  38. local radio shack (or other part supplier) this stuff:
  39.     1 male 9-pin rs-232 plug
  40.     1 female 9-pin rs-232 plug
  41.     2 casings for the above plugs (they are usually sold separately)
  42.     Some wire
  43. You also need, but may be able to borrow:
  44.     1 soldering iron
  45.     solder
  46.  
  47. Okay...this is how you connect it up!
  48.  
  49. These diagrams are looking into the REVERSE SIDE (the side where you solder
  50. the wire onto the plugs)  The letters G, R, and B represent the colors of the
  51. wires I used, and help to distinguish one line from the next.
  52. (NOTE:  I'm use standard rs-232 (as near as we can tell) numbering.  The APC
  53. book uses different numbers.  Ignore them!  Use ours...I already changed the
  54. numbers for you!)
  55.  
  56.    ---------------------     Male Side! (This goes into the UPS)
  57.     \  B   R  *  *  * /     
  58.       \  *  *  *  G  / 
  59.         ------------
  60.  
  61.  
  62.    ---------------------     Female Side! (This goes into your COM port)
  63.     \  R   *  *  *  G /
  64.       \  *  B  *  *  / 
  65.         ------------
  66.  
  67.  
  68. For those who like the numbers better:
  69.     Male        Female
  70. ---------------------------------------
  71.     1        7        Black
  72.     2        1        Red
  73.     9        5        Green
  74.  
  75.  
  76. ---------Aside:  What the rs-232 pins are for!-----------
  77. Since we had to dig this info up anyway:
  78.  
  79. >From the REAR (the soldering side) the pins are numbered so:
  80.  
  81.    ---------------------
  82.     \  1   2  3  4  5 /
  83.       \  6  7  8  9  / 
  84.         ------------
  85.  
  86. The pins mean:
  87.     Number    Name            Abbr. (Sometimes written with D prefix)
  88.     1    Carrier Detect        CD
  89.     2    Receive Data        RD
  90.     3    Transmit Data        TD(?)
  91.     4    Data Terminal Ready    DTR
  92.     5    Signal Ground        Gnd
  93.     6    Data Set Ready        DSR
  94.     7    Request to Send        RTS(?)
  95.     8    Clear to Send        CS
  96.     9    Ring Indicator        RI
  97.  
  98. What we did is connect the UPS's RS-232 Line Fail Output to the CD, the UPS's
  99. chassis to Gnd, and the UPS's RS-232 Shut Down Input to RTS.
  100. Easy now that we told you, no?
  101.  
  102. I have no idea if the software below will work, if you purchase the cable
  103. from APC.  It might, and it might not.
  104.  
  105.  
  106. *** The Software ***
  107.  
  108.     Okay, I use the SysVInit package by Miquel van Smoorenburg for Linux.
  109. (see end for file locations, credits, email addresses, etc.)  I don't know
  110. what would have to be changed to use someone elses init, but I know this code
  111. (following) will work with Miquel's stuff.
  112.     Just so I give credit where credit's due.  I looked at Miquel's code
  113. to figure out how ioctl()'s worked.  If I didn't have that example, I'd have
  114. been in trouble.  I also used the powerfail() routine (verbatim, I think),
  115. since it must interact with his init, I thought that he should know best.
  116.     The .c file is at the end of this document, and just needs to be
  117. clipped off.  To clip the file, edit away and extra '.sigs' and junk.  This
  118. document should end on the line /* End of File */.....cut the rest.
  119. Then type:
  120.     tail -n 116 backups.HOWTO > backupsd.c
  121.  
  122. This may need a little editing, but it works!
  123.  
  124.     This program can either be run as a daemon to check the status of the
  125. UPS and report it to init, or it can be run to send the kill-power command
  126. to the UPS.  The power will only be killed if there is a power problem, and
  127. the UPS is running off the battery.  Once the power is restored, it turns back
  128. on.
  129.  
  130.     To run as a daemon, just type:
  131.         backupsd /dev/backups
  132.  
  133. /dev/backups is a link to /dev/cua0 at the moment (COM 1, for you DOSers).
  134. The niceness of the link is that I can just re-link the device if I change
  135. to com 2 or 3.
  136.  
  137. Then, if the power dies init will run the commands for the powerwait.
  138. An example (This is from my /etc/inittab):
  139.  
  140. # Here are the actions for powerfailure.
  141. pf::powerwait:/etc/rc.d/rc.power start
  142. po::powerokwait:/etc/rc.d/rc.power stop
  143.  
  144. The powerwait will run, if the power goes down, and powerokwait will
  145. run if the power comes back up.
  146.  
  147. Here is my entire rc.power:
  148. ----------------------------------------------------------------------------
  149. #! /bin/sh
  150. #
  151. # rc.power      This file is executed by init when there is a powerfailure.
  152. #
  153. # Version:      @(#)/etc/rc.d/rc.power   1.50    1994-08-10
  154. #
  155. # Author:       Christian Holtje, <docwhat@uiuc.edu>
  156. #
  157.  
  158.   # Set the path.
  159.   PATH=/sbin:/etc:/bin:/usr/bin:/sbin/dangerous
  160.  
  161.   # Find out how we were called.
  162.   case "$1" in
  163.         start)
  164.                 echo "Warning there is Power problems."     | wall
  165.         # Save current Run Level
  166.         ps | gawk '{ if (($5 == "init") && ($1 == "1")) print $6 }' \
  167.              | cut -f2 -d[ | cut -f1 -d] \
  168.              > /tmp/run.level.power
  169.         /sbin/shutdown -h +1m
  170.                 ;;
  171.         stop)
  172.                 echo "Power is back up.  Attempting to halt shutdown." | wall
  173.                 shutdown -c
  174.                 ;;
  175.         *)
  176.                 echo "Usage:  $0 [start|stop]"
  177.                 exit 1
  178.                 ;;
  179.   esac
  180. #End of File
  181. ------------------------------------------------------------------------------
  182.  
  183. Pretty nifty, no?
  184.  
  185. There is one little detail left, that is having the UPS turn off the power if
  186. it was halted with the power out.  This is accomplished by adding this line
  187. into the end of your halt script:
  188.  
  189.   /sbin/backupsd /dev/backups killpower
  190.  
  191. This will only kill the power if there is no power being supplied to your
  192. UPS.
  193.  
  194.  
  195. *** Testing the stuff ***
  196.  
  197.     This is just a short section saying this:
  198.  
  199.     BE CAREFUL!
  200.  
  201.     I recommend backing up your linux partitions, syncing several times
  202. before testing and just being careful in general.  Of course, I'm just
  203. recommending this.  I wasn't careful at all, and had to clean my partition
  204. several times testing my config.  But it works.  :)
  205.  
  206.  
  207. *** Where to Get It ***
  208.  
  209.     Miquel van Smoorenburg's SysVInit can be gotten at:
  210.     sunsite.unc.edu:/pub/Linux/system/Daemons/SysVinit-2.50.tgz
  211.  
  212.     and a fix for some bash shells is right next-door as:
  213.     sunsite.unc.edu:/pub/Linux/system/Daemons/SysVinit-2.50.patch1
  214.     
  215.     As to getting this HOWTO, you can email me.
  216.     docwhat@uiuc.edu  with the subject saying 'request'
  217.     and the keyword 'backups' in body of the letter.
  218.     (I may automate this, and other stuff)
  219.  
  220. *** Credit Where Credit's Due Dept. ***
  221.  
  222.     Thanks to Miquel van Smoorenburg <miquels@drinkel.nl.mugnet.org>
  223. for his wonderful SysVInit package and his powerd.c which helped me very much.
  224.  
  225.     Christian Holtje <docwhat@uiuc.edu>
  226.         Documentation
  227.         backupsd.c (what wasn't Miquel's)
  228.         rc.power
  229.  
  230.     Ben Galliart <bgallia@orion.it.luc.edu>
  231.         The cable
  232.         Information for the RS-232 standard
  233.         Lousy Jokes (none quoted here)
  234.  
  235. ------------------>8-------------CUT HERE--------8<---------------------------
  236.  
  237.  
  238.  
  239.  
  240.  
  241. /*  backupsd.c -- Simple Daemon to catch power failure signals from a
  242.  *                Back-UPS (from APC).
  243.  * 
  244.  *  Parts of the code are from Miquel van Smoorenburg's powerd.c
  245.  *  Other parts are original from Christian Holtje <docwhat@uiuc.edu>
  246.  *  I believe that it is okay to say that this is Public Domain, just
  247.  *  give credit, where credit is due.
  248.  *
  249.  *  Disclaimer:  We make NO claims to this software, and take no
  250.  *               resposibility for it's use/misuse.
  251.  */
  252.  
  253. #include <sys/types.h>
  254. #include <sys/ioctl.h>
  255. #include <fcntl.h>
  256. #include <errno.h>
  257. #include <stdlib.h>
  258. #include <unistd.h>
  259. #include <stdio.h>
  260. #include <signal.h>
  261.  
  262. /* This is the file needed by SysVInit */
  263. #define PWRSTAT         "/etc/powerstatus"
  264.  
  265. void powerfail(int fail);
  266.  
  267. /* Main program. */
  268. int main(int argc, char **argv)
  269. {
  270.   int fd;
  271.   int killpwr_bit = TIOCM_RTS;
  272.   int flags;
  273.   int status, oldstat = -1;
  274.   int count = 0;
  275.  
  276.   if (argc < 2) {
  277.         fprintf(stderr, "Usage: %s <device> [killpower]\n", argv[0]);
  278.         exit(1);
  279.   }
  280.  
  281.   /* Open the the device */
  282.   if ((fd = open(argv[1], O_RDWR | O_NDELAY)) < 0) {
  283.         fprintf(stderr, "%s: %s: %s\n", argv[0], argv[1], sys_errlist[errno]);
  284.         exit(1);
  285.   }
  286.  
  287.   if ( argc >= 3  && (strcmp(argv[2], "killpower")==0) )
  288.       {
  289.       /* Let's kill the power! */
  290.       fprintf(stderr, "%s: Attempting to kill the power!\n",argv[0] );
  291.       ioctl(fd, TIOCMBIS, &killpwr_bit); 
  292.       /* Hmmm..... If you have a power outtage, you won't make it! */
  293.       exit(0);
  294.       }
  295.   else
  296.       /* Since we don't want to kill the power, clear the RTS. (killpwr_bit) */
  297.       ioctl(fd, TIOCMBIC, &killpwr_bit); 
  298.  
  299. /* Become a daemon. */
  300.   switch(fork()) {
  301.   case 0: /* I am the child. */
  302.                 setsid();
  303.                 break;
  304.   case -1: /* Failed to become daemon. */
  305.                 fprintf(stderr, "%s: can't fork.\n", argv[0]);
  306.                 exit(1);
  307.   default: /* I am the parent. */
  308.                 exit(0);
  309.   }
  310.  
  311.  
  312.   /* Now sample the DCD line. */
  313.   while(1) {
  314.       ioctl(fd, TIOCMGET, &flags);
  315.       status = (flags & TIOCM_CD); 
  316.       /* Did DCD jumps to high? Then the power has failed. */
  317.       if (oldstat == 0 && status != 0) {
  318.       count++;
  319.       if (count > 3) powerfail(0);
  320.       else { sleep(1); continue; }
  321.       }
  322.       /* Did DCD go down again? Then the power is back. */
  323.       if (oldstat > 0 && status == 0) {
  324.       count++;
  325.       if (count > 3) powerfail(1);
  326.       else { sleep(1); continue; }
  327.       }
  328.       /* Reset count, remember status and sleep 2 seconds. */
  329.       count = 0;
  330.       oldstat = status;
  331.       sleep(2);
  332.   }
  333.   /* Error! (shouldn't happen) */
  334.   return(1);
  335. }
  336.  
  337.  
  338. /* Tell init the power has either gone or is back. */
  339. void powerfail(ok)
  340. int ok;
  341. {
  342.   int fd;
  343.  
  344.   /* Create an info file needed by init to shutdown/cancel shutdown */
  345.   unlink(PWRSTAT);
  346.   if ((fd = open(PWRSTAT, O_CREAT|O_WRONLY, 0644)) >= 0) {
  347.         if (ok)
  348.                 write(fd, "OK\n", 3);
  349.         else
  350.                 write(fd, "FAIL\n", 5);
  351.         close(fd);
  352.   }
  353.   kill(1, SIGPWR);
  354. }
  355.  
  356. /* End of File */
  357.  LocalWords:  rc
  358.  
  359.  
  360.