【轉】用普通UPS實現停電監測

我們單位使用的服務器是一臺LINUX服務器,由於經費有限,無法購買昂貴的在線式UPS.而只是購買了一臺APC BACK 500(RMB 500). 在外電源切斷時,其說明書稱可以維持電源供應約15分鐘。
如果在15分鐘內無法來電,而該服務器又無法正常關閉,輕則丟失數據,重則導致系統崩潰,無法啓動。這是我們所不希望出現的情況。
爲解決上述問題,我們考慮了用廉價的UPS開發自己適用的UPS系統,該系統的唯一要求是: 在停電時自動關閉計算機,確保系統的安全。

要解決上述問題,必須解決兩個關鍵性的技術問題:
1)硬件上如何檢測停電,並將停電信號傳給計算機?
2)在Linux 系統中如何用守護程序來完成對停電信號的響應,自動關閉計算機?

我們知道,在計算機的串行口中有一些輸入/輸出腳,例如,DCD(載波檢測)(25針8腳,
9針1腳)。我們的基本思路是通過DCD腳信號的變化來檢測是否停電。具體做法如下:
從市面上採購一個6V-12V/100mA-500mA的穩壓電源作爲停電檢測傳感器,把其輸出的電壓調整到
9V,在其輸出的線纜上串接一個3K的電阻(阻抗匹配用)後與一串口線的DCD腳相連接,其地線
與串口的數字地(25針7腳,9針5腳)相連接。將該穩壓電源與UPS輸入端接在同一個接線板上,
平時正常供電時,DCD腳的電平將也爲高(9V),而一旦停電時,DCD腳的電平將發生變化,通過
檢測這種變化,我們就可以實現停電自動關機。

電路連結示意圖如下:

PC< --->UPS<--->POWER
| |
|<-- 穩壓電源<---|


Linux 下停電監測守護程序power.c如下:
#include〈sys/ioctl.h>
#include〈fcntl.h>
int main(int argc, char *argv[])
{
int fd;
int flags;
/*打開串行口*/
if((fd=open(argv[1],O_RDWR |O_NDELAY))<0)
{
printf("usage: power /dev/cua0 or power /dev/cua1\n");
exit(1);
}
/*兩次調用fork()&setsid()系統調用,使程序成爲守護進程*/
if(fork()) exit(0);
if(setsid()==-1) exit(1);
if(fork()) exit(0);
if(setsid()==-1) exit(1);
for(;;)
{
ioctl(fd,TIOCMGET, &flags);/*從串行口讀入DCD信號*/
flags=flags & 0x0040;
if(flags == 0)/*檢測flags低字節的第7位如果不爲1,則關機*/
system("/sbin/shutdown -h now");
sleep(300);/*每5分鐘檢測一次*/
}
}

在Linux系統中執行如下命令序列:

gcc power.c -o power
mv power /sbin/.

vi /etc/rc.local 在rc.local中加入 :
power /dev/cua0 (com1作監測口) 或
power /dev/cua1(com2作監測口)

重新啓動計算機,即啓動了該守護程序。

該系統投入使用後經多次停電的檢驗均正常工作,保證了服務器的安全

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章