Linux内核异常自动重启(watchdog and panic)

本文探讨了Linux内核在遇到严重错误时如何自动重启,包括hardwarewatchdog的作用,使用watchdog工具进行测试的方法,以及如何配置内核panic和oops以实现自动重启。通过具体步骤和实例,详细介绍了如何制造kernelpanic,以及系统参数的调整。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Linux内核异常自动重启(watchdog and panic)

一般嵌入式设备都有 hardware watchdog,这样系统出现异常情况时,也能够自动重启而不是设备挂住。
如果系统没有hardware watchdog的前提下,Linux kernel发生panic时,也可以自动重启。
1)watchdog
busybox下的watchdog设置
# watchdog –help
BusyBox v1.27.1 (2018-06-12 09:43:31 CST) multi-call binary.

Usage: watchdog [-t N[ms]] [-T N[ms]] [-F] DEV

Periodically write to watchdog device DEV

    -T N    Reboot after N seconds if not reset (default 60)
    -t N    Reset every N seconds (default 30)
    -F      Run in foreground

Use 500ms to specify period in milliseconds
# watchdog -t 30 /dev/watchdog

watchdog测试
首先是通过ps查看有没有watchdog设置过:
#ps
1071 root 0:00 watchdog -t 30 /dev/watchdog
# kill -9 1071
[17925.103865] watchdog watchdog0: watchdog did not stop!
好像不能直接修改,只能先kill了,然后再设置:
# watchdog -T 1 -t 30 /dev/watchdog
等1s就可以重启,即可测试watchdog有没有开启。

默认是后态运行, -F Run in foreground是前台运行。

2)panic
该文件表示如果发生“内核严重错误(kernel panic)”,则内核在重新引导之前等待的时间(单位为秒)。0,表示在发生内核严重错误时将禁止自动重新引导。缺省设置:0
# cat /proc/sys/kernel/panic
0
# echo 5 > /proc/sys/kernel/panic
# cat /proc/sys/kernel/panic
5
3)oops
内核oops不同于panic,后者会导致OS重启,而设备驱动引发的oops通常不会如此。Oops是由于内核引用了无效指针;发生于用户空间程序通常产生一个段错误segfault,而用户态程序自身无法恢复;发生于内核空间时则称作oops。
# cat /proc/sys/kernel/panic_on_oops
0
# echo 1 > /proc/sys/kernel/panic_on_oops
# cat /proc/sys/kernel/panic_on_oops
1
#
4)怎么制造kernel panic
echo c > /proc/sysrq-trigger
/ # echo c > /proc/sysrq-trigger
[ 124.661311] sysrq: SysRq : Trigger a crash
[ 124.664614] Unable to handle kernel NULL pointer dereference at virtual address 00000000
[ 124.671127] pgd = ffff800037dcd000
[ 124.673850] [00000000] *pgd=00000000b7dcf003, *pud=00000000b7db9003, *pmd=0000000000000000
[ 124.680493] Internal error: Oops: 96000046 [#1] SMP
[ 124.684399] Modules linked in: pfe(C)
[ 124.687340] CPU: 0 PID: 1057 Comm: sh Tainted: G C 4.1.35-rt41 #1
[ 124.693126] Hardware name: LS1012A RDB Board (DT)
[ 124.696894] task: ffff800039547180 ti: ffff8000397d8000 task.ti: ffff8000397d8000
[ 124.702896] PC is at sysrq_handle_crash+0x14/0x20
[ 124.706666] LR is at __handle_sysrq+0x11c/0x190
[ 124.710295] pc : [] lr : [] pstate: 60000145
[ 124.716219] sp : ffff8000397dbd40
[ 124.718870] x29: ffff8000397dbd40 x28: ffff8000397d8000
[ 124.723131] x27: ffff800000830000 x26: 0000000000000040
[ 124.727391] x25: 000000000000011a x24: 0000000000000015
[ 124.731650] x23: 0000000000000000 x22: 0000000000000004
[ 124.735910] x21: ffff800000bc3f50 x20: 0000000000000063
[ 124.740170] x19: ffff800000ba7000 x18: 00000000fffffff0
[ 124.744430] x17: 0000ffffb27ba280 x16: ffff80000019c9f0
[ 124.748690] x15: ffff800000ba7f20 x14: ffff800000c2ac48
[ 124.752950] x13: ffff800000ba7000 x12: ffff800000c2a000
[ 124.757210] x11: 0000000000000000 x10: 000000000000007c
[ 124.761469] x9 : 0000000000000170 x8 : 0000000000000002
[ 124.765729] x7 : 0000000000000001 x6 : 0000000000000170
[ 124.769989] x5 : 000000000000238c x4 : 0000000000000000
[ 124.774248] x3 : 0000000000000000 x2 : 0000000000000770
[ 124.778508] x1 : 0000000000000000 x0 : 0000000000000001
[ 124.782766]
[ 124.783957] Process sh (pid: 1057, stack limit = 0xffff8000397d8028)
[ 124.789048] Stack: (0xffff8000397dbd40 to 0xffff8000397dc000)
[ 124.793655] bd40: 397dbd80 ffff8000 003cd014 ffff8000 00000002 00000000 fffffffb ffffffff
[ 124.800211] bd60: 397dbeb8 ffff8000 00000002 00000000 80000000 00000000 00000015 00000000
[ 124.806767] bd80: 397dbda0 ffff8000 001f9300 ffff8000 397b1280 ffff8000 0019e258 ffff8000
[ 124.813323] bda0: 397dbdc0 ffff8000 0019b57c ffff8000 394f7b00 ffff8000 12acd760 00000000
[ 124.819880] bdc0: 397dbe40 ffff8000 0019bee0 ffff8000 394f7b00 ffff8000 12acd760 00000000
[ 124.826436] bde0: 397dbeb8 ffff8000 00000002 00000000 80000000 00000000 00000015 00000000
[ 124.832992] be00: 0000011a 00000000 394f7b00 ffff8000 397dbeb8 ffff8000 3967b600 ffff8000
[ 124.839548] be20: 397dbe40 ffff8000 0019beb0 ffff8000 394f7b00 ffff8000 12acd760 00000000
[ 124.846104] be40: 397dbe80 ffff8000 0019ca34 ffff8000 394f7b00 ffff8000 394f7b00 ffff8000
[ 124.852660] be60: 12acd760 00000000 00000002 00000000 80000000 00000000 00000000 00000000
[ 124.859216] be80: f8ebea80 0000ffff 00085db0 ffff8000 00000000 00000000 00000001 00000000
[ 124.865773] bea0: ffffffff ffffffff b27ba268 0000ffff 00000200 dead0000 00000000 00000000
[ 124.872329] bec0: 00000001 00000000 12acd760 00000000 00000002 00000000 12acd761 00000000
[ 124.878885] bee0: 12ac0063 00000000 00000000 00000000 80808080 00800000 00000010 00000000
[ 124.885441] bf00: 00000040 00000000 fffffff0 ffffffff 01010101 01010101 004f72e8 00000000
[ 124.891997] bf20: 01010101 01010101 00000000 00000000 004b84a8 00000000 00000008 00000000
[ 124.898553] bf40: 00000000 00000000 b27ba280 0000ffff 00000000 00000000 004f7000 00000000
[ 124.905109] bf60: 00000001 00000000 12acd760 00000000 00000002 00000000 12acd760 00000000
[ 124.911664] bf80: 00000020 00000000 00000000 00000000 004f7000 00000000 12ac8440 00000000
[ 124.918220] bfa0: 00000000 00000000 f8ebea80 0000ffff 0040e8f8 00000000 f8ebe110 0000ffff
[ 124.924776] bfc0: b27ba268 0000ffff 80000000 00000000 00000001 00000000 00000040 00000000
[ 124.931331] bfe0: 00000000 00000000 00000000 00000000 5f787200 6c616f63 65637365 6573755f
[ 124.937882] Call trace:
[ 124.939841] [] sysrq_handle_crash+0x14/0x20
[ 124.944446] [] write_sysrq_trigger+0x54/0x68
[ 124.949122] [] proc_reg_write+0x58/0x88
[ 124.953450] [] __vfs_write+0x1c/0xf8
[ 124.957568] [] vfs_write+0x90/0x1b8
[ 124.961616] [] SyS_write+0x44/0xa0
[ 124.965595] Code: 52800020 b9039820 d5033e9f d2800001 (39000020)
[ 124.970501] —[ end trace bff4483b3310fae9 ]—
[ 124.974199] Kernel panic - not syncing: Fatal exception
[ 124.978384] Rebooting in 5 seconds..

参考文章
【1】http://en.linuxreviews.org/Kernel_panic
【2】http://blog.51cto.com/changfei/1672700 linux系统参数注释
【3】https://szlin.me/2016/05/12/linux-kernel-對於系統發生kernel-panic-自動重啟之原理/
【4】https://stackoverflow.com/questions/49655943/how-to-create-a-kernel-panic-in-rhel-without-rebooting-after-panic
【5】https://unix.stackexchange.com/questions/66197/how-to-cause-kernel-panic-with-a-single-command

### Linux 重启内核的方法及相关原因 #### 方法一:通过命令行工具重启内核Linux系统中,可以通过`reboot`命令来实现系统的重启操作。该命令会触发一系列的关闭和初始化过程,最终调用内核中的机器特定的重启函数,例如`machine_real_restart()`[^1]。此函数通常位于架构相关的源码文件中(如`arch/x86/kernel/reboot.c`),并依赖于底层硬件的支持完成实际的重启动作。 ```bash sudo reboot ``` #### 方法二:手动加载新编译好的内核 当需要更新或替换现有内核时,可能涉及重新编译内核的过程。如果遇到升级后的内核导致系统崩溃的情况,则需仔细对比当前配置与旧版本之间的差异,并调整`.config`文件以匹配稳定状态下的设置[^2]。具体做法包括但不限于将某些内置驱动改为模块形式(`=m`),从而减少潜在冲突点。 另外,在完成了新的自定义内核构建之后,记得创建对应的initramfs镜像以及更新GRUB引导菜单项: ```bash mkinitcpio -P # Arch-based distributions use this command. update-grub # Debian/Ubuntu-like systems may need to run this instead. grub-install /dev/sda # Replace sda with your actual boot device identifier as necessary. ``` 随后即可尝试切换到最新安装的目标内核运行环境。 #### 自动化处理硬锁定状况下强制恢复机制 针对可能出现由于资源耗尽或者死锁引发的应用程序乃至整个操作系统层面的服务终止现象——即所谓的"panic"—可通过激活kernel panic timeout参数设定达到预设时间间隔后自行重置的效果;而对于更深层次涉及到cpu完全丧失控制权的情形(hard lockups), 则依靠性能监控单元(performance monitoring unit)产生的非屏蔽中断(non-maskable interrupt,NMI)来进行诊断判定是否存在此类极端事件发生迹象[^4]: 编辑 `/etc/sysctl.conf`, 添加如下内容: ```conf kernel.panic = 10 # 单位秒, 表示进入内核恐慌模式多久之后自动重启 kernel.nmi_watchdog = 1 # 开启nmi watchdog功能用于探测hardlockup等问题 ``` 应用更改: ```bash sysctl -p ``` 以上措施有助于提高服务器稳定性,尤其是在无人值守环境下部署关键业务服务期间显得尤为重要。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值