尝试重新挂载还是无法解决问题,重启后回复正常,重启后收集sosreport。
查看了sosreport/var/log/message,在问题出现的时间点前后没有发现NFS相关的报错信息(见图),由此推测NFS连接并未直接断开且本地文件系统正常。
查的资料得知在连接完全断开时,message文件中会在超时时间过后(默认三分钟左右RHEL mount hangs: nfs: server [...] not responding, still trying - Red Hat Customer Portal)出现not responding的报错信息(见图)。
然后通过sosreport/var/log/sa/sa02文件查看出问题时的系统负载情况,观察到从当天11:00开始已出现明显异常,具体表现为:%iowait增高(见图1),任务队列长度增加(见图2),NFS读写速度下降(见图3),网卡吞吐量下降(见图4)。
图 1
图 2
图 3
图 4
日志显示在问题出现时存在较多任务处于iowait状态,但设备流量明显下降。若等待IO任务的目标是NAS盘,那么出现上述情况可能是网络链路问题。经过进一步分析sar数据,我们发现本地盘IO及另一块网卡的流量也同期出现了下降现象(见图4,图5),且一个CPU的%system极高(见图6)。
图 5
图 6
从sar文件中可看到,本地IO及另一块网卡流量的数值表现与NFS流量的变化具有共性特点,可以认为这些不同资源的监控数值变化是由同一原因引发或有强相关性。考虑到问题出现时CPU的%system占用极高且任务队列长,推测这些监控数值的变化是由任务阻塞导致。
而NFS操作占用100%CPU导致相关任务阻塞是当前版本内核中一个已知bug的典型现象,故推测本次故障与当前版本中内核已知bug有关(链接:RHEL 7.6: NFS share hangs when NFS operations are in-progress and a network partition occurs involving an unexpected RST - Red Hat Customer Portal,该bug的涉及到的内核版本为[3.10.0-957.el7, 3.10.0-957.5.1.el7),且在nfsv3版本更容易出现),由于故障时未能触发vmcore,无法进一步通过分析core文件的调用栈来确认。
为了证明分析的正确性,我们又通过模拟测试,实验过程是在NAS盘上写入数据的同时,断开NFS使用的TCP链接,此时由于NFS并未同步到TCP链接的状态,表现为系统长时间无响应,df -h卡住,与客户反应的现象一致,通过收集并分析sar监控数据,表现与sosreport中的sa记录一致(见图7,图8)。
图 7
图 8
该bug的触发逻辑如下:
在3.10.0-957.5.1版本的内核中,RPC的错误处理函数中增加了一个对于TCP状态的特判(见图9),以识别并处理RPC与TCP状态不同步的问题。
图 9
经过多次实验和内核代码分析,基本确认本次故障是由于麒麟系统的3.10.0-957.el7.x86_64版本内核存在bug导致,由于当时未能生成core文件,因此也不排除NAS所在网络异常的诱因。
一、升级内核至3.10.0-957.5.1版本及以上
二、为排除NAS链路异常等因素的干扰,建议再次发生故障(重启前)时做如下处置:
1、通过ping或curl的方式,判断故障机到nas服务端的链路是否正常;
2、给mount和umount添加-v参数重新卸载&挂载,收集输出信息;
3、收集当前状态下的sosreport。
4、收集尝试读写NAS盘时的pcap。
(1)在一个终端执行tcpdump -i <连接NAS的网卡> -w <保存的文件名>。
(2)在另一终端通过echo,cat,df等命令对nfs做读写操作。
(3)ctrl+c停止tcpdump,收集产生的文件。
5、使用strace(yum install strace)及ftrace(yum install trace-cmd)收集mount,umount,df命令的执行过程信息。
(1)strace使用方式为在原命令前加上strace -o output_filename,例如df -h改为strace -o ouput.log df -h,其他命令同理。
(2)ftrace使用举例如下:
1.systemctl status rasdaemon确认该服务处于关闭状态
2.mount|grep debugfs 检查文件系统是否挂载(通常已挂载)
3.未挂载则执行mount -t debugfs debugfs /sys/kernel/debug
4.执行下面的命令:
5.收集umount.log,mount.log,df.log,/sys/kernel/debug/tracing/trace。(trace文件较特殊,保险起见可通过cat /sys/kernel/debug/tracing/trace > ~/trace收集其文本格式)
通过执行echo c > /proc/sysrq-trigger手动触发crash以生成vmcore。