A Watch Timer(WDT)是一个硬件电路可以用来在系统软件发生错误的情况下reset计算机系统。
通常来说一个用户空间的daemon通过特定设备/dev/watchdog,以一定的时间间隔来通知kernel的watchdog驱动系统仍然alive。驱动然后会通知硬件设备一切正常,硬件WDT电路更新reset系统重启的timeout时间。如果用户空间失败(RAM error, kernel bug等等),那么这个通知就不会发生,硬件WDT在timeout到达后就开始重启系统。
所有的驱动都要支持最基本的操作模式:在打开/dev/watchdog后,WDT立刻就被激活了。WDT将reset系统除非每隔一定时间watchdog驱动被ping一下。这个时间间隔被称作timout或者margin。ping watchdog的最简单方法就是向WDT设备写入数据。一个非常简单的应用层watchdog daemon实现参见Documentation/watchdog/src/watchdog-simple.c
当watchdog设备节点被关闭后,如果不支持"Magic Close"功能,watchdog功能就被disable。关闭watchdog功能并不是一个好的实现方式,因为如果是watchdog daemon被不小心关闭(daemon本身的bug, 系统杀掉daemon等等),那么watchdog电路将无法重启系统。基于这个原因,许多watchdog驱动都支持内核配置选项"Disable watchdog shutdown on clost", CONFIG_WATCHDOG_NOWAYOUT. 配置这个内核选项后,那么系统一旦使能了watchdog, 这个功能将不会再被disable。但是这样又有一个问题,就是如果watchdog进程不存在的话,系统一定会重新启动,而不管是不是系统真的必须重启。
Magic Close feature:
如果驱动支持"Magic Close",那么在关闭设备文件后,驱动将不会disalbe watchdog daemon;除非在关闭前把一个特定magic 字符'V'写入watchdog设备。如果userspace daemon没有发送'V',直接关闭了文件,那么watchdog驱动会认为watchdog daemon已经死了,在给定时间内仍然没有喂狗的话就会导致WDT电路重启系统
ioctl API:
所有兼容的驱动都应该支持这个API。
使用ioctl来实现对watchdog的ping操作:
所有的驱动要支持一个ioctl操作WDIOC_KEEPALIVE,WDIOC_KEEPALIVE和write操作有相同的作用,所以watchdog daemon的主循环可以如下方式实现:
while (1) {
inctl(fd, WDIOC_KEEPALIVE, 0);
sleep(10);
}
Setting and getting the timeout:
对于某些驱动,支持在watchdog运行时通过WDIOC_SETTIMEOUT修改timeout,这些驱动的option域设置了WDIOF_SETTIMEOUT标志。这个ioctl操作的参数是一个整数,代表timeout秒数。驱动通过这个参数返回当前设置后timeout,由于硬件电路的限制,这个timeout和请求设置的timeout可能并不相同。
从linux kernel2.4.18开始,增加了GETTIMEOUT ioctl来查询当前的timeout值
Pretimeouts:
有些watchdog支持在重启计算机前某一时间点上,设置一个触发机关。可以通过NMI, interrupt或者其他机制实现。这样允许系统在reset前记录有用的信息(比如panic信息和kernel coredumps)。
pretimeout = 10;
ioctl(fd, WDIOC_SETPRETIMEOUT, &pretimeout);
注意pretimeout是触发时间到系统重启时间点的长度。比如,如果你设置timeout为60, pretimeout为10,那么在50秒的时候(重启之前的 10秒)将触发机关。
操作WDIOC_GETPRETIMEOUT用来获取设置的pretimeout:
ioctl(fd, WDIOC_GETPRETIMEOUT, &timeout);
不是所有的watchdog驱动都支持pretimeout
获取watchdog距离重启的秒数
一些驱动支持获取系统watchdog重启需要的秒数,WDIOC_GETTIMELEFT ioctl用来实现这个功能
ioctl(fd, WDIOC_GETTIMELEFT, &timeleft);
printf("The timeout was is %d seconds\n", timeleft);
环境监测
所有的驱动要求能够返回watchdog系统的一些信息,GETSUPPORT ioctl用来查询设备可以支持哪些信息查询