1

我正在尝试收集一些与块设备上的某些目标进程执行的写入相关的块层信息。具体来说,我想找到:(1)需要写入的起始扇区,(2)写入的扇区数和(3)写入的时间。

我编写了一个基本的bcc-pythonblock_rq_complete脚本来通过探测事件来收集所需的信息。脚本如下:

from bcc import BPF

PROG = """
#include <linux/blkdev.h>
#include <linux/sched.h>

struct data_t {
    u32 pid;
    u64 ts;
    u64 sector_start;
    u64 nr_sectors;
    char comm[TASK_COMM_LEN];
};
BPF_PERF_OUTPUT(events);

TRACEPOINT_PROBE(block, block_rq_complete) {
    struct data_t data = {};
    data.pid = bpf_get_current_pid_tgid();
    data.ts = bpf_ktime_get_ns();
    data.sector_start = args->sector;
    data.nr_sectors = args->nr_sector;
    bpf_get_current_comm(&data.comm, sizeof(data.comm));

    events.perf_submit(args, &data, sizeof(data));

    return 0;
}
"""

def print_event(cpu, data, size):
    event = b["events"].event(data)
    print(event.comm, event.ts, event.sector_start, event.nr_sectors)

b = BPF(text=PROG)
b["events"].open_perf_buffer(print_event)
while True:
    b.perf_buffer_poll()

当我运行这个脚本时,我发现大多数调用block_rq_complete实际上是由交换器执行的。我知道很多这些调用可能是为了写脏缓存。如果进程没有显式调用fsync,进程的 pid 可能永远不会真正出现在事件中,并且进程的相应写入将由交换器写入。

有没有办法捕获专门为(或代表)我想要的进程执行的写入?有没有办法从交换者中筛选出大量事件?例如,即使我正在向终端写入内容或clear在终端上使用,事件也会出现(令人惊讶的是,它们发生在 SSD 上,使用主要和次要数字标识)。

我将非常感谢任何帮助。谢谢!

4

0 回答 0