记一次Linux内核崩溃(Kernel Panic)日志分析:Lustre文件系统与锁竞争引发的宕机
事件背景
近期,监控系统(Prometheus)发出告警,提示OpenLava计算平台服务不可用。初步排查发现,计算节点上的Lustre文件系统挂载点消失,系统响应中断,怀疑是Linux内核崩溃导致。本次故障发生在2025年09月05日下午16:42左右,节点随后触发了kdump生成了vmcore转储文件。以下是对该次内核崩溃的详细分析记录。
一、崩溃环境信息
项目 | 信息 |
---|---|
崩溃时间 | 2025-09-05 16:42:14 |
节点IP | 127.0.0.1 |
转储文件 | /var/crash/127.0.0.1-2025-09-05-16:42:14/vmcore |
内核版本 | $(uname -r) (分析时实际获取) |
故障进程 | rex (PID: 2115) |
相关文件系统 | Lustre (客户端模块: osc, ptlrpc, obdclass) |
二、初步排查与日志捕获
系统崩溃后,首先检查了系统日志以确认崩溃原因:
# 检查内核环形缓冲区日志
dmesg -T | grep -i "panic\|oops\|error" > kernel_crash.log
# 检查系统日志(因节点已重启,需查看历史日志)
grep -i "panic\|lustre\|rex" /var/log/messages /var/log/kern.log >> kernel_crash.log
在日志中发现了 Kernel panic - not syncing
的相关信息,表明系统遇到了严重错误。由于配置了kdump,系统在崩溃时生成了vmcore转储文件,为分析提供了基础。
三、使用Crash工具分析内核转储
1. 启动Crash调试环境
使用crash工具加载vmcore和调试符号文件:
crash /usr/lib/debug/lib/modules/$(uname -r)/vmlinux /var/crash/127.0.0.1-2025-09-05-16\:42\:14/vmcore
2. 查看崩溃时的调用栈(Backtrace)
在crash环境中执行 bt
命令,获取崩溃时的详细调用栈:
crash> bt
PID: 2115 TASK: ffffa17747992100 CPU: 30 COMMAND: "rex"
#0 [ffffa16bf706f4f8] machine_kexec at ffffffff97669504
#1 [ffffa16bf706f558] __crash_kexec at ffffffff97729d32
#2 [ffffa16bf706f628] crash_kexec at ffffffff97729e28
#3 [ffffa16bf706f640] oops_end at ffffffff97dbc818
#4 [ffffa16bf706f668] die at ffffffff97631c0b
#5 [ffffa16bf706f698] do_general_protection at ffffffff97dbc0f2
#6 [ffffa16bf706f6d0] general_protection at ffffffff97dbb758
[exception RIP: lock_matches+29]
RIP: ffffffffc0ef5ced RSP: ffffa16bf706f780 RFLAGS: 00010213
RAX: ffa16cccaaa7b8ff RBX: ffa16cccaaa7b6ff RCX: ffffa16bf706f948
RDX: 0002000000000000 RSI: ffffa16bf706f8d0 RDI: ffa16cccaaa7b6ff
RBP: ffffa16bf706f798 R8: 0000000000000000 R9: 0000000000000000
R10: ffffa14fde02b530 R11: 0000000000002000 R12: ffffa16bf706f8d0
R13: ffffa16bf706f8d0 R14: ffffa16bf706f808 R15: ffffffffc0ef5ef0
ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0018
#7 [ffffa16bf706f7a0] itree_overlap_cb at ffffffffc0ef5f3e [ptlrpc]
#8 [ffffa16bf706f7c8] interval_search at ffffffffc0cc347b [obdclass]
#9 [ffffa16bf706f800] search_itree at ffffffffc0ef2284 [ptlrpc]
#10 [ffffa16bf706f840] ldlm_lock_match_with_skip at ffffffffc0ef70ff [ptlrpc]
#11 [ffffa16bf706f940] osc_enqueue_base at ffffffffc0aee2f0 [osc]
#12 [ffffa16bf706f9f8] osc_lock_enqueue at ffffffffc0af874e [osc]
#13 [ffffa16bf706fab0] cl_lock_enqueue at ffffffffc0cb5295 [obdclass]
#14 [ffffa16bf706faf0] lov_lock_enqueue at ffffffffc0ba9e69 [lov]
#15 [ffffa16bf706fb30] cl_lock_enqueue at ffffffffc0cb5295 [obdclass]
#16 [ffffa16bf706fb70] cl_lock_request at ffffffffc0cb5857 [obdclass]
#17 [ffffa16bf706fba8] cl_io_lock at ffffffffc0cb9dc6 [obdclass]
#18 [ffffa16bf706fbf0] cl_io_loop at ffffffffc0cba8ad [obdclass]
#19 [ffffa16bf706fc28] ll_file_io_generic at ffffffffc1156b86 [lustre]
#20 [ffffa16bf706fd28] ll_file_aio_read at ffffffffc11588a4 [lustre]
#21 [ffffa16bf706fdf0] ll_file_read at ffffffffc1158b39 [lustre]
#22 [ffffa16bf706fed8] vfs_read at ffffffff9785b76f
#23 [ffffa16bf706ff08] sys_read at ffffffff9785c5e5
#24 [ffffa16bf706ff50] system_call_fastpath at ffffffff97dc539a
关键发现:
-
崩溃直接原因:
general_protection
异常(通常由内存访问违规、页错误等原因引起),在lock_matches+29
地址处(位于ptlrpc
模块内)发生。 -
调用栈路径:崩溃发生在Lustre文件系统客户端处理读请求的路径上(
ll_file_read
→cl_io_loop
→ ... →lock_matches
)。 -
涉及内核模块:
lustre
、osc
(Lustre客户端)、ptlrpc
(Lustre RPC)、obdclass
(Lustre对象设备) 等,表明问题与Lustre文件系统密切相关。
3. 分析故障进程
查看崩溃进程(rex)信息:
crash> ps -p 2115
...
PID: 2115 TASK: ffffa17747992100 CPU: 30 COMMAND: "rex"
查看进程打开的文件描述符:
crash> files 2115
...
FD FILE DENTRY INODE TYPE PATH
...
3 ffffa18cd5c26900 ffffa1b37e491e00 ffffa14eac0acb68 REG /lustre/nvme_client/projects/.../qrc.TEST_MUX_TOP.log
...
8 ffffa172c9c79000 ffffa16b54cf3ec0 ffffa1585c2d5128 REG /lustre/nvme_client/projects/PDKs/.../qrcTechFile
...
关键发现:
-
进程
rex
(PID: 2115) 是导致崩溃的直接进程。 -
该进程正在访问Lustre文件系统上的文件(
qrc.TEST_MUX_TOP.log
和qrcTechFile
),这与调用栈中Lustre读操作路径一致。 -
rex
通常是OpenLava作业调度系统中的一个组件,负责作业执行,这解释了Prometheus告警OpenLava不可用的原因。
四、崩溃原因深度分析
-
直接原因:内核在执行
lock_matches
函数(Lustre的锁管理相关函数)时发生了通用保护错误(General Protection Fault)。此类错误通常由非法内存访问(如空指针解引用、访问已释放内存、内存对齐问题)、或内核数据结构损坏等原因引起。 -
根因推测: - 锁竞争可能性:
lock_matches
函数涉及Lustre分布式锁的管理。崩溃可能源于某种锁竞争条件,例如多个线程或中断上下文对同一锁的异常争用,尤其是在Lustre客户端与服务器交互复杂的场景下。 - 硬件或驱动因素:虽然本次分析重点在软件栈,但不能完全排除底层硬件(如内存、NIC)或驱动故障的可能性,这些也可能导致内核数据结构损坏。 后续需结合硬件日志(如mcelog
)进一步排查。 - 模块缺陷:崩溃点位于Lustre内核模块(ptlrpc
)内部,很可能是该模块在处理特定锁状态或网络报文时存在Bug。 -
关联性:OpenLava的
rex
进程通过Lustre客户端访问文件时,触发了Lustre内核模块中潜在的锁竞争Bug,最终导致内核崩溃。
五、解决方案与规避措施
-
立即措施: - 重启节点,恢复服务(已完成)。 - 检查Lustre文件系统完整性(
lustre_fsck
)。 - 监控节点稳定性。 -
中期措施: - 更新Lustre客户端驱动:检查是否有可用的Lustre客户端补丁或更新版本,特别是修复锁管理或内存安全性问题的版本。 - 调整OpenLava工作负载:如果可能,暂时将涉及大量Lustre文件I/O的作业调度到其他节点,减少潜在触发机会。 - 配置更详细的内核日志:开启Lustre的详细调试日志(需谨慎,可能影响性能),以便未来捕获更详细的错误信息。
-
长期措施: - 与Lustre社区沟通:将此次崩溃的日志(特别是vmcore和调用栈信息)提交给Lustre社区或支持厂商,寻求官方诊断和修复。 - 内核与硬件健康检查:定期对集群节点进行内存测试(如
memtest86+
)、磁盘健康检查(smartctl
),确保底层硬件稳定性。 - 评估内核参数调整:在某些情况下,调整与内存管理、锁超时或看门狗相关的内核参数可能有助于缓解或提前暴露问题,但需严格测试。
六、经验总结
-
kdump是关键:在生产环境务必确保kdump已配置并有效工作。 它是分析复杂内核崩溃几乎唯一有效的手段。
-
日志要集中:系统日志(
/var/log/messages
、/var/log/kern.log
)应实时收集并集中存储,便于节点宕机后查询历史记录。 -
怀疑硬件,但要证据:内核崩溃虽常怀疑硬件,但需结合硬件日志(如BMC、mcelog)或诊断工具确认,避免误判。
-
社区力量:遇到开源组件(如Lustre)引发的内核问题,积极与社区沟通往往能更快找到根源或解决方案。
本次宕机事件由Lustre文件系统客户端模块中的潜在锁管理缺陷触发,与特定工作负载(OpenLava作业通过rex进程访问Lustre文件)相结合导致。通过vmcore分析准确定位了问题点,为后续修复和规避提供了明确方向。
附录:常用内核崩溃分析命令参考
命令 | 用途 | 示例 |
---|---|---|
`dmesg -T~s | grep -i "panic"` | 查看内核环形缓冲区中的恐慌信息 |
crash <vmlinux> <vmcore> |
加载转储文件进入分析环境 | |
bt |
查看崩溃调用栈 | |
ps |
查看崩溃时进程状态 | |
files <PID> |
查看指定进程打开的文件 | |
log |
显示内核日志 | |
kmem -i |
显示内存使用信息 | |
struct <struct_name> <addr> |
查看结构体内容 | |
modinfo <module_name> |
查看内核模块信息 |
希望这篇分析对遇到类似问题的同学有所帮助。内核调试虽难,但抽丝剥茧,总能找到线索。