一、问题背景
业务方在使用自研文件系统挂载目录下,执行go语言编译的可执行程序时报错,脚本核心逻辑是os.RemoveAll(dir),功能是可以删除目录不为空的目录。结果在运行时报错:directory not empty。
排查中虽有弯路,但是还是增长了不少经验。这篇文章为大家分享排查问题中的收获。
二、排查过程
从自研文件系统侧排查,自研文件系统客户端通过fuse实现,fuse是filesystem in user space,一个用户空间的文件系统框架,允许非特权用户建立功能完备的文件系统,而不需要重新编译内核。fuse模块仅仅提供内核模块的入口,而本身的主要实现代码位于用户空间中。对于读写虚拟文件系统来讲,fuse是个很好的选择。fuse包含包含一个内核模块和一个用户空间守护进程,将大部分的VFS调用都委托一个专用的守护进程来处理。
复现方式:编写go脚本:err = os.RemoveAll(dir),创建dir目录含300个文件。在挂载点内执行此脚本,结果会大概率出现directory not empty进而运行失败。RemoveAll主要逻辑是遍历目录下所有文件逐一删除,然后再删除目录。
问题原因:
原因是内核层在做readdir的时候,收到中断信号,于是在重新处理时会从刚才的offset去发送给/dev/fuse,但是我们没有对此场景进行处理,吐到内核的数据我们认为就成功了然后丢弃掉量,于是又重新向我们要刚才的数据,但是拿不到因此就失败了。
排查经过:
经过多次实验,发现其他fuse文件系统均无问题,只有我们有问题,因此多半原因是我们自己的代码bug。于是排查自己的代码,发现在目录下文件unlink的个数不对,没有全部unlink完,因此会报目录不为空的错误,而unlink是根据readdir去拿的结果,排查发现在某次readdir时从/dev/fuse设备拿到的偏移量不对,而我们是根据偏移量去返回结果的,因此我们就觉得和自身的逻辑没有关系。(从结果反推,是跟我们有关系的,偏移量有可能因为某次内核没有处理完本地而重新发送刚才的偏移量)
另一个发现是复现条件是特定的,在centos7编译在龙蜥运行才会复现,让我们一度认为是跟内核有关(从结果反推复盘发现是当时测试验证的少了,结论太武断导致排查方向有误,并不是只有这种情况才会复现)
内核日志追踪
通过分析内核fuse获取目录相关模块梳理获取整个流程:
用户脚本执行中先获取目录内容,触发systemcall为sys_getdents64,在VFS调用iterate_dir方法,该方法在fuse模块触发fuse_readdir方法向fuse挂载设备/dev/fuse发送读取请求,分布式文件系统客户端从/dev/fuse读取请求后,通过分布式文件系统集群的相关处理将结果返回给/dev/fuse,而fuse_readdir方法收到结果后,会通过dir_emit方法将返回结果一条一条拷贝到用户空间。通过在几个关键节点加日志分析,最终发现,在执行dir_emit时再执行,signal_pending(current)返回-4,因此中断了后续的处理,再回来的时候从本批次首个offset重新向用户空间请求数据。内核fuse模块编译及应用参考如下脚本:
make CONFIG_FUSE_FS=m M=fs/fuse
yes | cp fs/fuse/fuse.ko /usr/lib/modules/4.18.0_80.7.1.el8_0_bch_v1.0/kernel/fs/fuse/
umount /mnt
umount /sys/fs/fuse/connections/
rmmod fuse
insmod /usr/lib/modules/4.18.0_80.7.1.el8_0_bch_v1.0/kernel/fs/fuse/fuse.ko
pending信号处理是否为正常信号
至此需要验证一下收到的待处理信号是否为正常逻辑(当然无论正常至此已可以定位到文件系统逻辑的不严谨,但是为了追究细则还需要再查一步),首先安装bcc工具,killsnoop追踪kill信号的系统调用,未发现异常。于是通过ftrace调试工具分析以及重新对复现场景条件追查发现信号处理为正常逻辑,至此修复分布式文件系统逻辑后该问题得以解决。Frace追踪systemcall使用方式参考如下:
cd /sys/kernel/debug/tracing
echo 0 > tracing_on
echo > trace
echo syscalls:* > set_event
echo raw_syscalls:* >> set_event
echo ${pid} >> set_event_pid
echo 1 > tracing_on
运行程序
cat trace
希望以上经验,能帮助到需要的人!
关注“360智汇云”,更多产品技术好文等着你~
360智汇云
360智汇云官方服务号,致力于打造高质量、高安全、高可用、便捷、稳定的一站式云服务平台。
官方网址:智汇云-企业数智化核心引擎
本文暂时没有评论,来添加一个吧(●'◡'●)