无法正确访问跟踪点上下文结构字段

Can't access correctly to tracepoint context struct fields

目标: 仅在使用 O_RDONLY 标志调用 openat 时写入 trace_pipe。我已经构建了看起来包含此处 /sys/kernel/debug/tracing/events/syscalls/sys_enter_open/format

格式的结构

问题 我想我没有访问标志字段,因为看起来第二个 if 语句总是错误的。 问题:我是否正确访问了标志字段?有没有办法打印标志变量内容?

struct syscalls_enter_openat_args {
    __u64 pad;
    int __syscall_nr;
    const char * filename;
    int flags;
    unsigned short modep;
};
SEC("tracepoint/syscalls/sys_enter_openat")
int bpf_sys(struct syscalls_enter_openat_args *ctx)
{
    char fmt[] = "llo\n";
    int flags = ctx->flags;

    if (flags){
        if (flags == O_RDONLY)
            bpf_trace_printk(fmt, sizeof(fmt)); 
    }
    return 0;
}
char _license[] SEC("license") = "GPL";

因此您提到以下检查的计算结果始终为假:

if (flags == O_RDONLY)

这可能是因为通过变量 flags 传递给 openat() 的标志不仅仅是 O_RDONLY。来自 openat() 手册页:

The argument flags must include one of the following access modes: O_RDONLY, O_WRONLY, or O_RDWR. These request opening the file read-only, write-only, or read/write, respectively.

In addition, zero or more file creation flags and file status flags can be bitwise-or'd in flags. The file creation flags are O_CLOEXEC, O_CREAT, O_DIRECTORY, O_EXCL, O_NOCTTY, O_NOFOLLOW, O_TMPFILE, and O_TRUNC. The file status flags are all of the remaining flags listed below. The distinction between these two groups of flags is that the file creation flags affect the semantics of the open operation itself, while the file status flags affect the semantics of subsequent I/O operations. The file status flags can be retrieved and (in some cases) modified; see fcntl(2) for details.

因此,与其检查您的 flags 是否 等于 O_RDONLY,不如检查它们是否 包含 标志,通过像这样对其进行位掩码:

if (flags & O_RDONLY)

至于打印 flags 的值,它可能是这样的(未测试):

        char fmt[] = "flags: %x\n";
        int flags = ctx->flags;

        if (flags & O_RDONLY)
                bpf_trace_printk(fmt, sizeof(fmt), flags);