我们单位使用的服务器是一台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作监测口)
重新启动计算机,即启动了该守护程序。
该系统投入使用后经多次停电的检验均正常工作,保证了服务器的安全
【转】用普通UPS实现停电监测
最新推荐文章于 2024-08-27 15:08:04 发布