如何记录哪些进程执行了特定的系统调用?

如何记录哪些进程执行了特定的系统调用?

最近我发现许多进程/恶魔喜欢发出不需要的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 性能工具

答案2

除了接受的答案之外,还审计正如@Gilles 在评论中提到的那样,可以做到这一点。

Auditd 可以通过以下方式控制审计控制命令,以及一个

auditctl -S fsync,fdatasync,...

将记录的系统调用限制为我们想要的。

相关内容