在一些业务环境的VMware Guest虚拟机上安装我们的内核模块后,偶尔虚拟机会变成无响应的状态。重启后登录系统查看,处于无响应状态的那段时间在/var/log/messages中却没有任何信息,完全没有分析问题原因的头绪。
经过调研,找到两种方法可以帮助排查定位这类系统失去响应的问题,分别是:
- 发送
NMI: Non-Maskable Interupt给虚拟机 - VMware内存快照
发送NMI给虚拟机
NMI是不可屏蔽的硬件中断。在虚拟化环境中,Hypervisor可以向Guest虚拟机发送NMI中断。Guest虚拟机收到NMI后产生dump文件, 继而从dump文件中分析系统状态。
只是Linux系统对于NMI中断的默认处理行为是发送到stdout,并不会panic并产生dump文件。为了在接收到NMI时产生dump文件,我们需要在Guest的Linux系统中完成这些配置:
安装
kexec-tools, 并启动kdump服务:1
systemctl start kdump.service
配置
sysctl参数,令Linux系统接收到NMI时panic:1
2sysctl -w kernel.panic_on_unrecovered_nmi=1
sysctl -w kernel.unknown_nmi_panic=1
在VCenter的GUI界面中, 可以在相应Guest虚拟机的导出系统日志操作中向虚拟机发送NMI, 如图:
这种方式对VCenter登录帐号的管理权限有所要求。
在相应的ESXi主机上也可以通过命令行向虚拟机发送NMI:
1 | vm-support -a HungVM:Send_NMI_To_Guest --vm=/vmfs/volumes/Path/of/VMname.vmx |
可以参考官方KB:
如果是RHEV和oVirt环境, 可以使用virsh命令发送NMI:
1 | virsh inject-nmi guest1 |
具体可以参考链接:
内存快照
另外一种方法就是基于VMware的快照。VMware官方提供了一个工具可以将快照文件转换成crash工具可以读取的dump文件。
工具使用说明:
工具下载地址:
但经过尝试,发现转换完成的dump文件使用crash并不能正常读取。
和Redhat这篇KB上描述的错误一致:
crash无法读取的根本原因是从7.5版本开始,RHEL内核默认启用了KASLR特性:
1 | Starting 7.5, RHEL kernels feature KASLR (Kernel Address Space Linear Randomization) enabled by default. KASLR is a security feature that enables the kernel to relocate itself to a random location on each boot, making writing exploits that depend on local resources significantly harder. |
可以参考这里:
但它也提到,crash可以直接读取VMware的快照文件,步骤如下:
- 复制
ESXi主机上Guest所在目录下的.vmss/.vmsn和.vmem文件到一个目录 - 保持文件名称不变
- 使用
crash工具打开.vmsn/.vmss文件,crash会自动加载相应的.vmem文件
如:
1 | # crash <NAME>.vmsn /cores/retrace/repos/kernel/x86_64/usr/lib/debug/lib/modules/<kernel version>/vmlinux |
不过在生成快照时,需要注意勾选包括虚拟机的内存:
有时侯系统可能会连NMI也无法响应,这种场景下就只能使用快照方式。但快照方式本身需要从ESXi主机上获取快照文件,也不是很方便。总之各有利弊,看情况选择使用哪种方法。
因为使用crash工具分析dump文件,需要对应内核版本的debuginfo包。有时我们拿到dump文件,却不知道内核版本。我们可以从dump文件中直接查找字符串来搜索, 如:
1 | [root@localhost centos76-Snapshot1]# strings vmss.core |grep -i 'BOOT_IMAGE' |
参考:
- https://support.delphix.com/Continuous_Data_Engine_(formerly_Virtualization_Engine)/Platforms/How_to_Generate_a_non-maskable_interrupt_in_VMware_ESX__(KBA1129)
- https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/virtualization_deployment_and_administration_guide/sect-generic_commands-injecting_nmi
- https://kb.vmware.com/s/article/1015180
- https://kb.vmware.com/s/article/2149185
- https://kb.vmware.com/s/article/67438
- https://kb.vmware.com/s/article/2003941
- https://flings.vmware.com/vmss2core
- https://access.redhat.com/articles/3587631
- https://access.redhat.com/solutions/210063
- https://access.redhat.com/solutions/3622951
- https://knowledge.broadcom.com/external/article/181598/how-to-convert-a-vmware-virtual-machine.html