Linux

如何記錄,哪些程序進行了特定的系統呼叫?

  • May 6, 2020

最近我發現許多程序/惡魔喜歡發出不需要fsync()的系統呼叫,增加一點它們的穩定性,代價是大大降低了整個系統的總體性能。我想停止這種不合作的行為。但是,首先我需要以某種方式找到它們。

我認為,最理想的事情是,如果我能以某種方式為特定類型的系統呼叫設置“監視器”,並記錄呼叫它的程序的數據。

就我而言,如果有任何程序進行fsync()系統呼叫,我想知道它。最理想的情況是,它應該是一個 syslog 條目,或者在dmesg.

我已經閱讀了一些關於 auditd 的內容,但我不確定它是否可以做到這一點。

假設正在使用最近的發行版,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)。該工具的成本預計可以忽略不計,因為同步(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 的BPF 性能工具的第 293 和 294 頁

引用自:https://unix.stackexchange.com/questions/584734