Date: Wed, 29 Jan 1997 21:16:32 -0600 (CST) From: "Gil Kloepfer Jr." <gil@limbic.gc2.kloepfer.org> To: FreeBSD-gnats-submit@freebsd.org Subject: misc/2617: upsmon - UPS monitor utility submission Message-ID: <199701300316.VAA07446@limbic.gc2.kloepfer.org> Resent-Message-ID: <199701300320.TAA14923@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 2617 >Category: misc >Synopsis: Utility submission - upsmon - UPS monitor program >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Class: change-request >Submitter-Id: current-users >Arrival-Date: Wed Jan 29 19:20:02 PST 1997 >Last-Modified: >Originator: Gil Kloepfer Jr. >Organization: None >Release: FreeBSD 2.1-STABLE i386 >Environment: FreeBSD 2.1.5-RELEASE (and likely all 2.*.* versions) TrippLite UPS system with LAN 2.1 interface >Description: Utility provides the capability to monitor the UPS and send users/administrators status messgages as well as semi-gracefully shut the system down when battery power is low. >How-To-Repeat: N/A >Fix: The following is a shar of the code, makefile, and manual page, and a message I originally sent to Jordan Hubbard originally submitting the program. He recommended I submit it in this way with a followup e-mail to the -hackers list. See the manual page for electrical details. Yes, I know it isn't as flexible as it should be as far as support for other UPS systems. This is a good start though, and if someone sends me the specs for other UPS systems, I may be able to write the code and cabling for that UPS, and I'll build up the code to something more extensible. To: jkh@freebsd.org From: Gil Kloepfer Jr. <gil@gc2.kloepfer.org> Date: Mon, 27 Jan 1997 21:35:06 -0600 (CST) Subject: Software submission: upsmon.c Jordan- I'm not sure what the best way to submit software to the FreeBSD project is, and you're the release coordinator... I figure you'll probably know who should look at this. That said, this may or may not be useful for the project. I seem to recall linux has something called powerd that allows UPS systems to be monitored. I had some of my own ideas in mind and decided to write a UPS monitor program for my Tripp Lite UPS without looking at any of it. I could have wasted my time... In any case, I wrote a man page and a makefile for it. I thought someone may find it useful. Please let me know whether or not this makes sense to put into FreeBSD in some form. Constructive comments welcome, of course! I included the whole thing as a shar file since it wasn't very big... --- Gil Kloepfer gil@gc2.kloepfer.org http://www.gc2.kloepfer.org/ -- Cut Here -- # This is a shell archive. Save it in a file, remove anything before # this line, and then unpack it by entering "sh file". Note, it may # create directories; files and directories will be owned by you and # have default permissions. # # This archive contains: # # Makefile # upsmon.c # upsmon.8 # echo x - Makefile sed 's/^X//' >Makefile << 'END-of-Makefile' X# X# Makefile for upsmon X# X# Copyright (c) 1997 Gilbert C. Kloepfer, Jr. X# All rights reserved. X# X# Redistribution and use in source and binary forms, with or without X# modification, are permitted provided that the following conditions X# are met: X# X# 1. Redistributions of source code must retain the above copyright X# notice, this list of conditions and the following disclaimer. X# X# 2. Redistributions in binary form must reproduce the above copyright X# notice, this list of conditions and the following disclaimer in the X# documentation and/or other materials provided with the distribution. X# X# 3. All advertising materials mentioning features or use of this software X# in products other than the FreeBSD operating system must display X# the following acknowledgement: X# X# This product includes software developed by Gilbert C. Kloepfer, Jr. X# X# 4. The name of the author may not be used to endorse or promote products X# derived from this software without specific prior written permission. X# X# THIS SOFTWARE IS PROVIDED BY GILBERT C. KLOEPFER, JR. (THE AUTHOR) X# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT X# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS X# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE X# AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, X# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, X# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR X# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY X# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING X# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS X# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. X# X# $Id: Makefile,v 1.1 1997/01/28 03:20:55 gil Exp $ X# X XPROG= upsmon XSRCS= upsmon.c XMAN8= upsmon.8 XNOSHARED= true XBINDIR= /sbin X X.include <bsd.prog.mk> END-of-Makefile echo x - upsmon.c sed 's/^X//' >upsmon.c << 'END-of-upsmon.c' X/* X * Copyright (c) 1997 Gilbert C. Kloepfer, Jr. X * All rights reserved. X * X * Redistribution and use in source and binary forms, with or without X * modification, are permitted provided that the following conditions X * are met: X * X * 1. Redistributions of source code must retain the above copyright X * notice, this list of conditions and the following disclaimer. X * X * 2. Redistributions in binary form must reproduce the above copyright X * notice, this list of conditions and the following disclaimer in the X * documentation and/or other materials provided with the distribution. X * X * 3. All advertising materials mentioning features or use of this software X * in products other than the FreeBSD operating system must display X * the following acknowledgement: X * X * This product includes software developed by Gilbert C. Kloepfer, Jr. X * X * 4. The name of the author may not be used to endorse or promote products X * derived from this software without specific prior written permission. X * X * THIS SOFTWARE IS PROVIDED BY GILBERT C. KLOEPFER, JR. (THE AUTHOR) X * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT X * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS X * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE X * AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, X * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, X * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR X * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY X * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING X * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS X * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. X * X * $Id: upsmon.c,v 1.2 1997/01/28 03:26:38 gil Exp $ X * X */ X X#include <stdio.h> X#include <unistd.h> X#include <stdlib.h> X#include <fcntl.h> X#include <termios.h> X#include <sys/ioctl.h> X#include <sys/time.h> X#include <syslog.h> X#include <stdarg.h> X#include <signal.h> X Xint get_serstat(int); Xvoid delay(int), sys_shutdown(), runit(char *,...); X X#define STATE_ONLINE 1 X#define STATE_TRANSBATT 2 X#define STATE_BATTERY 3 X#define STATE_TRANSLINE 4 X#define STATE_LOWBATT 5 X X#define ON 1 X#define OFF 0 X#define forever for(;;) X X#define set_dtr(FD,STA) { int bits = TIOCM_DTR; \ X if (STA == ON) \ X (void)ioctl(FD, TIOCMBIS, &bits); \ X else \ X (void)ioctl(FD, TIOCMBIC, &bits); \ X } X X#define set_rts(FD,STA) { int bits = TIOCM_RTS; \ X if (STA == ON) \ X (void)ioctl(FD, TIOCMBIS, &bits); \ X else \ X (void)ioctl(FD, TIOCMBIC, &bits); \ X } X X#define set_td(FD,STA) { if (STA == ON) \ X (void)ioctl(FD, TIOCSBRK, 0); \ X else \ X (void)ioctl(FD, TIOCCBRK, 0); \ X } X X Xmain(argc, argv) Xint argc; Xchar *argv[]; X{ X int fd, savstat, statemach; X char *ctltty; X struct termios tioblk; X X X if (argc != 2 || *argv[1] == '\0') { X (void)fprintf(stderr, "usage: %s {tty port}\n", argv[0]); X exit(1); X } X ctltty = argv[1]; X X openlog("upsmon", LOG_CONS | LOG_NDELAY | LOG_PID, LOG_DAEMON); X X fd = open(ctltty, O_RDWR|O_NONBLOCK|O_EXCL); X if (fd < 0) { X syslog(LOG_ALERT, "cannot open %s: %m (aborting)", ctltty); X exit(2); X } X X /* X * Set the tty port in raw mode and turn off any flow control or X * other modem signalling that may interfere with the monitor's X * ability to directly control the tty port's control lines X */ X X if (tcgetattr(fd, &tioblk) < 0) { X syslog(LOG_ALERT, "cannot tcgetattr %s: %m (aborting)", ctltty); X exit(2); X } X X cfmakeraw(&tioblk); X tioblk.c_cflag |= CLOCAL; X tioblk.c_cflag &= ~(CRTS_IFLOW | CDTR_IFLOW | X CCTS_OFLOW | CDSR_OFLOW | CCAR_OFLOW); X X if (tcsetattr(fd, TCSAFLUSH, &tioblk) < 0) { X syslog(LOG_ALERT, "cannot tcgetattr %s: %m (aborting)", ctltty); X exit(2); X } X X /* X * Everything passing OK, we should now make ourself a daemon X */ X X if (daemon(0,0) < 0) { X syslog(LOG_ALERT, "daemon library call failed: %m (aborting)"); X exit(2); X } X X /* X * X * Quick review of control signals: X * X * CTS = Common for line fail relay. Common also feeds emitter X * of low battery NPN phototransistor X * X * TD = anode of inverter cutoff LED (usually off (-)) X * X * RTS = Positive pull-up supply for DCD, NO input of line fail X * relay. Almost always ON (+) except when testing line fail X * relay reading integrity. X * X * GND = cathode of inverter cutoff LED X * X * DTR = NC input of line fail relay. Usually OFF (-) except when X * testing line fail relay signal integrity (pulsed) X * X * DCD = Follows state of line fail relay. Line fail relay signal. X * Since low battery is only valid on line fail closed, we X * can pulse DTR on battery power to test this signal. X */ X X /* X * Initial check to see if we are communicating with the UPS. X * X * A good basic check is to see that DCD is asserted (+) when X * RTS is asserted and vice versa. We can also simulate some X * activity on some of the signal lines to make sure that the X * cable is functioning. X * X * If the cable is bad, or we're already on battery power for X * some reason, print a message explaining the problem and X * exit the monitor. We don't want to monitor a system X * already on battery since that would be a truly odd X * situation, in addition to being a possible cable fault X * that could bring down a bunch of systems already running. X */ X X set_td(fd, OFF); X set_rts(fd, ON); X set_dtr(fd, OFF); X X delay(10); X savstat = get_serstat(fd); X if (!(savstat & TIOCM_CTS)) { X syslog(LOG_ALERT, "CTS not on - Bad cable connection or already on battery power (aborting)"); X exit(2); X } X X if (!(savstat & TIOCM_CAR)) { X syslog(LOG_ALERT, "DCD not on - Probable bad UPS monitor cable (aborting)"); X exit(2); X } X X set_rts(fd, OFF); X delay(10); X if (get_serstat(fd) & TIOCM_CTS) { X syslog(LOG_ALERT, "CTS not off - Bad cable connection (aborting)"); X exit(2); X } X X syslog(LOG_NOTICE, "UPS monitoring started"); X X statemach = STATE_ONLINE; X X forever { X /* X * Reset monitoring lines to initial values X * X * TD = off (-) X * DTR = off (-) X * RTS = on (+) X */ X X set_td(fd, OFF); X set_dtr(fd, OFF); X set_rts(fd, ON); X delay(10); X X switch(statemach) { X case STATE_ONLINE: /* On AC line power */ X savstat = get_serstat(fd); X if (!(savstat & TIOCM_CTS)) { X delay(500); X if (get_serstat(fd) & TIOCM_CTS) X break; X statemach = STATE_TRANSBATT; X break; X } X X if (!(savstat & TIOCM_CAR)) { X syslog(LOG_ALERT, "DCD not on in Online state - Possible cable fault (aborting)"); X exit(2); X } X X delay(1000); X break; X X case STATE_TRANSBATT: /* Transition to battery power */ X set_dtr(fd, ON); X delay(10); X if (!(get_serstat(fd) & TIOCM_CTS)) { X syslog(LOG_ALERT, "Battery Transition CTS sanity check identified cable fault (aborting)"); X exit(2); X } X set_dtr(fd, OFF); X syslog(LOG_CRIT, "On battery power"); X delay(1000); X statemach = STATE_BATTERY; X break; X X case STATE_BATTERY: /* On battery power */ X if (get_serstat(fd) & TIOCM_CTS) { X delay(500); X if (get_serstat(fd) & TIOCM_CTS) { X statemach = STATE_TRANSLINE; X break; X } X } X X /* X * Check for DCD off. This means that battery X * power is low. Note the ridiculous number of X * sanity checks is a very paranoid precaution X * against unnecessary shutdowns. There'd be nothing X * worse than having a battery backup system which X * basically shutdown everything without reason! X * X * We could identify cable faults here, but I'm X * going to assume transient failure and be a little X * lazy. X */ X X if (!(get_serstat(fd) & TIOCM_CAR)) { X delay(500); X if (get_serstat(fd) & TIOCM_CAR) X break; X set_dtr(fd, ON); X delay(50); X if (get_serstat(fd) & TIOCM_CAR) { X set_dtr(fd, OFF); X if (!(get_serstat(fd) & TIOCM_CAR)) { X statemach = STATE_LOWBATT; X break; X } X } X } X X /* X * We're gonna do a little cable check here though. X * Briefly toggle DTR to see if CTS follows it. If X * it doesn't, it means the cable fell out, because X * even if a race condition put the UPS back online, X * RTS is still ON so it wouldn't make a difference. X * We will take another reading a few ms apart on X * a failure to make sure the bad reading isn't X * due to relay contact bounce. X * X * It would be nice to do something more intelligent X * than just aborting the monitor on a cable fault, X * but if there IS a cable fault, then we can't be X * positively sure that the transition to battery X * power wasn't a manifestation of a bad cable also. X */ X X set_dtr(fd, ON); X delay(10); X if (!(get_serstat(fd) & TIOCM_CTS)) { X delay(10); X if (!(get_serstat(fd) & TIOCM_CTS)) { X syslog(LOG_ALERT, "Battery mode cable check noted cable fault (aborting)\n"); X exit(2); X } X } X set_dtr(fd, OFF); X X delay(1000); X break; X X case STATE_TRANSLINE: /* Transition back to AC line power */ X syslog(LOG_WARNING, "AC Power restored"); X delay(1000); X statemach = STATE_ONLINE; X break; X X case STATE_LOWBATT: /* Low battery -- Shut down the system */ X syslog(LOG_EMERG, "UPS low battery power detected - Shutting down the system!!"); X delay(2000); X sys_shutdown(); X set_td(fd, ON); X delay(5000); X X /* X * If we get here, it means the power did NOT shut X * off. This could mean the AC power got restored X * while we were shutting down the system. It could X * also mean there is a cable or UPS problem. X * X * If the AC power looks like it came back, reboot X * the system. If it looks like a cable problem, X * halt the system and wait for a manual X * reboot. X */ X X set_dtr(fd, OFF); X set_rts(fd, ON); X if (get_serstat(fd) & TIOCM_CTS) X runit("/sbin/reboot", NULL); X else X runit("/sbin/halt", NULL); X break; X X /* If we get here, give up...just die... */ X X exit(2); X } X } X X /* NOTREACHED */ X} X X Xint Xget_serstat(fd) Xint fd; X{ X int ttsigs; X X if (ioctl(fd, TIOCMGET, &ttsigs) < 0) { X syslog(LOG_ALERT, "get_serstat TIOCMGET failed - %m (aborting)"); X exit(2); X } X X return(ttsigs); X} X Xvoid Xdelay(ms_time) Xint ms_time; X{ X int ret; X struct timeval sto; X X sto.tv_sec = ms_time / 1000; X sto.tv_usec = (ms_time % 1000) * 1000; X ret = select(0, NULL, NULL, NULL, &sto); X if (ret < 0) { X syslog(LOG_ALERT, "select failed in delay() - %m (aborting)"); X exit(2); X } X} X X X/* X * This shutdown routine is not the best nor is it the safest, but it only X * gets called under the most extreme of circumstances. X * X * The reason we shut the system down in this way is because it is extremely X * hardware-dependent to shut down the power as part of the boot system X * call, as well as requiring some tricky modifications to the kernel code. X * Rather than embed this kind of magic in the kernel, we will perform as X * graceful a shutdown as possible under the circumstances, with the X * understanding that this should not get called unless we are ready to lose X * AC power and would otherwise trash the system in some unpredictable way. X */ X Xvoid Xsys_shutdown() X{ X (void)kill(1, SIGTSTP); /* Tell init to stop respawning gettys */ X delay(500); X (void)kill(-1, SIGTERM); /* Send termination signal to all */ X delay(5000); X (void)kill(-1, SIGTERM); /* Send it again, just to make sure */ X delay(2000); X (void)kill(-1, SIGHUP); /* Force interactive users off */ X delay(2000); X (void)kill(-1, SIGKILL); /* Forcefully kick everything else */ X delay(5000); X X runit("/sbin/umount", "-a", NULL); /* Unmount all disks */ X X sync(); sync(); sync(); /* Sync root fs */ X delay(500); X X /* System is shut down for all cases and purposes */ X} X X X/* X * This is an alternative to the system(3) library routine that doesn't X * invoke the shell for each command. This is preferable under the X * circumstances in which it will get run -- namely to perform X * housekeeping tasks before killing the system X * X * Number of args limited to 50. It's quick and dirty. X */ X Xvoid Xrunit(char *prog, ...) X{ X int narg = 0, status; X va_list ap; X char *argvec[51], *arg; X X argvec[narg++] = prog; X X va_start(ap, prog); X arg = va_arg(ap, char *); X while (arg) { X argvec[narg++] = arg; X arg = va_arg(ap, char *); X } X argvec[narg++] = NULL; X X va_end(ap); X X switch(fork()) { X case -1: /* Error */ X syslog(LOG_ALERT, "cannot fork %s in run(): %m", prog); X return; X X case 0: /* Child */ X (void)execv(prog, argvec); X exit(1); X X default: /* Parent */ X (void)wait(&status); X } X X return; X} END-of-upsmon.c echo x - upsmon.8 sed 's/^X//' >upsmon.8 << 'END-of-upsmon.8' X.\" Copyright (c) 1997 Gilbert C. Kloepfer, Jr. X.\" All rights reserved. X.\" X.\" Redistribution and use in source and binary forms, with or without X.\" modification, are permitted provided that the following conditions X.\" are met: X.\" X.\" 1. Redistributions of source code must retain the above copyright X.\" notice, this list of conditions and the following disclaimer. X.\" X.\" 2. Redistributions in binary form must reproduce the above copyright X.\" notice, this list of conditions and the following disclaimer in the X.\" documentation and/or other materials provided with the distribution. X.\" X.\" 3. All advertising materials mentioning features or use of this software X.\" in products other than the FreeBSD operating system must display X.\" the following acknowledgement: X.\" X.\" This product includes software developed by Gilbert C. Kloepfer, Jr. X.\" X.\" 4. The name of the author may not be used to endorse or promote products X.\" derived from this software without specific prior written permission. X.\" X.\" THIS SOFTWARE IS PROVIDED BY GILBERT C. KLOEPFER, JR. (THE AUTHOR) X.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT X.\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS X.\" FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE X.\" AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, X.\" EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, X.\" PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR X.\" PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY X.\" OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING X.\" NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS X.\" SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. X.\" X.\" $Id: upsmon.8,v 1.1 1997/01/28 03:20:55 gil Exp $ X.\" X.Dd January 27, 1997 X.Dt UPSMON 8 X.Os BSD X.Sh NAME X.Nm upsmon X.Nd monitor uninterruptable power systems (UPS) X.Sh SYNOPSIS X.Nm upsmon X.Ar tty_device X.Sh DESCRIPTION XThe X.Nm upsmon Xutility monitors the status of a battery-powered Uninterruptable XPower System (UPS) and notifies system users of power-related alerts Xgenerated by the UPS when available. When batteries are dangerously Xdrained (as indicated by the UPS), X.Nm upsmon Xwill also automatically bring the system to a quiescent state and Xinterrupt backup power. X.Pp X.Nm upsmon Xutilizes (abuses?) a serial X.Xr tty 4 Xdevice in such a manner as to be able to examine and manipulate Xindividual bits on the UPS status/control interface. The serial X.Xr tty 4 Xdevice was used due to its low cost and relatively standard device Xcontrol functions. X.Pp X.Nm upsmon Xmakes checks of the UPS monitor interface cable to assure that the Xsignals it receives are valid in order to avoid spirious system Xshutdowns and false warnings. X.Sh INTERFACE DESCRIPTION XThe X.Ar Tripp Lite LAN 2.1 Xinterface was used in the design of this software. Serial I/O Xconnections were made as follows: X.Pp X.Bd -literal -offset left X X RS232 Tripp Lite XSignal Name LAN 2.1 Sig/Pin Description X X CTS Common (1) Common relay & X Low Battery NPN collector X X TxD Inv Shut + (2) Inverter shutdown LED anode X X RTS Line Fail (3) Disconnected from Common when X Relay NO AC line fails or UPS power is off. X This signal is also used by this X application to provide positive X pull-up power for the low battery X phototransistor. X X GND Inv Shut - (4) Inverter shutdown LED cathode X X DTR Line Fail (5) Connected to Common when AC line X Relay NC fails or UPS power is off X X DCD Low Battery (6) Emitter of NPN phototransistor X conducts to Common when on X battery power and battery is low X X RxD, DSR (no connection) X XCable requires 6.2K ohm resistor between pins #3 and #6 (RS232 RTS Xand DCD). This acts as a pull-up resistor for the low battery Xphototransistor output. X X.Ed X.Sh CAVEATS X.Nm upsmon Xwas designed to function with the X.Ar Tripp Lite LAN 2.1 Xspecification. However, porting (via hardware or modification of Xthis software) can be performed to make this function with other Xvendors' UPS systems. Different vendors support different levels Xof functionality on their status ports. X.Pp XEmergency system shutdown before poweroff is handled as well Xas possible by a user-mode program. Since embedding Xhardware-specific kernel code to perform the poweroff function Xwould make this software more sloppy than it already is, a Xcompromise was made when shutting the system down. Before triggering Xthe X.Ar inverter-off Xfunction, all X.Xr getty 8 Xrespawns are stopped by sending a SIGTSTP to X.Xr init 8 , Xall user processes are killed much like is done in X.Xr shutdown 8 , Xall filesystems (except root) are unmounted by performing a X.Xr umount 8 Xcommand, the root filesystem is flushed through X.Xr sync 2 , Xand power is then interrupted. This is better than shutting off the Xpower with all the filesystems mounted and the system active, but Xisn't as good as shutting it down with the standard system shutdown Xcommands. X.Pp XBecause of the previous paragraph, X.Nm upsmon Xmust be compiled static (no shared libraries), and must reside Xsomewhere on the root filesystem (probably /sbin). X.Sh SEE ALSO X.Xr tty 4 , X.Xr init 8 , X.Xr shutdown 8 , X.Xr umount 8 X.Sh BUGS XThe tty device interface was never meant to be used in this way. X.Pp XShutdown is less than perfect, and could theoretically corrupt a Xroot filesystem under extremely rare circumstances. X.Pp XThere is no protection against rabid UPS or serial port failures. X.Sh AUTHOR XGil Kloepfer, Jr., ngk@gc2.kloepfer.org END-of-upsmon.8 exit >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199701300316.VAA07446>