列出进程以有效方式访问的所有文件

use*_*789 13 unix linux filesystems vfs linux-kernel

我想以有效的方式记录进程在其生命周期中所做的所有文件访问.

目前,我们通过预加载拦截处理文件访问的C库调用的共享库来使用LD_PRELOAD来实现此目的.该方法在没有太多性能开销的情况下是有效的,但不是防漏的.

例如,我们的LD_PRELOAD共享库有一个用于dlopen的钩子.此挂钩用于跟踪对共享库的访问,但该机制无法记录共享库的三级依赖关系.

我们曾尝试使用strace的,但使用的性能开销strace的是一个非首发我们.我很好奇,如果我们有其他机制,我们可以探索拦截进程及其子进程以有效方式进行的文件访问.我愿意在内核级别探索选项,挂钩到VFS层或其他任何东西.

思考?

osg*_*sgx 4

我们确实尝试过使用 strace,但使用 strace 的性能开销对我们来说是不可能的。

strace很慢,因为它使用古老且缓慢的ptrace系统调用来充当应用程序的调试器。应用程序进行的每个系统调用都将转换为 strace 的信号,围绕 strace 的两个 ptrace 系统调用(还有一些打印、访问其他进程内存以获取字符串/结构值)并继续目标应用程序(2 个上下文切换)。strace支持系统调用过滤器,但不能为 ptrace 注册过滤器,strace 在用户空间中进行过滤,跟踪所有系统调用。

有更快的基于内核的解决方案,Brendan Gregg ( Dtrace Book的作者- Solaris、OSX、FreeBSD)对跟踪工具有许多概述(在他的博客中:tracing 15 分钟BPF 超能力60s of linux perfChoosing Tracer 2015(以 Magic pony)页面缓存统计信息) 为例

Brendan Gregg - Linux 内核分析和工具

您对此图左侧靠近 VFS 块的部分感兴趣。perf(标准工具),dtrace(仅在某些 Linux 中受支持,有许可证问题 - CDDL 与 GPL 不兼容),stapsystemtap,与 CentOS 等红色 Linux 配合得更好)。

strace 可以直接替换 - sysdig 工具(需要额外的内核模块,github),它适用于系统调用,例如 tcpdump 适用于网络接口嗅探。该工具嗅探内核内部的系统调用,无需额外的上下文切换或信号,也无需使用 ptrace 刺入其他进程内存(内核已经拥有从用户复制的所有字符串),并且它还使用智能缓冲将跟踪以大数据包转储到用户空间工具。

还有其他通用跟踪框架/工具,例如 lttng(树外)、ftrace/trace-cmd。eBPFbcc是现代(4.9+)Linux 内核中包含的非常强大的框架(请查看http://www.brendangregg.com/Slides/SCALE2017_perf_analysis_eBPF.pdf)。bcc 和 eBPF 允许您编写小型(安全)代码片段,以在跟踪点附近的内核中进行一些数据聚合:

Brendan Gregg 围绕 Linux 内核子系统的密件抄送工具列表

如果您的 Linux 内核足够新,请尝试 VFS 附近的 Brendan 工具:opensnoop, statsnoop, syncsnoop; 可能还有一些文件*工具(工具支持 pid 过滤-p PID或可以在系统范围内工作)。它们在http://www.brendangregg.com/dtrace.html上有部分描述,并发布在他的 github 上: https: //github.com/brendangregg/perf-tools(也https://github.com/iovisor/bcc #工具

从 Linux 4.9 开始,Linux 内核终于拥有了与 DTrace 类似的原始功能。...

opensnoop 是一个监听文件打开的程序。文件名和文件句柄以及一些进程详细信息都会被跟踪。

# opensnoop -g
  UID   PID PATH                                   FD ARGS
  100  3528 /var/ld/ld.config                      -1 cat /etc/passwd
  100  3528 /usr/lib/libc.so.1                      3 cat /etc/passwd
  100  3528 /etc/passwd                             3 cat /etc/passwd   
  100  3529 /var/ld/ld.config                      -1 cal
  100  3529 /usr/lib/libc.so.1                      3 cal
Run Code Online (Sandbox Code Playgroud)

rwsnoop 监听读/写事件。这是测量应用程序级别的读取和写入 - 系统调用。

# rwsnoop
  UID    PID CMD          D   BYTES FILE
    0   2924 sh           R     128 /etc/profile
    0   2924 sh           R     128 /etc/profile
    0   2924 sh           R     128 /etc/profile
    0   2924 sh           R      84 /etc/profile
    0   2925 quota        R     757 /etc/nsswitch.conf
    0   2925 quota        R       0 /etc/nsswitch.conf
    0   2925 quota        R     668 /etc/passwd
Run Code Online (Sandbox Code Playgroud)