记一次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_readcl_io_loop → ... → lock_matches)。

  • ​涉及内核模块​​:lustreosc (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.logqrcTechFile),这与调用栈中Lustre读操作路径一致。

  • rex 通常是OpenLava作业调度系统中的一个组件,负责作业执行,这解释了Prometheus告警OpenLava不可用的原因。

四、崩溃原因深度分析

  1. ​直接原因​​:内核在执行 lock_matches 函数(Lustre的锁管理相关函数)时发生了​​通用保护错误​​(General Protection Fault)。此类错误通常由非法内存访问(如空指针解引用、访问已释放内存、内存对齐问题)、或内核数据结构损坏等原因引起。

  2. ​根因推测​​: - ​​锁竞争可能性​​:lock_matches 函数涉及Lustre分布式锁的管理。崩溃可能源于某种​​锁竞争条件​​,例如多个线程或中断上下文对同一锁的异常争用,尤其是在Lustre客户端与服务器交互复杂的场景下。 - ​​硬件或驱动因素​​:虽然本次分析重点在软件栈,但不能完全排除底层硬件(如内存、NIC)或驱动故障的可能性,这些也可能导致内核数据结构损坏。 后续需结合硬件日志(如mcelog)进一步排查。 - ​​模块缺陷​​:崩溃点位于Lustre内核模块(ptlrpc)内部,很可能是该模块在处理特定锁状态或网络报文时存在Bug。

  3. ​关联性​​:OpenLava的 rex 进程通过Lustre客户端访问文件时,触发了Lustre内核模块中潜在的锁竞争Bug,最终导致内核崩溃。

五、解决方案与规避措施

  1. ​立即措施​​: - 重启节点,恢复服务(已完成)。 - 检查Lustre文件系统完整性(lustre_fsck)。 - 监控节点稳定性。

  2. ​中期措施​​: - ​​更新Lustre客户端驱动​​:检查是否有可用的Lustre客户端补丁或更新版本,特别是修复锁管理或内存安全性问题的版本。 - ​​调整OpenLava工作负载​​:如果可能,暂时将涉及大量Lustre文件I/O的作业调度到其他节点,减少潜在触发机会。 - ​​配置更详细的内核日志​​:开启Lustre的详细调试日志(需谨慎,可能影响性能),以便未来捕获更详细的错误信息。

  3. ​长期措施​​: - ​​与Lustre社区沟通​​:将此次崩溃的日志(特别是vmcore和调用栈信息)提交给Lustre社区或支持厂商,寻求官方诊断和修复。 - ​​内核与硬件健康检查​​:定期对集群节点进行内存测试(如memtest86+)、磁盘健康检查(smartctl),确保底层硬件稳定性。 - ​​评估内核参数调整​​:在某些情况下,调整与内存管理、锁超时或看门狗相关的内核参数可能有助于缓解或提前暴露问题,但需严格测试。

六、经验总结

  1. ​kdump是关键​​:在生产环境​​务必确保kdump已配置并有效工作​​。 它是分析复杂内核崩溃几乎唯一有效的手段。

  2. ​日志要集中​​:系统日志(/var/log/messages/var/log/kern.log)应实时收集并集中存储,便于节点宕机后查询历史记录。

  3. ​怀疑硬件,但要证据​​:内核崩溃虽常怀疑硬件,但需结合硬件日志(如BMC、mcelog)或诊断工具确认,避免误判。

  4. ​社区力量​​:遇到开源组件(如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> 查看内核模块信息

希望这篇分析对遇到类似问题的同学有所帮助。内核调试虽难,但抽丝剥茧,总能找到线索。

posted on 2025-09-08 10:34  LeeHang  阅读(32)  评论(0)    收藏  举报