1.eBPF/Ftrace 双剑合璧:no space left on device 无处遁形
2.用trace工具 trace trace工具
eBPF/Ftrace 双剑合璧:no space left on device 无处遁形
在生产环境中,源码我们遇到了创建容器时“no space left on device”的源码问题,磁盘使用空间和inode的源码状况都显示正常。常规的源码排查方式无法定位问题,那么是源码否有快速且通用的方法来找出问题的根源?本文是通过eBPF和Ftrace在单独环境中进行问题分析和定位的记录,希望能为遇到类似情况的源码指静脉 源码读者提供参考。
当在机器上运行`docker run`命令时,源码系统会提示“no space left on device”,源码这表明在overlay mount过程中磁盘空间不足。源码使用`df -Th`命令检查磁盘空间情况,源码磁盘使用率仅为%。源码接下来,源码Android启动源码通过`df -i`查看inode的源码使用情况,overlay文件系统的源码inode使用率仅为7%。此时,源码我们可能怀疑是否存在文件被删除但句柄未被释放,导致inode泄露。为了验证这一假设,我们执行了`lsof | grep deleted`,但结果为空,意味着没有找到被删除但仍被使用的文件。
在常规排查方法都失效的情况下,我们尝试了eBPF(BCC工具集基于eBPF技术开发)和Ftrace的薪酬管理源码组合应用,以期快速定位问题。首先,我们利用BCC提供的系统调用跟踪工具`syscount-bpfcc`,通过错误码来快速确定问题。在时间允许的情况下,我们推荐从源代码逐步分析定位问题,这不仅能解决问题,还能深入学习。
在内核中搜索报错信息,我们可以直接在`include/uapi/asm-generic/errno-base.h`文件中找到与错误相关的定义。接着,sift opencv源码利用`syscount-bpfcc`工具过滤返回`ENOSPC`错误的系统调用,我们发现`mount`系统调用返回了`ENOSPC`错误。通过参数`-P`按进程聚合显示,我们得知`dockerd`后台进程调用了`mount`系统调用并返回了错误。
进一步跟踪错误的具体位置,我们使用了Ftrace中的`function_graph`跟踪器。通过使用`funcgraph`工具,我们能够获取到`__arm_sys_mount`函数中调用的主要子流程函数。在内核函数调用过程中,如果遇到错误,内核通常会直接跳转到错误相关的私人会所源码清理函数逻辑中,这里我们关注`path_mount`函数,以深入分析可能的问题。
在确认问题主要出现在`count_mounts`函数中后,我们通过源代码分析函数的主流程逻辑,确定问题是由`sysctl_mount_max`配置值过低引起,这是通过`/proc/sys/fs/mount-max`设置的。通过将此值调整为默认值,我们成功解决了问题。
本次问题排查的思路不仅适用于“no space left on device”的情况,也适用于其他场景下的问题分析和排查。同时,将此思路作为源码阅读和分析内核代码时的补充工具,能有效提升问题定位的效率。希望本文能为读者提供有用的参考,如果发现文中的错误或有更好的案例,欢迎留言交流。
用trace工具 trace trace工具
深入探讨了使用trace工具理解eBPF(eBPF)和trace工具的方法。首先,理解了使用eBPF工具进行调试以及trace工具理解trace原理的两种方式:从代码细节入手,或是先勾画大概,再深入细节。在复杂系统中,直接查看所有代码变得困难,尤其是在云环境中,此现象普遍。接下来,以`reallocarray`为例,创建了一个uprobe。
在探究如何通过trace-bpfcc生成uprobe时,通过strace工具发现使用了`perf_event_open`进行注入。进一步关注`perf_event_open`内部参数`struct perf_event_attr`,了解了`config1`和`config2`的作用:`config1`类似uprobe的路径名,而`config2`是特定偏移量。通过尝试不同方法,最终确认`config1`指向`libc.so`文件路径,`config2`为`reallocarray`在`libc-2..so`中的偏移。
创建uprobe后,编写了小程序来触发其执行。eBPF与uprobe的关联通过`trace trace-bpfcc`实现,最终调用`__uprobe_register`。对于`__uprobe_register`的实现,通过进一步查找代码获取信息。`mymem`触发uprobe的机制大致为程序加载或执行过程中会触发先前创建的uprobe,通过`ftrace`的`function_graph`功能筛选并打印调用函数链。
通过分析uprobe_mmap的调用栈,可以了解到在操作vma时会触发uprobe_mmap。uprobe_mmap内部的关键调用有助于理解其工作流程。总结以上trace分析,得出理解uprobe的实现和工作原理,主要通过trace和源码分析相结合的方式,掌握工具和方法是关键。
通过trace过程演示了使用trace工具的能力和方法,更多关于uprobe的实现细节,可以通过进一步的trace或阅读源码进行深入探索。这一过程展示了如何利用trace工具理解复杂系统中的特定功能和行为,为深入学习和调试提供了一条有效路径。