BMC故障导致kipmi0极高的CPU使用

快速起步

如果你没有时间看完这篇文章,这里有一个快速起步的三板斧:

  • BMC故障导致IPMI接口无响应,会导致大量ipmitool监控hang住占用系统资源(目前监控框架已经修改,超过10个ipmitool进程将不再发器新IMPI监控指令),此时top显示系统负载极高,同时没有实际CPU占用程序,也没有iowait,却有一个100%占用CPU的kipmi0进程。

  • 修复BMC的手段是reset cold,请依次通过如下方法尝试修复:

    • 在操作系统内执行 ipmitool mc reset cold - 有一定概率能冷重启BMC

    • 通过移除ipmi相关内核模块解决kipmi0占用CPU资源问题:rmmod ipmi_si - 这个步骤不解决BMC无响应故障,但通过关闭ipmi接口可以解决系统负载问题

    • 终极大招:通过OOB管理服务器向服务器管理IP发送指令ipmitool -I lanplus -H <oob_ip> -U <username> -P <passwd> mc reset cold冷重启BMC

如果你还有兴趣,请看以下排查故障的过程:

故障现象

最近遇到用户反馈kvm虚拟机中运行的应用响应缓慢(RT较高),对物理服务器检查,意外发现系统有一个非常高的负载的kipmi0进程。这个kipmi0进程是和BMC通讯的,通常应该极少占用资源。

top - 20:05:20 up 87 days,  7:59,  2 users,  load average: 193.69, 113.92, 81.70
Tasks: 729 total,   3 running, 726 sleeping,   0 stopped,   0 zombie
%Cpu(s): 93.3 us,  3.7 sy,  0.0 ni,  3.1 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem : 19786745+total,  3874380 free, 19185401+used,  2139072 buff/cache
KiB Swap: 12582904 total, 12582904 free,        0 used.  5360364 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
16114 root      20   0 92.520g 0.088t   6588 S  3013 47.8  25928,15 qemu-kvm
10926 root      20   0 92.583g 0.088t   6264 S  3005 47.8  26079,01 qemu-kvm
11749 root      39  19       0      0      0 R 100.0  0.0  33718:35 kipmi0

上述故障的特征是:

  • 系统load负载极高,但是应用程序运行占用的CPU资源很低,并且没有iowait(表明没有磁盘故障)

  • 系统有一个kipmi0进程接近100%占用了一个CPU资源

检查可以看到这个系统中有大量的ipmitool进程,显示很多ipmi监控脚本都么有执行完一直卡在系统中,大量消耗系统资源。

root     48830  0.0  0.0  23576  1344 ?        S    Oct18   0:00 /usr/bin/ipmitool mc info
root     48860  0.0  0.0  23576  1348 ?        S    04:57   0:00 /usr/bin/ipmitool mc info
root     48864  0.0  0.0  23576  1348 ?        SN   Oct19   0:00 /usr/bin/ipmitool -b 6 -t 0x2c raw 0x4 0x2d 0xbe
root     48877  0.0  0.0  23576  1344 ?        S    Oct04   0:00 /usr/bin/ipmitool mc info
root     48890  0.0  0.0  23576  1348 ?        S    Oct04   0:00 /usr/bin/ipmitool mc info
root     48901  0.0  0.0  23576  1344 ?        S    Oct16   0:00 /usr/bin/ipmitool mc info
root     48927  0.0  0.0  23576  1348 ?        S    Oct21   0:00 /usr/bin/ipmitool mc info
root     48953  0.0  0.0  23576  1344 ?        S    Oct15   0:00 /usr/bin/ipmitool mc info

选择检查其中一个ipmtool进程的stat,显示处于轮询等待中

$sudo cat /proc/65113/stack
[<ffffffff811edac5>] poll_schedule_timeout+0x55/0xb0
[<ffffffff811ee441>] do_select+0x6d1/0x7c0
[<ffffffff811ee70b>] core_sys_select+0x1db/0x300
[<ffffffff811ee8ea>] SyS_select+0xba/0x110
[<ffffffff8163e7c9>] system_call_fastpath+0x16/0x1b
[<ffffffffffffffff>] 0xffffffffffffffff

$sudo cat /proc/65113/stat
65113 (ipmitool) S 1 13257 13257 0 -1 1077944320 501 0 0 0 0 0 0 0 20 0 1 0 596383532 24141824 336 18446744073709551615 4194304 4831636 140735297749936 140735297748856 140139888896403 0 0 15973 2 18446744071580867269 0 0 17 32 0 0 0 0 0 6932832 7041384 7581696 140735297752421 140735297752447 140735297752447 140735297753062 0

杀掉所有ipmitool进程可以缓解负载问题

for i in `ps auxf | grep ipmitool | awk '{print $2}'`; do sudo kill $i; done

故障排除笔记

操作系统内mc reset cold

这个故障现象以前发现过,是因为带外oob控制器死机导致无法响应查询。彻底解决的方法是cold reset带外设备,如果cold reset无效则需要维修带外设备。

如果能够登录服务器,则可以在改服务器操作系统内部执行mc reset cold。如果幸运地冷重启BMC,则可以看到top 中的 ipmitool0 进程 占用的cpu资源迅速从 100% 降低到0。

ipmitool mc reset cold

如果操作系统内部执行ipmitool命令会没有响应。则可以尝试卸载ipmi内核模块或者通过带外重启MC

卸载ipmi模块

首先可以尝试卸载ipmi内核模块

检查ipmi内核模块

lsmod | grep ipmi

可以看到操作系统使用了如下内核模块

ipmi_devintf            7429  0
ipmi_si                44127  0
acpi_ipmi               3836  0
ipmi_msghandler        37887  3 ipmi_devintf,ipmi_si,acpi_ipmi

卸载内核模块ipmi_devintf(针对IPMI驱动的用户端IOCTL接口,每个为这个设备打开文件将绑定到消息处理器message handler作为一个IPMI用户)

此时kipmi0负载没有降低

尝试卸载内核模块ipmi_si(不同系统接口的驱动)

rmmod ipmi_si

GOOD,可以看到kipmi0进程的100%负载立即降低到0。

参考 Kipmi0 eating up to 99.8% cpu on centos 6.4 的建议方法,采用卸载ipmi_siipmi_msghandler可以解决kimpi0负载高的问题。

注意:卸载内核模块要按照模块引用计数器来卸载,引用计数为0的模块先卸载,所以先卸载ipmi_devintf,ipmi_siacpi_ipmi,然后再卸载ipmi_msghandler

继续将所有ipmi模块都卸载掉

rmmod acpi_ipmi
ipmi_msghandler

确定所有ipmi模块都卸载之后,尝试过sudo /etc/init.d/ipmi start,发现会导致modprobe ipmi_si进程D住:

root     15528  1.1  0.0   4016   712 pts/0    D+   10:31   0:01 modprobe ipmi_si
$ps r -A
  PID TTY      STAT   TIME COMMAND
15528 pts/0    D+     0:02 modprobe ipmi_si
24986 pts/1    R+     0:00 ps r -A

说明IPMI驱动接口内核模块无法启动,检查堆栈可以看到sys_init_module内核函数没有返回

$sudo cat /proc/15528/stack
[<ffffffffa04667c8>] wait_for_msg_done+0x38/0x70 [ipmi_si]
[<ffffffffa0466a88>] try_smi_init+0x288/0x820 [ipmi_si]
[<ffffffffa046bdc8>] init_ipmi_si+0x5e8/0xb00 [ipmi_si]
[<ffffffff81002046>] do_one_initcall+0x36/0x1c0
[<ffffffff810b59ff>] sys_init_module+0xef/0x260
[<ffffffff8100cf72>] system_call_fastpath+0x16/0x1b
[<ffffffffffffffff>] 0xffffffffffffffff

要重新卸载ipmi_si内核模块,首先要确保这个文件没有打开,否则会提示in use

#rmmod ipmi_si
ERROR: Module ipmi_si is in use

检查打开到文件句柄

#lsof | grep ipmi
modprobe  15528   root    3uw     REG                8,2       92280               606830 /lib/modules/2.6.32-358.23.2.ali1195.el5.x86_64/kernel/drivers/char/ipmi/ipmi_si.ko

杀掉进程15528之后查看再查看内核模块

ipmi_si                44127  0
ipmi_msghandler        37887  1 ipmi_si

注意:这里虽然看上去ipmi_si模块已经加载到内核,实际上ipmi0设备文件初始化没有成功,导致/dev/ipmi0设备不存在,无法通过ipmitool进行操作,例如

#ipmitool mc reset cold
Could not open device at /dev/ipmi0 or /dev/ipmi/0 or /dev/ipmidev/0: No such file or directory
Could not open device at /dev/ipmi0 or /dev/ipmi/0 or /dev/ipmidev/0: No such file or directory
Sent cold reset command to MC

实际可能硬件存在故障,无法初始化驱动

检查集群中其他服务器的/dev/ipmi0设备,可以看到

crw------- 1 root root 247, 0 Jun  3  2015 /dev/ipmi0

所以尝试在这台故障服务器上手工创建设备文件

cd /dev
mknod ipmi0 c 247 0

尝试使用sh MAKEDEV ipmi0提示错误MAKEDEV: MAKEDEV: cannot execute binary file,没有明白^_^

不过,实践发现内核模块ipmi_si没有正确加载情况下,即使手工创建/dev/ipmi0设备文件也无法执行mc reset cold,报错依旧。

终极大招:OOB带外mc reset cold

从带外oob管理机直接oob设备发reset指令。

ipmitool -I lanplus -H <oob_ip> -U <username> -P <passwd> chassis power status

如果电源状态能够检查到,就说明至少通过网络访问oob是正常的,此时可以尝试通过ipmitoollanplus方式冷启动一下

ipmitool -I lanplus -H <oob_ip> -U <username> -P <passwd> mc reset cold

前面手工mknod ipmi0 c 247 0创建的设备文件已定要先删除,否则即使mc reset cold之后再启动service ipmi start系统日志还会显示报错,并且导致modprobe ipmi_si进程D住:

Feb 20 13:07:51 server1.example.com kernel: : [54240346.738217] ipmi message handler version 39.2
Feb 20 13:07:51 server1.example.com kernel: : [54240346.755812] ipmi_si: Adding SMBIOS-specified kcs state machine
Feb 20 13:07:51 server1.example.com kernel: : [54240346.755880] ipmi_si: Adding ACPI-specified kcs state machine: duplicate interface
Feb 20 13:07:51 server1.example.com kernel: : [54240346.755884] ipmi_si: Trying SMBIOS-specified kcs state machine at i/o address 0xca8, slave address 0x20, irq 0

实际修复是通过终极大招OOB带外mc reset cold来修复完成:

  • 操作系统内部由于BMC无响应,所以无法重新加载ipmi_si内核模块,所以也无法在操作系统内部ipmitool mc reset cold

  • 如果带外能够通过lanplus接口reset cold一次BMC,则会恢复操作系统内部和BMC的通讯,所以这个方法修复的可能性较高。

参考

Last updated