Linux 看门狗(Watchdog)主要用于在系统出现死锁、异常或内核崩溃时,自动触发硬件复位或软件重启,以保障关键服务的可用性。其设置分为硬件看门狗与软件看门狗两种路径,核心机制是通过定时向/dev/watchdog设备写入信号(“喂狗”),若超过超时时间未写入,看门狗硬件或内核模块将强制重启系统。

1. 确认硬件看门狗设备
大多数 x86 平台(如 Intel/AMD 芯片组)和嵌入式开发板(如 ARM 平台)都内置看门狗定时器。在 Linux 下,对应的设备节点通常是 /dev/watchdog 或 /dev/watchdog0。可通过以下命令确认:
ls -l /dev/watchdog*
cat /proc/watchdog
如果设备存在,说明内核已识别硬件看门狗。若不存在,需要加载对应的内核模块,例如 i6300esb(Intel 6300 ESB 芯片组)、sp5100_tco(AMD 芯片组)、imx2_wdt(NXP i.MX 平台)等。使用 modprobe <模块名> 加载,并通过 lsmod | grep wdt 验证。
2. 使用 watchdog 守护进程(用户态软件喂狗)
最常用的标准工具是 watchdog(Unix 守护进程)。它负责周期性地向 /dev/watchdog 写入数据,并监控系统关键指标(如负载、内存、进程状态)。安装与配置步骤如下:
# Debian/Ubuntu
apt install watchdog
# RHEL/CentOS
yum install watchdog
配置文件位于 /etc/watchdog.conf,核心设置包括:
watchdog-device = /dev/watchdog
interval = 1 # 喂狗间隔(秒)
timeout = 60 # 硬件超时时间(秒),需与硬件规格匹配
realtime = yes # 使用实时优先级,防止调度延迟
priority = 1
logtick = 5 # 日志打印间隔
还可以指定监控的进程(若进程消失则触发重启):
pidfile = /var/run/foo.pid
file = /var/log/message
配置完成后,启用并启动服务:
systemctl enable watchdog
systemctl start watchdog
重要:timeout 必须小于或等于硬件看门狗的最大超时值,且 interval 必须小于 timeout,否则可能误触发重启。可用 wdctl 命令查看当前设备支持的超时范围和状态。
3. 直接通过内核接口设置(不依赖用户进程)
在内核配置开启 CONFIG_WATCHDOG 和 CONFIG_WATCHDOG_CORE 后,可以通过 ioctl 或写入 /sys 接口设置超时时间。系统启动时若 bootparam 包含 watchdog=1 或 nowayout=1,则看门狗在驱动加载后立即启动,且不可关闭(防止恶意停止喂狗)。
使用 wdt_set_timeout 工具或直接写 /dev/watchdog 来触发:
# 设置超时时间为 30 秒(先打开设备)
python3 -c "
import fcntl, os
fd = os.open('/dev/watchdog', os.O_WRONLY)
# 常用的 WDIOC_SETTIMEOUT 请求码为 0x80045706(Linux 4.15+),不同架构可能有差异
# 生产环境建议使用 wdctl 或 libwdog 库
os.close(fd)
"
更常见的是使用 wdtutil 或 gpio-wdt(用于 GPIO 看门狗,需在内核设备树中配置 compatible = "linux,wdt-gpio")。
4. 软件看门狗(softdog)
当硬件看门狗不存在时,内核提供 softdog 模块,它模拟看门狗功能,超时后触发内核 panic 或 softlockup 处理。加载方式:
modprobe softdog
echo 10 > /sys/devices/virtual/watchdog/watchdog0/timeout # 设置10秒超时
之后配合 watchdog 守护进程向 /dev/watchdog 喂狗。注意 softdog 不能防断电,但适合应对内核死锁。
5. 使用 systemd 的 watchdog 特性
systemd 可通过向硬件看门狗写入信号来监控系统服务。编辑 /etc/systemd/system.conf:
RuntimeWatchdogSec=20
ShutdownWatchdogSec=10
设置后,systemd 会每 20 秒喂狗一次,并在关闭阶段提供 10 秒的硬件复位窗口。需要系统编译时启用 CONFIG_WATCHDOG 且 systemd 支持(版本 ≥ 220)。
6. 自研喂狗脚本或程序
在嵌入式 Linux 或特殊业务中,常通过 C/C++ 直接操作 open("/dev/watchdog", O_WRONLY) 然后周期写入任意字符串(至少一个字节)来喂狗。示例(C 语言伪代码):
int fd = open("/dev/watchdog", O_WRONLY);
int timeout = 15;
ioctl(fd, WDIOC_SETTIMEOUT, &timeout);
while (1) {
write(fd, "w", 1); // 喂狗
sleep(5);
}
注意:驱动通常要求写的字节数非零;一旦关闭 fd,看门狗可能立即触发复位(取决于 nowayout 选项),因此需保持进程常驻。
7. 关键参数与注意事项
硬件看门狗的心跳超时视芯片而定,常见的 iTCO_wdt 支持 2~600 秒,imx2_wdt 支持 1~128 秒。设置前务必查阅硬件手册或通过 wdctl 输出确认。
务必避免同时启动多个喂狗进程,否则可能导致 EBUSY 错误。若遇到该错误,说明设备被占用,需先停止相关服务。
如果系统使用 nowayout=1 编译内核参数,则喂狗进程退出后看门狗不会自动停止,系统将在超时后重启,这是防止用户意外停止看门狗的安全措施。在调试阶段若需临时关闭,请追加 nowayout=0 或通过 soft_wdt 模块参数控制。
8. 验证看门狗生效
设置后可通过以下方式测试:
# 手动喂狗一段时间,检查系统是否稳定
wdctl /dev/watchdog
# 故意停止喂狗进程,观察系统是否在超时后重启
systemctl stop watchdog
# 等待一段时间,系统应自动复位
对于远端服务器测试需谨慎,避免造成业务中断。
总结:Linux 看门狗设置的核心是识别硬件设备 → 加载驱动 → 配置喂狗守护进程或自研喂狗逻辑 → 设置合理的超时时间。生产环境中最稳妥的方案是使用 watchdog 守护进程,同时结合 systemd 或硬件级 nowayout 提供多层保护。务必根据实际硬件规格调整参数,并确保喂狗线程具有足够高的调度优先级和故障自动重启机制。

查看详情

查看详情