home *** CD-ROM | disk | FTP | other *** search
- The Power Micro-Mini-HOWTO
- By Harvey J. Stein (hjstein@math.huji.ac.il)
- Version 1.0 (last edited Tue Aug 2 1994)
-
- Contents
-
- 1. Introduction
- 2. What you need to do (summary)
- 3. How it's supposed to work
- 4. Where to get the appropriate software
- 5. How to set things up
- 6. User Enhancements
- 7. How to make a cable
- 8. Serial port pin assignments
- 9. Ioctl bit numbers corresponding to RS232 control lines
- 10. Info on selected UPSs
- 10.1. Advice 1200 A
- 10.2. GPS
- 11. Reverse-engineering cables & hacking powerd.c
- 12. How to shutdown other machines on the same UPS
- 12.1. UPS status port method
- 12.2. Broadcast method
- 12.3. Dummy login method
-
-
- 1. Introduction
-
- This HOWTO covers connecting a UPS to a PC running Linux in such a way
- that Linux can shutdown cleanly when the power goes out. To a large
- extent it is reduntant, because all the basic info is contained in the
- powerd man page that comes with the SysVinit package. None the less,
- there seems to periodically be alot of discussion on the net regarding
- connecting Linux PCs to UPSs, (and the versions of Linux that I
- installed didn't come with a powerd man page). I figured having a
- HOWTO would be a good idea because:
-
- -A second source of information might help to understand how
- to connect Linux to a UPS, even if it's just the same information
- written differently.
- -The HOWTO can serve as a repository for UPS specific data.
- -The HOWTO contains additional details that aren't in the powerd
- man page.
-
- None the less, this does not replace the powerd man page. Hopefully,
- after reading both, people will be able to deal with UPSs.
-
-
- 2. What you need to do (summary)
-
- -Plug the PC into the UPS.
- -Connect the PC's serial port to the UPS with a special cable.
- -Run powerd on the PC.
- -Setup your initd to do something reasonable on powerfail & powerok
- events (like start a shutdown & kill any currently running
- shutdowns, respectively, for example).
-
-
- 3. How it's supposed to work
-
- UPS's job:
- When the power goes out, the UPS continues to power the PC &
- signals that the power went out by throwing a relay or turning
- on an opticoupler on it's control port.
-
- Cable's job:
- The cable is designed so that when the UPS throws said relay,
- this causes a particular serial port control line (typically
- DCD) to go high.
-
- Powerd's job:
- Powerd monitors the serial port. Keeps raised/lowered
- whatever serial port control lines the UPS needs to have
- raised/lowered (typically, DTR must be kept high & whatever line
- shuts off the UPS must be kept low). When powerd sees the UPS control
- line go high, it writes "FAIL" to /etc/powerfail & sends the
- initd process a SIGPWR signal. When the control line goes low
- again, it writes "OK" to /etc/powerfail & sends initd a SIGPWR
- signal.
-
- Initd's job (aside from everything else it does):
- When it receives a SIGPWR, it looks at /etc/powerfail. If it
- contains "FAIL" it runs the powerfail entry from /etc/inittab.
- If it contains "OK" it runs the powerokwait entry from inittab.
-
-
- 4. Where to get the appropriate software
-
- Pick up /pub/Linux/system/Daemons/SysVinit-2.50.tgz from
- sunsite.unc.edu or a mirror. It includes a copy of powerd.c,
- shutdown.c, an initd that understands what to do with SIGPWR, & can
- handle powerfail & powerokwait entries in the inittab file.
-
-
- 5. How to set things up
-
- -Edit /etc/inittab. Put in something like this:
-
- # What to do when power fails (Halt system & drain battery :):
- pf::powerfail:/etc/powerfailscript +5
-
- # If power is back before shutdown, cancel the running shutdown.
- pg:0123456:powerokwait:/etc/powerokscript
-
- -Write scripts /etc/powerfailscript & /etc/powerokscript to
- shutdown in 5 minutes (or whatever's appropriate) & kill any
- existing shutdown, respectively. Depending on the version of
- shutdown that you're using, this will be either so trivial that
- you'll dispense with the scripts, or be a 1 line bash script,
- something along the lines of:
-
- kill `ps -aux | grep "shutdown" | grep -v grep | awk '{print $2}'`
-
- and you'll keep the scripts.
-
- -Tell initd to re-process the inittab file with the command:
-
- telinit q
-
- -Edit rc.local so that powerd gets run upon startup. The syntax
- is:
- powerd <line>
-
- Replace <line> with the serial port that the modem is connected,
- such as /dev/cua1.
-
- -Connect PC's serial port to UPS's serial port. DO NOT PLUG PC
- INTO UPS YET.
-
- -Plug a light into the UPS.
-
- -Turn on the UPS & the light.
-
- -Run powerd.
-
- -Test the setup:
- -Yank the UPS's plug.
- -Check that the light stays on.
- -Check that /etc/powerfailscript is running.
- -Check that shutdown is running.
- -Plug the UPS back in.
- -Check that the light stays on.
- -Check that /etc/powerfailscript is no longer running.
- -Check that shutdown is no longer running.
- -Yank the UPS's plug again. Leave it out & make sure that the
- PC shuts down properly in the proper amount of time.
-
- -After everything seems to be proper, powerdown the PC & plug it
- into the UPS. Run a script that sync's the hard disk every
- second or so. Simultaneously run a second script that keeps
- doing a find over your entire hard disk. The first is to make
- this a little safer & the second is to help draw lots of power.
- Now, pull the plug on the UPS, check again that shutdown is
- running & wait. Make sure that the PC shuts down cleanly
- before the battery on the UPS gives out.
-
- Congratulations! You now have a Linux PC that's protected by a UPS
- and will shutdown cleanly when the power goes out!
-
-
- 6. User Enhancements
-
- -Hack powerd.c to monitor the line indicating that the batteries
- are low. When the batteries get low, do an *immediate* shutdown.
- -Modify shutdown procedure so that if it's shutting down in a
- powerfail situation, then it turns off the UPS after doing
- everything necessary.
-
-
- 7. How to make a cable
-
- This section is just from messages I've seen on the net. I haven't
- done it so I can't write from experience. If anyone has, please write
- this section for me :). See also the message about the GPS1000
- contained in section 10.2.
-
-
- >From miquels@caution.cistron.nl.mugnet.org Wed Jul 21 14:26:33 1993
- Newsgroups: comp.os.linux
- Subject: Re: UPS interface for Linux?
- From: miquels@caution.cistron.nl.mugnet.org (Miquel van Smoorenburg)
- Date: Sat, 17 Jul 93 18:03:37
- Distribution: world
- Organization: Cistron Electronics.
-
- In article <1993Jul15.184450.5193@excaliber.uucp> joel@rac1.wam.umd.edu (Joel M. Hoffman) writes:
- >I'm in the process of buying a UPS (Uninteruptable Power Supply), and
- >notice that some of them have interfaces for LAN's to signal the LAN
- >when the power fails.
- >
- >Is there such an interface for Linux?
- >
- >Thanks.
- >
- >-Joel
- >(joel@wam.umd.edu)
- >
-
- When I worked on the last versioon of SysVinit (Now version 2.4),
- I temporarily had a UPS on my computer, so I added support for it.
- You might have seen that in the latest <signal.h> header files there
- is a #define SIGPWR 30 now :-). Anyway, I did not have such a special
- interface but the output of most UPS's is just a relais that makes or breaks
- on power interrupt. I thought up a simple way to connect this to the
- DCD line of the serial port. In the SysVinit package there is a daemon
- called 'powerd' that keeps an eye on that serial line and sends SIGPWR
- to init when the status changes, so that init can do something (such as
- bringing the system down within 5 minutes). How to connect the UPS to
- the serial line is described in the source "powerd.c", but I will
- draw it here for explanation:
-
- +------------------------o DTR
- |
- +---+
- | | resistor
- | | 10 kilo-Ohm
- | |
- +---+ To serial port.
- |
- +-----o-------+------------------------o DCD
- | |
- o UPS |
- \ relais |
- \ |
- | |
- +-----o-------+------------------------o GND
-
- Nice drawing eh?
-
- Hope this helps.
- SysVinit can be found on sunsite (and tsx-11 probably) as
- SysVinit2.4.tar.z
-
- Mike.
-
- --
-
- Miquel van Smoorenburg, <miquels@cistron.nl.mugnet.org>
- Ibmio.com: cannot open CONFIG.SYS: file handle broke off.
-
-
- >From danny@caution.cistron.nl.mugnet.org Wed Jul 21 14:27:04 1993
- Newsgroups: comp.os.linux
- Subject: Re: UPS interface for Linux?
- From: danny@caution.cistron.nl.mugnet.org (Danny ter Haar)
- Date: Mon, 19 Jul 93 11:02:14
- Distribution: world
- Organization: Cistron Electronics.
-
- In article <9307174330@caution.cistron.nl.mugnet.org> miquels@caution.cistron.nl.mugnet.org (Miquel van Smoorenburg) writes:
- >How to connect the UPS to the serial line is described in the source
- >"powerd.c", but I will draw it here for explanation:
-
- The drawing wasn't really clear, please use this one in stead !
- >
- > +------------------------o DTR
- > |
- > +---+
- > | | resistor
- > | | 10 kilo-Ohm
- > | |
- > +---+ To serial port.
- > |
- > +-----o-------+------------------------o DCD
- > |
- > o UPS
- > \ relais
- > \
- > |
- > +-----o--------------------------------o GND
- >
-
- The DTR is kept high, when the UPS's power input is gone it
- will close the relais . The computer is monitoring
- the DCD input port to go LOW . When this happens it will start a
- shutdown sequence...
-
- _____
- Danny
-
- --
- <=====================================================================>
- Danny ter Haar <dannyth@hacktic.nl> or <danny@cistron.nl.mugnet.org>
- Robins law #103: 'a couple of lightyears can't part good friends'
-
-
- 8. Serial port pin assignments
-
- (The following is from David Tal's <GSRGAAO@TECHNION.BITNET>
- 'Frequently Used Cables and Connectors' document).
-
- Pin Assignment for the Serial Port (RS-232C), 25-pin and 9-pin
- --------------------------------------------------------------
- DB-25 DB-9
- Pin # Pin # Name EIA CCITT DTE-DCE Description
- ----- ----- ----- ----- ----- ------- -------------------
- 1 FG AA 101 ---- Frame Ground/Chassis GND
- 2 3 TD BA 103 ---> Transmitted Data, TxD
- 3 2 RD BB 104 <--- Received Data, RxD
- 4 7 RTS CA 105 ---> Request To Send
- 5 8 CTS CB 106 <--- Clear To Send
- 6 6 DSR CC 107 <--- Data Set Ready
- 7 5 SG AB 102 ---- Signal Ground, GND
- 8 1 DCD CF 109 <--- Data Carrier Detect
- 9 -- -- - - Positive DC test voltage
- 10 -- -- - - Negative DC test voltage
- 11 QM -- - <--- Equalizer mode
- 12 SDCD SCF 122 <--- Secondary Data Carrier Detect
- 13 SCTS SCB 121 <--- Secondary Clear To Send
- 14 STD SBA 118 ---> Secondary Transmitted Data
- 15 TC DB 114 <--- Transmitter (signal) Clock
- 16 SRD SBB 119 <--- Secondary Receiver Clock
- 17 RC DD 115 ---> Receiver (signal) Clock
- 18 DCR -- - <--- Divided Clock Receiver
- 19 SRTS SCA 120 ---> Secondary Request To Send
- 20 4 DTR CD 108.2 ---> Data Terminal Ready
- 21 SQ CG 110 <--- Signal Quality Detect
- 22 9 RI CE 125 <--- Ring Indicator
- 23 -- CH 111 ---> Data rate selector
- 24 -- CI 112 <--- Data rate selector
- 25 TC DA 113 <--- Transmitted Clock
-
- 1 13 1 5
- _______________________________ _______________
- \ . . . . . . . . . . . . . / \ . . . . . / RS232-connectors
- \ . . . . . . . . . . . . / \ . . . . / seen from outside
- --------------------------- ----------- of computer.
- 14 25 6 9
-
- DTE : Data Terminal Equipment (i.e. computer)
- DCE : Data Communications Equipment (i.e. modem)
- RxD : Data received; 1 is transmitted "low", 0 as "high"
- TxD : Data sent; 1 is transmitted "low", 0 as "high"
- DTR : DTE announces that it is powered up and ready to communicate
- DSR : DCE announces that it is ready to communicate; low=modem hangup
- RTS : DTE asks DCE for permission to send data
- CTS : DCE agrees on RTS
- RI : DCE signals the DTE that an establishment of a connection is attempted
- DCD : DCE announces that a connection is established
-
-
-
- 9. Ioctl bit numbers corresponding to RS232 control lines
- (taken from /usr/include/linux/termios.h)
-
- /* modem lines */
- #define TIOCM_LE 0x001
- #define TIOCM_DTR 0x002
- #define TIOCM_RTS 0x004
- #define TIOCM_ST 0x008
- #define TIOCM_SR 0x010
- #define TIOCM_CTS 0x020
- #define TIOCM_CAR 0x040
- #define TIOCM_RNG 0x080
- #define TIOCM_DSR 0x100
- #define TIOCM_CD TIOCM_CAR
- #define TIOCM_RI TIOCM_RNG
-
- Note that the 3rd column is in Hex.
-
-
- 10. Info on selected UPSs
-
- **** Please send them to me for inclusion here. ****
-
-
- 10.1. Advice 1200 A
-
- UPS from Advice Electronics, Tel Aviv Israel (they stick their own
- name on the things).
-
- UPS Control Port
- ----------------
-
- 2 - Power Fail.
- 5 - Battery Low.
- 6 - Shut Down UPS.
- 4 - Common ground for pin 2, 5, 6.
-
- They also gave me the following picture which didn't help me, but
- may help you if you want to build a cable yourself:
-
-
- 2 ----------+
- |
- \
- \|
- |--------------
- /|
- \/ (<--- The "\/" here indicates the type of
- | this transister. I forget what
- | denotes what, but this one points
- +-----+ away from the center line.)
- / / /
-
-
- 5 ----------+
- |
- \
- \|
- |--------------
- /|
- \/
- |
- |
- +-----+
- / / /
-
-
- +-------------
- |
- /
- 10K |/
- 6 --\/\/\/--|
- |\
- \/
- |
- |
- +-----+
- / / /
-
-
- 4 ----------+
- |
- |
- +-----+
- / / /
-
-
- Cable supplied
- --------------
- They first game me a cable that was part of a DOS UPS control
- package called RUPS. I used this for testing. When I was
- satisfied, they gave me a cable they use for Netware servers
- connected to UPSs. It functioned identically. Here are the
- details:
-
- DTR - Powers cable (keep high).
- CTS - Power out (stays high & goes low when power goes out).
- DSR - Battery low (stays high & goes low when battery does).
- RTS - Turns off UPS (keep low & set high to turn off UPS).
-
- (The powerd.c that comes with SysVinit set or left RTS high,
- causing the UPS to shut off immediately when powerd was started
- up!)
-
-
- 10.2. GPS1000 from ACCODATA
-
- >From hennus@sky.nl.mugnet.org Thu Mar 10 15:10:22 1994
- Newsgroups: comp.os.linux.help
- Subject: Re: auto-shutdown with UPS
- From: hennus@sky.nl.mugnet.org (Hennus Bergman)
- Date: Tue, 1 Mar 1994 22:17:45 GMT
- Distribution: world
- Organization: The Organization For Removal Of On-Screen Logos
-
- In article <CRAFFERT.94Feb28125452@nostril.lehman.com>,
- Colin Owen Rafferty <craffert@nostril.lehman.com> wrote:
- >I am about to buy an Uninterruptable Power Supply for my machine, and
- >I would like to get one that has the "auto-shutdown" feature.
- >
- I just got one of those real cheap :-)
- It's a GPS1000 by ACCODATA. Anybody know how good the output
- signal of these things is? [Don't have a scope myself :-(]
-
- >I assume that these each have some kind of serial connection that
- >tells the system information about it.
- >
- I took it apart to find out how it worked. There were three optocouplers
- (two output, one input) connected to a 9 pin connector at the back.
- One turns on when the power fails, and goes off again when the power
- returns. While the power is off, you can use the `input' to shut the
- battery off. [It releases the power-relay.] The third one is some kind
- of feedback to tell that it did accepted the `shut-down command'.
- I think the interface for my UPS was designed to be connected to TTL-level
- signals, but with some resistors it could be connected to serial port.
- It's wired in such a way that using a RS-232 port you cannot use both
- output optocouplers; but the shutdown feedback is not necessary anyway,
- just use the important one. ;-)
- [Note that it is possible to blow the transistor part in optocouplers
- with RS-232 levels if you wire it the wrong way round ;-)]
-
- I was hoping I would be able to connect it to my unused game port,
- but that doesn't have an output, does it?
- I'll probably end up getting an extra printer port for this.
-
- Not all UPS' use optocouplers, some use simple relays, which are
- less critical to connect, but of course not as `nice'.
-
- >Has anyone written a package that watches the UPS and does a shutdown
- >(or something) when the power is off?
- SysVinit-2.4 (and probably 2.5 as well) has a `powerd' daemon that
- continually watches a serial port for presence of the CD (Carrier
- Detect) line and signals init when it drops. Init then activates
- shutdown with a time delay. If the power returns within a few minutes
- the shutdown is cancelled. Very Nice.
- The only problem I had with it is that it doesn't actually tell the
- UPS to turn off when the shutdown is complete. It just sits there with
- a root prompt. I'll probably write a small program to shut it down
- >from /etc/brc. RSN.
-
- > Colin Rafferty, Lehman Brothers <craffert@lehman.com>
-
- Hennus Bergman
-
-
- 11. Reverse-engineering cables & hacking powerd.c
-
- Try to get documentation for the cables that your UPS seller supplies.
- In particular find out:
-
- -What lines need to be kept high.
- -What line(s) turn off the UPS.
- -What lines the UPS toggles to indicate that:
- -Power is out.
- -Battery is low.
-
- You then need to hack powerd.c appropriately.
-
- If you have trouble getting the above information (or just want to
- check it) the following program (upscheck.c) might help. It's a
- hacked version of powerd.c. It allows you to set the necessary port
- flags from the command line & then monitors the port, displaying the
- control lines every second. I used it as "upscheck /dev/cua1 2" (for
- example) to set the 2nd bit (DTR) & to clear the other bits. The
- number base 2 indicates which bits to set, so for example to set bits
- 1, 2 & 3, (& clear the others) use 7. See the code for details.
-
- Here's the (untested) upscheck.c program. It's untested because I
- edited the version I originally used to make it clearer, and can't
- test the new version at the moment.
-
- --------- Begin upscheck.c ------------------
- /*
- * upscheck Check how UPS & computer communicate.
- *
- * Usage: upscheck <device> <bits to set>
- * For example, upscheck /dev/cua4 4 to set bit 3 &
- * monitor /dev/cua4.
- *
- * Author: Harvey J. Stein <hjstein@math.huji.ac.il>
- * (but really just a minor modification of Miquel van
- * Smoorenburg's <miquels@drinkel.nl.mugnet.org> powerd.c
- *
- * Version: 1.0 19940802
- *
- */
- #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>
-
- /* Main program. */
- int main(int argc, char **argv)
- {
- int fd;
-
- /* These TIOCM_* parameters are defined in <linux/termios.h>, which */
- /* is indirectly included here. */
- int dtr_bit = TIOCM_DTR;
- int rts_bit = TIOCM_RTS;
- int set_bits;
- int flags;
- int status, oldstat = -1;
- int count = 0;
- int pc;
-
- if (argc < 2) {
- fprintf(stderr, "Usage: upscheck <device> <bits-to-set>\n");
- exit(1);
- }
-
- /* Open monitor device. */
- if ((fd = open(argv[1], O_RDWR | O_NDELAY)) < 0) {
- fprintf(stderr, "upscheck: %s: %s\n", argv[1], sys_errlist[errno]);
- exit(1);}
-
- /* Line is opened, so DTR is high. Force it anyway to be sure. */
- /* ioctl(fd, TIOCMBIS, &dtr_bit); */
- /* The above line was from the original powerd.c, but it turned off */
- /* my UPS! So, I changed it to the line below which clears the DTR */
- /* instead of setting the DTR bit & that worked for me. However, */
- /* it might not work for you, so I commented it out too. */
- /* ioctl(fd, TIOCMBIC, &dtr_bit); */
-
- /* Get the bits to set from the command line. */
- sscanf(argv[2], "%d", &set_bits);
-
- while (1) {
- /* Set the command line specified bits (& only the command line */
- /* specified bits). */
- ioctl(fd, TIOCMSET, &set_bits);
- fprintf(stderr, "Setting %o.\n", set_bits);
-
- sleep(1);
-
- /* Get the current line bits */
- ioctl(fd, TIOCMGET, &flags);
- fprintf(stderr, "Flags are %o.\n", flags);
-
- /* Fiddle here by changing TIOCM_CTS to some other TIOCM until */
- /* this program detects that the power goes out when you yank */
- /* the plug on the UPS. Then you'll know how to modify powerd.c. */
- if (flags & TIOCM_CTS)
- {
- pc = 0 ;
- fprintf(stderr, "power is up.\n");
- }
- else
- {
- pc = pc + 1 ;
- fprintf(stderr, "power is down.\n");
- }
- }
-
- close(fd);
- }
- ----------- End upscheck.c ---------------------------
-
-
-
- 12. How to shutdown other machines on the same UPS
-
- Some people (myself included) have several Linux PCs connected to one
- UPS. One PC monitors the UPS & needs to get the other PCs to shut
- down when the power goes out. There are a number of ways to do this,
- all are do-it-yourself currently, and most are just hypothetical.
-
- We assume the PCs can communicate over a network. Call the PC that
- monitors the UPS the master & the other PCs the slaves.
-
-
- 12.1. UPS status port method
-
- Set up a port on the master which, when connected to, either sends
- "OK", "FAIL", or "BATLOW", the first when the power is ok, the second
- when the power has failed, and the third when the battery is low.
- Model this on port 13 (the time port) which one can telnet to &
- receive the local time.
-
- Have the slaves run versions of powerd that look at this port instead
- of checking a serial line.
-
- The only down side I can see to this method is the network load due to
- checking this port. One would want to check this port often to
- quickly catch the BATLOW message & shut down before the battery dies.
-
-
- 12.2. Broadcast method
-
- Same as 12.1 except send an ethernet broadcast message that the power
- has just gone down.
-
- This might have security implications.
-
-
- 12.3. Dummy login method
-
- Set up dummy logins on the slaves with login names "powerok" &
- "powerfail", both with the same UID. Make /etc/powerokscript the
- shell of the powerok user, & make /etc/powerfailscript the shell of
- the powerfail user. On the master, have the /etc/powerokscript rlogin
- to each slave as user powerok, & have the /etc/powerfailscript rlogin
- to each slave as user powerfail. Put a .rhosts file on each slave in
- the home directory of powerok & powerfail to allow root from the
- master to login as user powerok & powerfail to each slave.
-
- This is the system I'm currently using.
-
- This might also have security implications.
-
-
- ---------- END UPS micro-mini HOWTO -------------------------
-
-
-