RedHat 7.1J, 7.3, 8 に OMRON BX50XFV(UPS)を接続このページでは、RedHat Linux に、OMRON BX50XFV(UPS)を接続して、シャットダウンソフトに genpowerd を使用した設定例を紹介いたします.RedHat Linux 7.1J に、OMRONの低価格UPS BX50XFVを導入しました. BX50XFVは、POWLI(パウリ、Power Line Insurance)の愛称を持ったUPSで、常時商用タイプの500VA(300W)用のものです. 当初、RedHat Linux 7.1J に導入していましたが、現在(2003年2月)は、RedHat Linux 7.3 および RedHat Linux 8 の上で使用しています.
OMRONのHPによれば、
OMRONのHPによれば、
このページは、Microsoft Internet Explorer 5.5 SP2 と Netscape(R) Communicator 4.73 で動作確認を行っています.
|
|
======= 1)導入背景の章 ===========================================
OMRON の BX50XFV です.
TOPに戻る4年前にBX352とBX510を導入後、特に問題もなく順調に使用していましたが、昨年(2001年)暮れにBX352が昇天してしまいました. 考えてみれば、その間バッテリ交換やメンテナンスなど何もやっておらず、バッテリの寿命が2年程度との事から、まあ、よく持ったものとの思いです. 更新にあたり、Linuxからでもシャットダウンが可能な自動シャットダウンソフトが添付されており、かつ、低価格のものをと物色した結果、このBX50XFV(オムロンダイレクト通販価格 19,800円)が目に止まりました.
|
|
======= 2)実装と設定の章 =========================================
しかし、OMRON のカスタマサポートセンタに問い合わせると、添付の自動シャットダウンソフト「PowerAssistant」は、RedHat Linix 6.2J には対応しているが新しいバージョン 7.1J には対応していない事が判りました.
せっかくですから、24時間稼動しているLinux機でも自動シャットダウン機能を使用したいもので、カスタマサポートセンタに聞くと、あくまで参考情報ですよ、との但し書き付きで下記のURLを教えて頂きました.
ここには、OSに debian、UPSにBX50XFVの姉妹機BX35XFとシャットダウンソフトに genpowerd を使用した例が掲示されています.
今回は、このページと、その中でリンクしている 仙台電波高専熊谷研究室さん のページを参考にしつつ、BX50XFVの取扱説明書と格闘する事になりました.
|
|
通信インターフェイス
BX50XFVとパソコンとの通信インターフェイスは、PowerAssistantプロトコルに対応したシリアル方式と従来からの接点方式の2種類があります.
シリアル方式とは、RS−232Cを用いてパソコン側からコマンドをBX50XFVに送ると、BX50XFVは、コマンドに対応した各種情報を返すことにより、BX50XFVの状態を知るものです.
接点方式とは、BX50XFV側にあるスイッチ(オープンコレクタです)のオン・オフによりBX50XFVの状態を知る方法です.
今回のLinuxでの使用は、従来からの接点方式を使用する事とします.
BX50XFV側の接点方式の場合の信号入出力は下図のような構成になっています. また、信号入出力コネクタは、DSUB9Pinメスです. BUとBLは、オープンコレクタなので何らかの方法でプルアップする必要があります.
|
|
ケーブル
BX50XFVには、自動シャットダウンソフト「PowerAssistant」が添付されており、これ用のケーブルも同梱されています.
このケーブルは、両端がそれぞれ9PinDSUBのオスとメスのコネクタのストレートケーブルです.
今回は、このケーブルを流用したいと考えました. UPS(無停電電源装置)を接続する の記事を読むとDTRとRTSをHighにする必要があると書かれていました. これでプルアップ用の電源は確保できるとしてもプルアップ抵抗がありません.
プルアップ抵抗は、BX50XFVに内蔵されているのだろうと推測し、再び OMRON のカスタマサポートセンタに問い合わせると、次のような返事が返ってきました.
具体的には、BX50XFV側でどのような事が行われているのか詳しく聞く事はできませんでしたが、BX50XFV内部にBUとBLのプルアップ抵抗がある事は確信できました. 同時にBX50XFVの1−4ピンおよび7−8ピン間の抵抗を測ると5〜6KΩとなっていました.
こんな経緯があり、ケーブルはBX50XFVに同梱されているケーブルをそのまま使用する事となりました.
|
|
信号線のまとめ
これらのことをまとめると、
TOPに戻る
|
|
======= 3)genpowerd の設定の章 =============================
|
|
genpowerd の入手
sunsite より入手可能です. 現在、genpower-1.0.2.tar.gz が最新バージョンのようです.
sunsite 以外でも Google 等の検索サイトでダウンロード可能なサイトが見つかります.
適当な場所にコピー後、
|
|
genpowerd.h の編集
{NULL} の行の前に、第2章の検討結果で得られたBX50XFVの信号仕様に合わせた設定を加え、末尾の PWRSTAT と UPSSTAT の定義を変更します.
|
/* OMRON BX35/50XFV */
{7, "omron-powli", {(TIOCM_DTR | TIOCM_RTS),0}, {TIOCM_ST,0}, 10, {TIOCM_CTS,0}, {TIOCM_CAR,0}, {0,0}},
{-1, NULL}
};
・
・
#define PWRSTAT "/var/run/powerstatus"
#define UPSSTAT "/var/run/upsstatus"
設定内容
|
|
genpowerfail の編集
genpowerd.h の修正に合わせて upsstatus のパスを変更とシャットダウン動作を再起動 -r から停止 -h に全て変更します.
さらに、case "$stats" in の中の処理を少々変更・追加します.
|
# Set location of upsstatus file
statpath="/var/run/upsstatus"
・
・
・
if [ -r $statpath ]
then
stats=`head -1 $statpath`
case "$stats" in
FAIL) # Power is down
shutdown -h +15 "THE POWER IS DOWN! SHUTTING DOWN SYSTEM! PLEASE LOG OFF NOW!" < /dev/console &
;;
SCRAM) # Battery is low
shutdown -c "THE POWER IS DOWN!"
shutdown -h now "THE POWER IS DOWN! BATTERY POWER IS LOW! EMERGENCY SHUTDOWN!" < /dev/console &
;;
CABLE) # Possible bad cable
shutdown -h +1 "POSSIBLE BAD CABLE! SHUTTING DOWN SYSTEM! PLEASE LOG OFF NOW!" < /dev/console &
;;
OK) #
shutdown -c "THE POWER IS BACK-02"
;;
*) # Unknown message, assume power is down
shutdown -h +2 "THE POWER IS DOWN! SHUTTING DOWN SYSTEM! PLEASE LOG OFF NOW!" < /dev/console &
;;
esac
else
# genowerfail called, and upsstatus dosen't exist.
# Assume user is using powerd, and shutdown.
shutdown -h +2 "THE POWER IS DOWN! SHUTTING DOWN SYSTEM! PLEASE LOG OFF NOW!" < /dev/console &
・
・
|
|
genpowerd のコンパイルとインストール
make all
su <== ルート権限に make install |
|
その他の変更と設定
/etc/inittab
停電時の処理として genpowerfail を使用するように変更する. # When our UPS tells us power has failed, assume we have a few minutes # of power left. Schedule a shutdown for 2 minutes from now. # This does, of course, assume you have powerd installed and your # UPS connected and working correctly. #pf::powerfail:/sbin/shutdown -f -h +2 "Power Failure; System Shutting Down" pf::powerfail:/etc/genpowerfail start # If power was restored before the shutdown kicked in, cancel it. #pr:12345:powerokwait:/sbin/shutdown -c "Power Restored; Shutdown Cancelled" pr:12345:powerokwait:/etc/genpowerfail stop
/etc/rc.d/rc.local
Linuxの起動時に genpowerd を起動するように変更する. rc.local の末尾に追加します. omron-powli は、genpowerd.h に追加したUPSの名称
# ADD support for the BX50XFV
echo "Starting genpowerd daemon..."
if [ -x /sbin/genpowerd ]; then
/sbin/genpowerd /dev/UPS omron-powli
fi
/etc/rc.d/init.d/halt
shutdown 時にUPSを停止するように変更する. halt の末尾の直前に追加します.
# Shutdown by the argument -k of genpowerd.
if [ -r /var/run/upsstatus ]; then
status=`head -1 /var/run/upsstatus`
# If the status of UPS is not OK.
if [ $status != "OK" ]; then
echo "Killing Power..."
sleep 5
genpowerd -k /dev/UPS omron-powli
fi
fi
# Now halt or reboot.
echo $"$message"
if [ -f /fastboot ]; then
echo $"On the next boot fsck will be skipped."
elif [ -f /forcefsck ]; then
echo $"On the next boot fsck will be forced."
fi
HALTARGS="-i -d"
if [ -f /poweroff -o ! -f /halt ]; then
HALTARGS="$HALTARGS -p"
fi
eval $command $HALTARGS
シンボリックリンクの設定
BX50XFVの監視に使用するCOMポートを設定します. COM1 ならば、/dev/cua0 を、COM2 ならば、/dev/cua1 を指定します. ln -s /dev/cua0 /dev/UPS |
|
TOPに戻る
|
|
======= 4)動作検証の章 ====================================
この動作検証を行っているあいだLinux機は、検証中のBX50XFVから電源の供給を受けるのではなく別の電源に接続します.
また、Linix機を再起動して genpowerd デーモンを起動させておきます.
|
|
停電時および電源復帰時の動作検証
|
|
バッテリ容量低下時の動作検証
TOPに戻る
|
|
======= 5)gentest の章 ====================================
ダウンロードした genpowerd には、UPSの挙動(正常動作や停電時の信号線の様子)やケーブルの接続状態をテストする gentest というプログラムが入っています.
使用方法は、
# gentest [-r -d] <serial port>-r :RTSをHighに設定する. -d :DTRをHighに設定する.
# gentest -r -d /dev/UPS --------------- DTR = Set RTS = Set CAR = High (*) CTS = High (*) DSR = High (*) RNG = Low ( )
起動すると各端子の情報を表示します. 変化のあった端子は (*) を付けて表示されます.
CAR は、DCD の事です. CTRL + C で停止するまで各端子に変化があるたびに新しい情報を表示してくれます.
次の実行例は、genpowerd を起動中に gentest も並行して起動後、BX50XFVを正常 → 停電 → 電源復帰と変化させたものです. # gentest -r -d /dev/UPS --------------- DTR = Set RTS = Set CAR = High (*) CTS = High (*) DSR = High (*) RNG = Low ( ) --------------- DTR = Set RTS = Set CAR = High ( ) CTS = Low (*) <== 停電 DSR = High ( ) RNG = Low ( ) Broadcast message from root (console) Sun Jan 20 21:30:40 2002... THE POWER IS DOWN! SHUTTING DOWN SYSTEM! PLEASE LOG OFF NOW! The system is going DOWN for system halt in 15 minutes !! --------------- DTR = Set RTS = Set CAR = High ( ) CTS = Low ( ) DSR = High ( ) RNG = High (*) --------------- DTR = Set RTS = Set CAR = High ( ) CTS = High (*) <== 電源復帰 DSR = High ( ) RNG = Low (*) Broadcast message from root (console) Sun Jan 20 21:30:49 2002... THE POWER IS BACK-02
|
|
======= 6)起動時のUPS接続確認の章 =========================
普段、パソコンがUPSから電源の供給を受け、監視用のケーブルがUPSに接続されていれば別段問題はないのですが、第3章の設定のままでは、メンテナンスなどで他の電源に接続し監視用のケーブルを取り外して起動すると、起動直後にシャットダウンが開始されてしまいます.
これには、いささか抵抗を感じます. まあ、root でログインして2分以内に shutdown -c を実行すればいいのですがちょっと情けない気がします. そこで、rc.local で genpowerd を起動する前に監視用のケーブルが接続されているかどうかを確認後、ケーブルが接続されている時だけ genpowerd を起動する事とします.
まず、監視用のケーブルが接続されていない状態を gentest で調べてみます. # gentest -d -r /dev/UPS
---------------
DTR = Set
RTS = Set
CAR = Low ( )
CTS = Low ( )
DSR = Low ( )
RNG = Low ( )
すべての信号線が Low となってます. この中で CTS をチェックするプログラム genchk.c を作成しました.BX50XFVが正常に動作しておれば、CTS は High であり、停電時は Low となります. しかし、パソコンが起動している事を考えれば停電では無いと確信できる訳です. そこでパソコンが起動しているにも関わらず CTS が Low である事は監視ケーブルが外れているものと認識します. しかし、本番環境であってもケーブルが外れたままでもパソコンが起動してしまいますので起動後に genpowerd が起動している事を確認する注意が必要です. このプログラムは、CTS が High ならば "OK" を、そうでなければ "ERR" を標準出力へ出力します. プログラム genchk.c #include <sys/types.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
/* Main program. */
int main( int argc, char **argv ) {
int fd;
int rts_bit = TIOCM_RTS;
int dtr_bit = TIOCM_DTR;
int flags;
int flags2;
/*************************/
/* Monitor the CTS line. */
/*************************/
/* Open monitor device. */
if ( ( fd = open( argv[1], O_RDWR | O_NDELAY ) ) < 0 ) {
fprintf( stderr, "%s: Open Error\n", argv[1] );
printf( "ERR\n" );
exit( 1 );
}
ioctl( fd, TIOCMBIS, &rts_bit );
ioctl( fd, TIOCMBIS, &dtr_bit );
sleep( 2 );
/* Get the CTS status. */
ioctl( fd, TIOCMGET, &flags );
flags &= TIOCM_CTS;
ioctl( fd, TIOCMGET, &flags2 );
flags2 &= TIOCM_CTS;
if ( flags && flags2 ) {
printf( "OK\n" );
exit( 0 );
}
printf( "ERR\n" );
exit( 1 );
}
コンパイル・インストール % gcc -O -o genchk genchk.c
% su <== root 権限に
# cp -p genchk /sbin/
# chown root.root /sbin/genchk
# chmod 754 /sbin/genchk
/etc/rc.d/rc.local の変更
今までの設定を下記のように置き換えます. # ADD support for the BX50XFV
echo "Starting genpowerd daemon..."
if [ -x /sbin/genpowerd ]; then
if [ -x /sbin/genchk ]; then
genstat=`/sbin/genchk /dev/UPS`
if [ $genstat = "OK" ]; then
/sbin/genpowerd /dev/UPS omron-powli
fi
fi
fi
|
|
======= 7)RedHat 7.3 対応の章 ================================
今年(2003年)の正月休みを利用して各システムを RedHat 7.3 へ移行しました.
RedHat 7.3 への移行にあたり、前章での内容はそのまま使用できます. ここでは、RedHat 7.3 への移行にあたり、genpowerd 等を RedHat 7.3 の環境で再コンパイル・インストール時の警告などの解消方法について記述します. コンパイル時に、若干の警告と、インストール時に man8 のディレクトリが無いと文句を言われます. まあ、実際の動作には影響ないのですが・・・
この現象は、内容からして RedHat 7.1 の時代からあったものと思います. つまり、筆者がこのページへ書き忘れていただけのようです.
コンパイル時の警告は、strcmp と strcpy 関数用のプロトタイプ宣言が無いために生じるものです.
下記のように、genpowerd.c と gentest.c に #include <string.h> を追加します.
genpowerd.c #include <signal.h> #include <syslog.h> #include <string.h> #include "genpowerd.h"
gentest.c
#include <stdio.h> #include <signal.h> #include <string.h> #define MAXSTRING 10
次に、インストール時の man8 のディレクトリは、下記のように Makefile を修正します.
Makefile SCRIPTDIR = /etc MANDIR = /usr/share/man/man8 OWNER = root
|
|
======= 8)RedHat 8 対応の章 ================================
故あって、RedHat 8 でも UPS を使用する事となってしまいました.
RedHat 7.3 で無事コンパイルが完了しているので RedHat 8 でも問題なかろうと安易に考えていたのですが、コンパイラはしっかりと警告を出してくれました(笑).
$ make cc -N -Wall -O6 genpowerd.c -o genpowerd /tmp/ccvcKK0D.o: In function `main': /tmp/ccvcKK0D.o(.text+0x421): `sys_errlist' is deprecated; use `strerror' or `strerror_r' instead cc -N -Wall -O6 gentest.c -o gentest /tmp/cc8izhey.o: In function `main': /tmp/cc8izhey.o(.text+0x225): `sys_errlist' is deprecated; use `strerror' or `strerror_r' instead
genpowerd.c と gentest.c で sys_errlist を使っているのが気に入らなくて、strerror か strerror_r を使えと言っているようです.
RedHat 7.3 の修正に加えて、genpowerd.c で2箇所、gentest.c で1箇所を下記のように修正します. genpowerd.c if (pups->killtime) {
if ((fd = open(argv[1], O_RDWR | O_NDELAY)) < 0) {
fprintf(stderr, "%s: %s: %s\n",program_name, argv[1], strerror(errno));
exit(1);
} /* if ((fd = open(argv[1], O_RDWR | O_NDELAY)) < 0) */
/* Open monitor device. */
if ((fd = open(argv[1], O_RDWR | O_NDELAY)) < 0) {
syslog(LOG_ERR, "%s: %s", argv[1], strerror(errno));
closelog();
exit(1);
} /* if ((fd = open(argv[1], O_RDWR | O_NDELAY)) < 0) */
gentest.c
/* Open monitor device. */
if ((fd = open(argv[1], O_RDWR | O_NDELAY)) < 0) {
fprintf(stderr, "%s: %s", argv[1], strerror(errno));
exit(1);
} /* if ((fd = open(argv[1], O_RDWR | O_NDELAY)) < 0) */
これで無事コンパイルが通ります. これ以外は、RedHat 7.1j, 7.3 と同様です.
TOPに戻る
|
|
参考資料
|
|
|
|
||
|
|
||