最近我发现许多进程/恶魔喜欢发出不需要的fsync()
系统调用,稍微增加一点稳定性,但代价是极大地降低整个系统的总体性能。我想制止这种不合作的行为。然而,首先我需要以某种方式找到它们。
我认为,最理想的事情是,如果我能够以某种方式为特定类型的系统调用设置一个“监视器”,并记录调用它的进程的数据。
就我而言,如果任何进程执行fsync()
系统调用,我想知道它。最理想的情况是,它应该是一个系统日志条目,或者在dmesg
.
我读过一些有关auditd 的内容,但我不确定它是否可以做到这一点。
答案1
假设正在使用最近的发行版,那么这bpftrace
确实很方便。对于它,在Debian 10中,需要安装它:
apt install bpftrace
然后使用synsnoop.bt
, 在系统范围内侦听 *sync 相关的系统调用:
# syncsnoop.bt
Attaching 7 probes...
Tracing sync syscalls... Hit Ctrl-C to end.
TIME PID COMM EVENT
03:15:35 443 dhclient tracepoint:syscalls:sys_enter_fsync
^C
该工具的工作原理是通过跟踪点跟踪sync(2)变体:sync(2)、syncfs(2)、fsync(2)、fdatasync(2)、sync_file_range(2)和msync(2)。该工具的开销预计可以忽略不计,因为sync(2) 的速率通常非常罕见。
或者使用bpftrace
脚本语言:
# ./sync.bt
Attaching 7 probes...
Tracing sync syscalls... Hit Ctrl-C to end.
TIME PID COMM EVENT
08:09:53 443 dhclient tracepoint:syscalls:sys_enter_fsync
^C
sync.bt
记录所有的源同步相关系统调用:
#!/usr/bin/bpftrace
BEGIN {
printf("Tracing sync syscalls... Hit Ctrl-C to end.\n");
printf("%-9s %-6s %-16s %s\n", "TIME", "PID", "COMM", "EVENT");
}
tracepoint:syscalls:sys_enter_sync,
tracepoint:syscalls:sys_enter_syncfs,
tracepoint:syscalls:sys_enter_fsync,
tracepoint:syscalls:sys_enter_fdatasync,
tracepoint:syscalls:sys_enter_sync_file_range,
tracepoint:syscalls:sys_enter_msync
{
time("%H:%M:%S ");
printf("%-6d %-16s %s\n", pid, comm, probe);
}
PS 来自 Brendan Gregg 的第 293 和 294 页BPF 性能工具