ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Linux重启后如何判断是否看门狗触发及定位根因

Linux重启后如何判断是否看门狗触发及定位根因 设备跑着跑着忽然重启业务日志干干净净什么都没留下群里已经有人开始怀疑硬件坏了。这种场景我碰到过很多次每次都不急着换板子而是先查一个特别容易被忽略的元凶——看门狗。在Linux系统里看门狗触发的重启、断电重启、内核panic重启、人为reboot表面上看都是“机器重启了”但日志里其实留有足够的蛛丝马迹。这篇文章就专门说清楚一件事重启之后怎么判断是不是看门狗干的以及怎么顺着线索找到真正让系统“暴毙”的原因。1. 先分清重启类型看门狗不是唯一“背锅侠”1.1 四种常见重启路径现象很接近我在排查重启类问题的时候第一步从来不是去看看门狗而是先把重启的“类型”归个类。Linux服务器或者嵌入式设备的重启归根结底就是下面四种硬件看门狗复位外部看门狗芯片或者SoC内部看门狗超时直接拉复位脚整机硬件级复位。特点是日志突然中断最后一条日志往往和业务没有任何关系甚至就是半句话。内核panic/软锁死/挂起任务内核主动进入异常状态如果配置了panic重启系统会在打印panic信息之后自动重启。这类情况日志里有明显的大段错误输出。用户主动reboot/shutdown有人执行了reboot、shutdown或者systemd触发了重启。日志里有明确的reboot记录和正常的关机流程。断电、电源波动、硬件故障瞬间断电再上电日志同样是突然中断但看门狗电路本身并没有参与。为什么要先分这个类因为看门狗复位和其他类型的处理思路完全不一样。如果是业务进程把内存吃爆导致的panic你去调看门狗超时时间就是白费力气如果是电源模块异常你花一周时间追代码也没用。1.2 先看时间线和启动记录判断重启类型最快的方式是先看系统记录的启动时间和重启历史。三条命令就能搭起一个初步框架last reboot | head -20 uptime -s journalctl --list-bootslast reboot会从/var/log/wtmp里读出每次系统启动的时间点。如果你发现重启时间和你接到告警的时间对得上再去看这次启动距离上一次启动过了多久。uptime -s显示本次系统的启动时间配合date就能算出机器已经运行了多久。journalctl --list-boots尤其关键它会按启动顺序列出所有日志会话比如0 8f2a1f... Wed 2025-01-08 10:22:31 CST—Wed 2025-01-08 11:40:12 CST -1 6b3a1c... Wed 2025-01-08 09:10:03 CST—Wed 2025-01-08 10:22:30 CST看到这种多个boot会话说明系统确实重启过。接下来要做的是对比上一次会话-1的最后日志是什么时间这次重启会话0的开始时间是什么时间。如果两条时间几乎挨在一起没有正常的关机日志那就不是用户主动重启而是异常复位。2. 找证据系统里留着的看门狗“脚印”2.1 journalctl里最值得看的那几行如果看门狗参与过复位虽然日志会断得很突然但往往在断掉之前已经有内核在“求救”了。最典型的线索在上一段启动日志的末尾journalctl -b -1 -n 300 --no-pager重点不是看业务日志而是看内核的诊断信息。下面这几类内容出现时你基本可以锁定系统不是正常关机watchdog: BUG: soft lockup - CPU#0 stuck for 22s! [kworker/0:1:29] INFO: task xxx blocked for more than 120 seconds. kernel: watchdog: watchdog0: watchdog did not stop!第一条soft lockup是内核软锁检测器报出来的意思是某个CPU核在内核态卡了22秒连时钟中断都没能正常处理。这种卡死如果持续下去用户空间喂狗线程也会跟着停掉硬件看门狗随即超时复位。第二条task blocked for more than 120 seconds是hung task机制在报警某个内核线程或者进程在内核态里卡住超过了120秒。这个信息出现后后面往往跟着调用栈你可以顺着调用栈看是卡在驱动里、文件系统里还是内存管理上。第三条watchdog0: watchdog did not stop是内核启动时发现硬件看门狗已经被前一轮启动开启了而当前内核没能关掉它。这说明看门狗在系统复位过程中确实“工作”过。2.2 dmesg和pstore是最后的现场journalctl的数据来自systemd-journald它本身要依赖磁盘和文件系统。如果看门狗强制复位太突然日志缓冲区可能还没来得及落盘那你可能什么都查不到。这就是为什么排查看门狗问题不能只看journald。内核自己的环形缓冲区dmesg里可能有更多信息但重启后dmesg内容会清空。真正能用的是pstore/ramoops机制。很多嵌入式平台和部分服务器会在内存里保留一小块区域专门存内核崩溃前的最后日志重启后挂载到/sys/fs/pstore。ls -l /sys/fs/pstore/ cat /sys/fs/pstore/dmesg-ramoops-0如果这块区域里有内容那绝对是宝贝里面就是内核在复位前最后的遗言。没有pstore的话就得靠外部手段比如串口console日志、带外管理、IPMI的SEL事件这些是判断硬件复位最硬的证据。2.3 看门狗设备和驱动信息想知道本次系统里到底有没有启用看门狗以及超时时间设了多久可以看这些文件ls -l /dev/watchdog* cat /sys/class/watchdog/watchdog0/state cat /sys/class/watchdog/watchdog0/timeout dmesg | grep -i watchdog/dev/watchdog0存在说明内核注册了看门狗设备。timeout文件显示当前超时秒数state显示是active还是inactive。如果驱动启用了nowayout你就算在用户空间把进程杀掉内核也不会释放看门狗系统依然会被复位。在x86服务器上常见的是Intel TCO看门狗日志里可能看到iTCO_wdt。嵌入式平台则常见imx2_wdt、dw_wdt、omap_wdt这类驱动名。看到驱动名你就知道是哪一层在看门狗后面排查驱动超时时间也和它直接相关。3. 理解看门狗触发的底层机制才能不被表象骗3.1 硬件看门狗电路是怎么“杀”系统的很多人把看门狗想得太神秘其实它的本质就是一个独立计数器。以典型的外置看门狗芯片为例芯片有一个喂狗输入端系统正常运行时要定期翻转这个引脚计数器就不断被清零。一旦系统卡死没人喂狗计数器就会数到溢出芯片随即输出复位信号到主板复位脚整个系统被强制重新上电。这个过程对Linux来说是“无感的”。内核不知道外部芯片什么时候复位它日志里自然不会有类似“我要重启了”的告别。你看到的只是日志中断然后系统重新启动。这也就解释了为什么看门狗复位有时什么错误都查不到——它本来就不需要经过软件同意。3.2 软件看门狗与内核软锁检测是两回事Linux里提到看门狗其实要分三层说清楚第一层是硬件看门狗驱动比如softdog模块是纯软件模拟的但它也提供一个/dev/watchdog设备。真正的硬件看门狗驱动直接操作芯片喂狗超时后强制复位。第二层是内核自带的软锁检测器它在kernel/watchdog.c里本质是一个高优先级中断机制定期检查CPU是否还能响应中断。如果CPU卡死超过阈值就会打印soft lockup。这一层默认不直接复位系统只是打印告警。但如果你配了panic_on_warn或者某些内核参数它打印告警后会触发panic进而重启。第三层是用户空间喂狗进程比如systemd服务设置WatchdogSec或者watchdog包里的守护进程。它定期去写/dev/watchdog。如果应用层卡死但内核还正常喂狗进程停止喂硬件看门狗就会超时。明白这三层的区别后排查方向会很清晰如果日志里有soft lockup那是内核层的问题如果完全没有日志只有复位重点怀疑硬件看门狗或者喂狗进程失效。3.3 为什么看门狗重启经常“无日志”排查看门狗问题最痛苦的就是明明它触发过但你什么都查不到。原因有三点第一硬件复位不等软件。内核可能正要写日志数据还在page cache里复位信号一到所有未落盘的数据全丢。第二ext4这类文件系统没有journal的元数据还好但如果正好在写journal可能连上次启动的文件系统状态都受影响。第三串口和网络console如果没有配置内核最后的printk输出无处可去。所以凡是做嵌入式产品的人都会在研发阶段就把pstore/ramoops和串口console打开。这不是可选项而是看门狗问题排查的基础设施。没有这些你只能靠猜。4. 实操排查流程可以直接抄作业的步骤4.1 一组命令先摸清现场不管是什么架构的Linux我建议按下面这个顺序执行。每一步都有明确目的不是随便敲的# 1. 确认重启时间线 last reboot | head -20 journalctl --list-boots # 2. 检查上一段启动的尾部日志 journalctl -b -1 -n 200 --no-pager | tail -100 # 3. 搜关键字 journalctl -b -1 --no-pager | grep -iE watchdog|soft lockup|hung task|panic|oops|reset # 4. 查看本次启动的内核日志 dmesg | grep -iE watchdog|panic|reset|reboot # 5. 看watchdog设备状态 ls -l /dev/watchdog* cat /sys/class/watchdog/watchdog0/state 2/dev/null cat /sys/class/watchdog/watchdog0/timeout 2/dev/null # 6. 检查pstore残留日志 ls -l /sys/fs/pstore/ 2/dev/null cat /sys/fs/pstore/dmesg-ramoops-0 2/dev/null这段流程跑完大部分情况下你已经能得出结论。如果没有结论至少能排除掉70%的可能。4.2 确认看门狗到底有没有被启用有时你看日志半天发现内核里根本没有看门狗驱动那看门狗复位这件事压根不成立方向就得转到电源和硬件上。怎么确认先看内核日志里有没有注册过看门狗驱动dmesg | grep -i watchdog如果输出里有类似iTCO_wdt: initialized或imx2-wdt: device registered说明驱动在跑。再检查设备节点ls -l /dev/watchdog*如果只有一个/dev/watchdog或者/dev/watchdog0说明系统存在可操作的看门狗设备。这时候还要注意光有设备节点不代表它一定在“被喂”。你可以看/sys/class/watchdog/watchdog0/state是active还是inactive。如果是active意味着当前内核正在喂狗你杀掉喂狗进程后系统会在超时后复位。有些平台还支持IPMI带外看门狗在服务器上可以用ipmitool mc watchdog get这条命令能显示BMC看门狗是否启用、超时时间、计数器剩多少。如果BMC看门狗启用且计数器不断减少那就说明它也在计时异常时BMC会直接给主机发复位信号。4.3 还原触发源而不是停留在“谁复位了系统”确认是看门狗复位只是第一步更关键的是还原“为什么没人喂狗”。我一般这么排查如果journalctl -b -1尾部有soft lockup记下CPU编号和卡住的进程名。如果有hung task重点看调用栈里涉及的驱动比如网卡、SD卡、USB控制器。如果日志尾部干干净净那就是喂狗进程自身停了。这时去看是哪个进程在喂狗systemd的WatchdogSec还是独立守护进程。如果是systemd服务启用了看门狗可以查服务的WatchdogSec设置systemctl show 服务名 | grep -i watchdog这一项如果存在systemd会让服务周期性喂狗服务自身卡死超时后systemd会触发系统重启。这类问题往往和服务主进程的业务逻辑有关比如某个请求阻塞了主循环。不要只停在“看门狗把它复位了”这个结论上。看门狗是个执行者不是肇事者真正的肇事者是那个把系统卡死的代码或硬件。5. 排障避坑经验都是实际踩过的5.1 超时时间设得太短开机阶段就被反复复位我在一个项目里遇到过设备频繁重启而且每次重启都发生在启动后2秒内业务日志完全没机会写。后来一查U-Boot里开启的硬件看门狗超时时间是3秒而Linux内核加载驱动前要花掉好几秒。U-Boot启动Linux时没有继续喂狗硬件看门狗直接超时复位于是系统陷入“启动→复位→再启动”的死循环。这种坑在嵌入式平台特别常见。解决办法是在U-Boot阶段就把看门狗关了等内核完全启动、应用进程开始喂狗后再接管或者把U-Boot的看门狗超时时间调到足够长超过整个内核启动时间。5.2 不要一看到看门狗字样就认定是硬件复位内核日志里带watchdog的内容有两种截然不同的含义一种是硬件看门狗驱动另一种是内核的软锁检测器。软锁检测器里的“watchdog”只是个名字它报出来的问题是CPU在内核态卡住不是硬件芯片在复位你。如果你在dmesg里看到watchdog: BUG: soft lockup就跑去查硬件看门狗芯片方向就错了。这时候应该去分析调用栈看是哪个驱动、哪个中断处理函数占用了CPU。很多时候是驱动里的死循环或者中断风暴导致的。5.3 喂狗进程独立于业务进程别把责任推给业务有的用户空间看门狗守护进程只是简单定时写/dev/watchdog不关心业务逻辑。业务进程卡住了、内存池满了、请求队列堵死只要喂狗进程还活着看门狗就不会复位。这时候系统不会重启但业务已经不可用。反过来如果喂狗进程本身没有独立运行或者和某个业务线程耦合在一起那业务线程卡死就会导致喂狗停止最终出发看门狗复位。所以排查时不要只看“业务有没有报错”要搞清楚喂狗动作到底由谁执行。5.4 生产环境千万别为了省事直接禁用看门狗有人为了快速恢复业务会把内核的看门狗驱动卸载或者把喂狗服务mask掉。短期看系统确实不重启了但代价是你失去了一个重要的安全兜底。一旦系统真的陷入死锁没有看门狗兜底你只能靠人工介入恢复这在无人值守的嵌入式场景里是灾难。更合理的做法是把看门狗超时时间调长一点同时打开pstore、串口console让系统即使重启也能留下证据。等定位到根因并修复后再把超时时间调回正常值。最后分享一个排查习惯说真的我自己排查这类问题最依赖的永远是“提前留后路”。凡是我经手的Linux设备只要有条件我都会做三件事内核命令行里加printk.synchronous1或者调低console_loglevel保证关键日志尽量同步输出确认pstore/ramoops分区已挂载有条件就接串口哪怕只是调试阶段临时接一条。这三件事看着不起眼真出问题时能省掉一整个星期的排查时间。如果你现在正在排查一台已经重启的机器我的建议是先把journalctl --list-boots打出来再决定下一步走哪条路。绝大多数情况下问题不是看门狗太“凶”而是系统里确实有地方卡死了只是你还没看到它的调用栈而已。
返回列表