分类: LINUX
2009-02-17 16:38:17
Linux 在不同领域如电信、终端便携设备等得到广泛应用,不同领域的应用对 Linux系统也提出相应的需求。Carrier Grade Linux 是 OSDL(Open Source Development Lab)发布的电信级 Linux 的标准,在系统可用性这部分指出 Linux 必须支持 watchdog 机制。Linux 内核从 1.3.51 版本开使提供硬件、软件 watchdog 驱动。随着内核的发展,Linux 对不同类型的硬件 watchdog 卡提供了广泛的支持。本文首先介绍 Linux 内核对硬件、软件 watchdog 的支持;然后通过一个开源项目watchdog daemon介绍如何在一个系统监控应用中加入 watchdog 的使用以提高系统的可用性,以及如何在一个 Linux 服务应用中加入watchdog 模块以提高应用的可用性。
Watchdog在实现上可以是硬件电路也可以是软件定时器,能够在系统出现故障时自动重新启动系统。在Linux 内核下, watchdog的基本工作原理是:当watchdog启动后(即/dev/watchdog 设备被打开后),如果在某一设定的时间间隔内/dev/watchdog没有被执行写操作, 硬件watchdog电路或软件定时器就会重新启动系统。
/dev/watchdog 是一个主设备号为10, 从设备号130的字符设备节点。 Linux内核不仅为各种不同类型的watchdog硬件电路提供了驱动,还提供了一个基于定时器的纯软件watchdog驱动。 驱动源码位于内核源码树drivers\char\watchdog\目录下。
对于应用程序而言, 操作软件、硬件watchdog的方式基本相同:打开设备/dev/watchdog, 在重启时间间隔内对/dev/watchdog执行写操作。即软件、硬件watchdog对应用程序而言基本是透明的。
在任一时刻, 只能有一个watchdog驱动模块被加载,管理/dev/watchdog 设备节点。如果系统没有硬件watchdog电路,可以加载软件watchdog驱动softdog.ko。
在Linux下使用watchdog开发应用之前, 请确定内核已经正确地配置支持watchdog。内核源码下的drivers/char/watchdog/Kconfig文件提供了各种watchdog配置选项的详细介绍。特别指出关于‘CONFIG_WATCHDOG_NOWAYOUT’选项的配置,从清单1软件watchdog的模块信息可以看到,nowayout参数的缺省值等于‘CONFIG_WATCHDOG_NOWAYOUT’, 如果‘CONFIG_WATCHDOG_NOWAYOUT’选项在内核配置时设为‘Y’, 缺省情况下,watchdog启动后(即/dev/watchdog被打开后),无论是执行close操作还是写入字符‘V’都不能停止watchdog的运行。
linux-mach:~ # modinfo softdog filename: /lib/modules/2.6.16.21-0.8-smp/kernel/drivers/char/watchdog/softdog.ko author: Alan Cox description: Software Watchdog Device Driver license: GPL alias: char-major-10-130 vermagic: 2.6.16.21-0.8-smp SMP 586 REGPARM gcc-4.1 supported: yes depends: srcversion: EAE9E5688843C073B0EF5BC parm: soft_noboot:Softdog action, set to 1 to ignore reboots, 0 to reboot (default depends on ONLY_TESTING) (int) parm: nowayout:Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT) (int) parm: soft_margin:Watchdog soft_margin in seconds. (0 |
在开发应用之前,必须了解所用的watchdog驱动的重启时间间隔。各种硬件以及软件watchdog驱动都设有一个缺省的重启时间间隔,此重启时间间隔也可在加载驱动模块时设置。
从清单1软件watchdog的模块信息可以看到,soft_margin参数代表了softdog.ko的重启时间间隔,缺省值是60秒,可以在加载softdog.ko 时指定重启时间间隔, 如 `modprobe softdog soft_margin=100`。
各种硬件以及软件watchdog驱动都为应用提供了相同的操作方式。打开/dev/watchdog设备,watchdog将被启动。如果在指定重启时间间隔内没有对/dev/watchdog执行写操作,系统将重启。
int wdt_fd = -1; wdt_fd = open("/dev/watchdog", O_WRONLY); if (wdt_fd == -1) { // fail to open watchdog device } |
如果内核配置选项‘CONFIG_WATCHDOG_NOWAYOUT’设为‘Y’, 缺省情况下watchdog启动后不能被停止。 如果模块的nowayout参数设为0, 往/dev/watchdog 写入字符`V’ 可以使watchdog停止工作。可以参考参考文献二2.6内核源码drivers\char\watchdog目录下各种硬件及软件watchdog驱动的write函数得到停止watchdog的逻辑, 譬如软件watchdog驱动softdog.c 中的write函数。
参考文献三watchdog daemon源码 watchdog-5.4.tar.gz的 close_all函数提供了停止watchdog运行的范例。以下是一个简单的停止watchdog的代码段范例:
if (wdt_fd != -1) { write(wdt_fd, "V", 1); close(wdt_fd); wdt_fd = -1; } |
从1.6节中提到的softdog模块的write函数可以看到,在watchdog重启时间间隔内执行写操作,softdog_keepalive将被调用,增加定时器定时时间。
所以应用在启动watchdog后,必须在重启时间间隔内,周期性地对/dev/watchdog执行写操作才能使系统不被重启。
参考文献三watchdog daemon源码 watchdog-5.4.tar.gz的keep_alive函数提供了保持watchdog运行的范例。以下是一个简单的保持watchdog运行的代码段范例:
if (wdt_fd != -1) write(wdt_fd, "a", 1); |
不同的系统与应用有自己的监控需求,不同的被监控对象有相应的监控方法。下文第一部分介绍了一个Linux下的开源项目watchdog daemon。 这是一个系统监控的后台应用,通过从配置文件中读取监控对象以及监控参数等信息对系统进行内存、负载、进程、网络等方面的监控, 同时将各种监测信息记入系统日志,并能够在系统重启之前发email通知管理员。通过阅读这个项目的源码可以学习到:
当Linux用于电信、 嵌入式领域, 一些基于Linux操作系统开发的服务应用在可用性上有较高的要求,下文第二部分介绍了如何在这种类型的应用中加入watchdog机制以提高应用的可用性。
watchdog daemon是一个Linux下使用了watchdog的系统监控的后台应用。开发人员可以下载最新的watchdog_5.4.tar.gz源码。 参见参考资源下载源码。
Watchdog daemon主程序运行流程如下:
如果没有在配置文件中设置某些配置信息, 相应的检测将不被执行。
如果检测返回错误, 检测返回值显示故障可以修复,同时配置文件中也设置了修复程序, 修复程序将会被调用。如果修复故障失败,主程序将会尝试执行一系列清理、记载日志、email通知管理员的操作,然后重新启动系统。必须注意的是,当检测发现错误时,主程序并不是退出while(1)循环,使/dev/watchdog在1分钟内没被执行写操作而导致系统被动重启; 而是执行一系列操作后主动重启系统,这样既可以记录下日志信息,email通知管理员,也可以防止系统被动重启导致文件系统损坏。
主程序在主动重启之前, 会执行以下一系列操作:
从以上程序框架可以看到,监控应用检测出系统故障时,在系统可控的状态下,应用会尝试主动重启系统。但是通过启动watchdog,能够在系统不可控,或是监控应用自身不能正常运行时,由watchdog自动启动系统。
watchdog daemon根据配置文件对系统进行以下类型的监控,并将每次检测的结果记入系统日志:
watchdog daemon提供了一些常用的很有参考价值的监控方法及源码,开发人员也可自行设计开发更丰富的监控方法对系统进行更为细致、全面的监控。
Linux因为其强大的功能已成为很多企业级应用的开发平台。这些应用本身并不是一个监控程序而是一个管理或服务程序, 对可用性有较高的要求。通过在这类应用中加watchdog模块, 一方面监测系统状态, 另一方面监测此应用中其它模块的工作状态。系统出现故障时能自动重启,因为应用已加在系统的init.d启动服务中, 应用会随着系统的启动而启动,自动提供服务。
这类服务应用通常是多线程的,甚至是多进程的。 加入watchdog机制的通常作法是在应用中加入一个watchdog线程,此线程主循环的工作流程与上节介绍的系统监控应用的守护进程的主循环工作流程大致相似。Watchdog线程在进入主循环之前的初始化阶段打开/dev/watchdog 启动watchdog, 然后执行上节中提到的while(1)循环中的操作。
如果此应用是多进程的,子进程的fork可以放在watchdog线程的初始化阶段执行。 Watchdog线程可以获得这些子进程的pid,从而检测这些子进程的工作状态。
Watchdog线程除了可以参照上节watchdog daemon提供的方法对系统状态进行监控, 还可以通过消息队列或套接口与应用中的其它线程进行通信, 获得其它线程的工作状态。不过这需要在其它子线程中加入与watchdog线程进行通信的接口。
周婷,软件工程师,目前在 IBM 中国系统技术实验室从事服务器管理固件的开发工作 |