技术解析

一次奇怪的 kernel panic 解决,但求甚解
0
2021-07-08 10:58:16
idczone

楼主的一台 Linode ,运行好好的突然就 kernel panic 了,不能重启,重启有很大概率无法启动——成功的概率大概小于 1%,不要问我怎么计算的,的确进去过一次...

首先说频繁重启肯定是 Lassie 狗的原因,检测到系统没有启动就会尝试 reboot ,这并不是问题

问题在于看到 dmesg 的一瞬间楼主就傻了,贴一小段出来:

Entering non-interactive startup
Calling the system activity data collector (sadc)...
ipset: Loaded with no configuration
ip6tables: Applying firewall rules: [ OK ]^M
iptables: Applying firewall rules: [ OK ]^M
Bringing up loopback interface: [ OK ]^M
Bringing up interface eth0: BUG: unable to handle kernel NULL pointer dereference at 0000000000000030

这是在说 eth0 无法启动啊?不过楼主非常确信没有改过网卡的配置。

于是改为 Single 模式启动, Lish 进去,先检查了一下配置信息,看起来都没什么问题,然后楼主就在拼命回忆之前修改了哪些配置,然并卵,因为很久没重启过了已然记不清了。

没办法,只好先禁用一部分启动项,把和网络有关的都 chkconfig off 掉了,改回正常运行模式,重启,喵了个咪,起来了!

于是非常确定嫌犯就在这些启动项里面,最后逐个排查的结果(点重启点到手断),居然是 iptables 导致的!

于是尝试清空了 iptables 的全部规则,重新 chkconfg iptables on ,重启,没问题!

那么问题必然出在规则上面了!

楼主尝试添加了之前删除的规则,没问题! service iptables save 重启!擦,又特喵的挂了!

那么这几条规则到底是什么呢?还是贴一小部分出来:

-A PREROUTING -p tcp -m multiport --dports 60000:60199 -j REDIRECT --to-ports XXXX
-A PREROUTING -p udp -m multiport --dports 60000:60199 -j REDIRECT --to-ports XXXX
-A PREROUTING -p tcp -m multiport --dports 60200:60399 -j REDIRECT --to-ports XXXX
-A PREROUTING -p udp -m multiport --dports 60200:60399 -j REDIRECT --to-ports XXXX

其实就是个范围端口重定向,看起来很正常啊,不过只要 iptables 启动的时候有这些规则,必死无疑。

想到这里的时候,楼主本来都准备放弃治疗了,干脆启动后动态载入这些规则罢了。

不过奇迹的瞬间就这么来了,楼主最后一次超载了智商,突然想起来,前几天修改过 sysctl 里面的一个参数 net.ipv4.ip_local_port_range

赶紧打开配置文件看,现在是 net.ipv4.ip_local_port_range = 1024 65535

难道是这个端口范围和我的重定向存在冲突?赶紧修改为 1024 59999 ( 60000 以后的楼主都做了重定向),保存全部规则,重启,妥了。

那么问题来了,且问各位看官,端口重定向为何会引发 kernel panic ?
和 ip_local_port_ranged 的冲突又是怎么形成的?


我这默认是 32768 61000 啊,怎么会改到那么奇怪的数字的……。
其实你这个说不定是个 bug ,去 kernel 那边报一下?
应该是最新版 kernel 吧。

Linode 自带的不算新吧, 4.1.5 啊
所以我暂时没有考虑是 kernel 的 bug

楼主试试改成 1024: 60398 有错没

看错了,请忽略上条...

eth0: BUG: unable to handle kernel NULL pointer dereference at 0000000000000030
空指针解引用,然后内核挂了。
这当然是 kernel 的 bug 啊, consle.log 里应该有不少的 Call Trace 吧。
建议换 kernel 试试,排除下先么。
要求甚解,就仔细读 Call Trace 或 配 kdump 抓 vmcore 慢慢研究,或者找到稳定的重现步骤,报 bug 给 upstream 让他们去研究也是极好的。

今天晚些时候我切换成 Release 版本内核尝试一下,现在用的是 L 记的优化内核。

发个 kernel dump 吧,这种要通过 crash core 和代码综合分析了。

数据地带为您的网站提供全球顶级IDC资源
在线咨询
专属客服