NAME¶
powstatd - a configurable UPS monitor.
SYNOPSIS¶
powstatd [
-t |
-k ]
DESCRIPTION¶
powstatd is a configurable UPS monitoring daemon designed to work with
SysVinit (e.g., most Linux distributions).
powstatd monitors a serial connection from a "dumb" or
"relay" UPS for power failures and shuts the machine down gracefully
if the power remains off for more than a prespecified interval.
powstatd can also be configured to allow a master machine to control
several slave machines connected to the same UPS via a network connection.
This allows you to run several machines off the same UPS, with only one of the
machines actually reading the UPS status over the serial line. When compiled
with appropriate options enabled,
powstatd also provides security by
means of fast encryption of master/slave communication to prevent malicious
shutdown of slave systems.
powstatd has two options:
- -t
- Test mode. Used to explore what a given UPS signals under
various failure modes as an aid to constructing an appropriate
configuration file. When operating in test mode, powstatd doesn't
actually signal init, so while changes in UPS status are detected, they
are not acted upon. See configuration information for more details.
- -k
- Kill mode. Directs powstatd to attempt to shut down
the UPS. Most UPS systems will ignore the shutdown signal unless the power
is actually off. By shutting down the UPS, powstatd ensures that
once the main power returns the UPS will automatically turn on and cause
the machine to reboot.
CAVEATS¶
powstatd uses the connectionless UDP protocol to communicate UPS status
from master to slave. To keep just anyone from generating a UDP packet that
will shut your slave machine down when encrypted master/slave communication is
not in use, the slave checks the IP address of origin in the UDP packet it
receives. If your master has more than one network card, a master with
multiple addresses may provide an unexpected IP address, which results in the
slave ignoring (legitimate) status reports.
So when you have a machine with multiple network cards, you must either ensure
that the master has a unique IP address (try connecting the single-NIC slave
to the UPS and demoting the dual-NIC master to slave instead), or use
encrypted master/slave communication, which does not need to check IP source
addresses thanks to the cryptographic measures used.
When using encrypted master/slave communication,
powstatd also uses a
timestamp to foil replay attacks. Outdated status messages (as defined by a
compile-time constant) are simply rejected; thus master and slave clocks
should be reasonably synchronized (using, for example, the NTP protocol) or
valid status messages may be rejected.
CONFIGURATION¶
powstatd is configured via a configuration file,
/etc/powstatd.conf by default, that specifies the serial line behavior
of the UPS under its various failure modes (note that, if compiled with
appropriate security option enabled,
powstatd will require that file
permissions on the configuration file deny rwx access to "group" or
"other").
To configure your UPS, follow these steps:
0. Edit the Makefile to suit your installation. In particular, the secure
master/slave communication protocol is selected/deselected by making the
appropriate change to the definition of CFLGS in the Makefile. Note that users
outside the United States wishing to use the secure communication protocol
will first need to download the public-domain ANSI C implementation of TEA,
the
Tiny Encryption Algorithm, from
ftp://vader.eeng.brad.ac.uk/pub/crypto/xtea.c
1. Compile
powstatd:
% make
or, if you are compiling on a DEC Alpha platform:
% make alpha
2. Make sure your new UPS is completely charged and is connected to your
machine via the serial monitoring line provided by the UPS manufacturer to
your machine (if you did not get such a monitoring line with your UPS, see the
the UPS-HOWTO for information on how to make one).
3. In order to configure
powstatd, make sure your machine
is
not powered from the UPS but is instead plugged directly into the wall
outlet (your UPS should still, however, be connected to the machine via the
serial monitoring line). Instead, plug a desk light or radio into the UPS.
4. Determine what serial line is connected to your UPS and create an
initial copy of
/etc/powstatd.conf (you can look at the sample
powstatd.conf.* files included in the distribution) containing a single line
specifying the serial line, e.g.:
watch ttyS0
5. As root, run
powstatd in test mode (you'll have to be root to
have rw access to /dev/ttyS0 or whatever device corresponds to your UPS
monitoring line).
% ./powstatd -t
Hit ^C to stop after you see something like:
CTS |
DSR |
DCD |
RNG |
RxD |
TxD |
DTR |
RTS |
STATUS |
1 |
0 |
1 |
1 |
0 |
0 |
0 |
1 |
OK |
1 |
0 |
1 |
1 |
0 |
0 |
0 |
1 |
OK |
1 |
0 |
1 |
1 |
0 |
0 |
0 |
1 |
OK |
1 |
0 |
1 |
1 |
0 |
0 |
0 |
1 |
OK |
The output describes the state of the serial connection between the UPS and the
computer. Since the signaling needs of a UPS/computer connection are really
quite low (just a few bits), we aren't really using the serial connection as
it was designed to be used for higher-throughput applications. Instead, we'll
use the individual control and transmission lines in the nine wire standard
connector a bit differently.
Of the nine wires, six are of particular interest: four "input"
control lines (CTS, DSR, DCD, RNG) and two "output" control lines
(DTR, RTS). The remaining three lines consist of an electrical ground and the
two transmission lines (TxD and RxD, one running in each direction); the
latter are typically used for asynchronous serial information rather than for
control. Most "dumb" UPS systems ignore the transmission lines and
operate only by toggling combinations of the four "input" wires to
indicate the status of the UPS and the two "output" wires to send
commands back to the UPS from the computer (for now, we'll assume that the
current UPS is one of these).
Since the UPS is fully charged and the power is on, we want to play with the
configuration in
/etc/powstatd.conf until STATUS reads OK, and not LOW
or FAIL. Provided we are actually watching the correct serial line, getting
STATUS to read OK entails setting initial values for the output lines DTR and
RTS (of course, it makes no sense to try to set initial values on the input
lines). Try adding permutations of init values like:
init dtr 1
init rts 1
until you get the OK status reading.
6. Repeat step 4, but this time pull the plug on the UPS and then
reinsert it after a few seconds. Observe changes in the values for the input
lines; it should be easy to determine what line corresponds to power failure.
For example:
CTS |
DSR |
DCD |
RNG |
DTR |
RTS |
STATUS |
|
1 |
0 |
1 |
1 |
0 |
1 |
OK |
|
1 |
0 |
1 |
1 |
0 |
1 |
OK |
|
1 |
0 |
1 |
1 |
0 |
1 |
OK |
|
1 |
0 |
1 |
1 |
0 |
1 |
OK |
|
0 |
0 |
1 |
1 |
0 |
1 |
FAIL |
<- plug pulled |
0 |
0 |
1 |
1 |
0 |
1 |
FAIL |
|
0 |
0 |
1 |
1 |
0 |
1 |
FAIL |
|
0 |
0 |
1 |
1 |
0 |
1 |
FAIL |
|
1 |
0 |
1 |
1 |
0 |
1 |
OK |
<- plug reinserted |
1 |
0 |
1 |
1 |
0 |
1 |
OK |
|
1 |
0 |
1 |
1 |
0 |
1 |
OK |
|
would indicate that CTS going to 0 corresponds to a power failure. If you leave
the UPS unplugged long enough to discharge (this may take quite a while even
with a good size light bulb!), the UPS should signal a battery failure in a
similar fashion, e.g.,
CTS |
DSR |
DCD |
RNG |
DTR |
RTS |
STATUS |
0 |
0 |
0 |
1 |
0 |
1 |
LOW |
0 |
0 |
0 |
1 |
0 |
1 |
LOW |
0 |
0 |
0 |
1 |
0 |
1 |
LOW |
0 |
0 |
0 |
1 |
0 |
1 |
LOW |
7. At this point, you should know the power failure and low battery
signals. Now we must determine the appropriate UPS shutdown signal.
Fortunately, for most UPS systems, there are only 4 possible simple signals.
With the UPS on battery power (e.g., unplugged), try adding each of the
following lines into
/etc/powstatd.conf in turn:
kill dtr 0
kill dtr 1
kill rts 0
kill rts 1
for each trial, try issuing the command:
% ./powstatd -k
one of the line specifications should cause the desk lamp or radio to turn off;
that's the one you want. Important: be aware that many UPS have a "dead
time" after the signal is sent before the UPS turns itself off; this
"dead time" can be as long as 30-45 seconds! So don't be too
impatient here or you won't know which signal is responsible for actually
turning the UPS off.
8. At this point configuration should be complete. For example, for the
Cyberpower Power99 325/385/450/500VA models, a reasonable
/etc/powstatd.conf configuration file reads:
watch ttyS0
fail cts 0
low dcd 0
init rts 1
init dtr 0
kill dtr 1
9. If you have other machines running off the same UPS, include one or
more slave entries specifying their names in the master's configuration file:
slave slave1.domain.edu
slave slave2.domain.edu
The slave machines' configuration files
/etc/powstatd.conf should contain
a single line specifying the name of the master machine that is actually
monitoring the UPS that also powers the slave:
watch master.domain.edu
If you intend to run more than 2 slaves off a very large UPS, you will need to
adjust the MAXSLAVES parameter in the source code accordingly and then
recompile.
If
powstatd is compiled with the appropriate security option enabled,
encryption is used to protect slaves from malicious shutdown messages. An
identical password directive should therefore appear in both master and slave
configuration files:
password MyPasswordHere
In addition to encrypting status information,
powstatd will encrypt
generate and check timestamps in order to foil replay attacks.
10. Make sure your inittab file contains appropriate lines to invoke
powstatd.fail, powstatd.low, and
powstatd.ok:
# UPS signals a power outage.
pf:12345:powerfail:/sbin/powstatd.fail
# UPS signals power restored before the shutdown kicks in.
pr:12345:powerokwait:/sbin/powstatd.ok
# UPS signals low battery power: emergency shutdown.
pn:12345:powerfailnow:/sbin/powstatd.low
11. Edit scripts
powstatd.ok, powstatd.fail, and
powstatd.low to adjust time parameters, if desired.
12. "make install", then reboot the machine. If you don't want
to reboot, issue instead:
% /etc/rc.d/init.d/powstatd start
% /sbin/init q
How It Works:¶
powstatd is initiated as a daemon in runlevels 3 and 5.
A UPS can only be in one of three states; OK, FAIL, or LOW. Usually, when the
main power is on, the UPS is operating in the OK state; when power fails, the
UPS changes to FAIL mode, from which it can either recover and return to OK
(if the power is restored) or can move to LOW (if the battery starts running
out of juice before the power returns).
powstatd monitors the UPS condition. When the state changes,
powstatd writes the new state of the UPS in
/etc/powerstatus and
then signals init (the mother of all processes) of the change in the UPS
condition. The init process receives this notice (a SIGPWR interrupt) and
checks
/etc/powerstatus to see if it contains "OK",
"FAIL" or "LOW".
The contents of
/etc/powerstatus tells init (which is configured by the
/etc/inittab file) to run one of three scripts:
powstatd.fail,
powstatd.ok, or
powstatd.low The init process then removes
/etc/powerstatus so as not to be confused on subsequent interrupts.
powstatd.fail
initiates a timed shutdown -h (halt) in
background, on the assumption that if power is restored the shutdown can be
cancelled.
powstatd.ok
cancels the running shutdown and notifies all
users that power is restored and no shutdown is imminent.
powstatd.low
cancels the running shutdown and initiates an
immediate shutdown -h in foreground; this means once the UPS tells you
the battery is low, you will indeed shutdown (there is no recovery).
Note that as you halt the machine, the shutdown sequence invokes
powstatd
one last time, but this time with the kill flag (-k), forcing the UPS to turn
off, but only if the UPS is indeed in either the FAIL or LOW state (in any
case, most supplies will ignore the kill signal if power is still available).
In this fashion, once the power eventually returns (even after a day or two),
the system should automatically restart without intervention.
Troubleshooting:¶
1. If your machine doesn't seem to notice power status changes even when
the UPS daemon is signalling them, try adjusting the location of the
powerstatus file by changing the value of STATUS in the Makefile and
recompiling. Some versions of the init process look in
/var/log/powerstatus rather than the default
/etc/powerstatus.
2. If your machine keeps shutting down even when the power is on, you're
probably watching the wrong serial line. To recover, try rebooting in single
user mode (issue "linux 1" at the LILO prompt) and disable
powstatd by renaming
/etc/powstatd.conf to something else.
Reboot and you should be able to fix the configuration.
3. Some older UPS systems as well as some homebuilt cable connections
(see the UPS HowTo) may require that UPS shutdown signals be sent on the
transmission line rather than on one of the signaling lines. Usually, this
implies that a serial break signal (e.g., a long series of zeros) is required
for the UPS to shut down. For these situations, you can use the special
configuration file command
kill break
to obtain the appropriate behavior.
4. If your slave machines keep rejecting seemingly valid status messages
from the master when using encrypted master/slave communication, first make
sure they are running the same version of the software. Otherwise, try
changing the definition of "outdated" at compile time
(MAXCLOCKDRIFT) and recompiling. If you are not using NTP or some other
mechanism to ensure that master and slave clocks are reasonably synchronized,
you may well be better off running powstatd compiled without -DSECURE.
5. Some older versions of init are not capable of invoking one of several
different scripts (e.g., powstatd.ok, powstatd.fail, powstatd.low) on receipt
of SIGPWR under different circumstances. Instead, they always invoke the same
script, which must then handle the control logic (i.e., deciding whether to
shutdown gracefully, abort a shutdown, or shutdown immediately) internally
(SPARC/Solaris and SGI/Irix apparently fall in this catagory). If you have
such a version of init, look at the sample script
powstatd.dumb
included in the distribution for an example of how to go about handling this
case.
ACKNOWLEDGEMENTS¶
I learned a lot from reading the publically-available source code for other UPS
monitoring packages, like
genpower, powerd and
upsd. I
wrote
powstatd primarily because the exact combination of features or
configuration options I required were not available with these other packages.
Peter Galbraith (galbraithp@dfo-mpo.gc.ca), the
powstatd Debian package
maintainer, provided numerous suggestions and bug fixes, as did Philippe Troin
(phil@fifi.org), who was the first to suggest using, e.g., MD5-based digital
signatures to avoid malicious shutdowns. Nick Holgate (holgate@debian.org)
suggested an extension to
powstatd signaling capabilities in order to
support UPS systems that require a break signal for shutdown. Nicolas Simonds
(nic@bridge.com) provided information about changes to the code for both
SPARC/Solaris and SGI/Irix.
TEA, or the
Tiny Encription Algorithm, is due to David Wheeler and Roger
Needham of the Cambridge Computer Laboratory. Their implementation, used here,
is in the public domain.
Alberto Maria Segre
segre@cs.uiowa.edu
S378 Pappajohn Building
The University of Iowa
Iowa City, IA 52242-1000.