GOAL:仅当使用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[] = "llon";
int flags = ctx->flags;
if (flags){
if (flags == O_RDONLY)
bpf_trace_printk(fmt, sizeof(fmt));
}
return 0;
}
char _license[] SEC("license") = "GPL";
所以你提到以下检查总是计算为 false:
if (flags == O_RDONLY)
这可能是因为通过变量传递给openat()
的标志不仅仅是O_RDONLY
flags
。从openat()
手册页:
参数标志必须包括以下访问模式之一:
O_RDONLY
、O_WRONLY
或O_RDWR
。 这些请求分别以只读、只写或读/写方式打开文件。此外,零个或多个文件创建标志和文件状态标志可以按位或按位输入标志。文件创建标志是
O_CLOEXEC
、O_CREAT
、O_DIRECTORY
、O_EXCL
、O_NOCTTY
、O_NOFOLLOW
、O_TMPFILE
和O_TRUNC
。 文件状态标志是下面列出的所有剩余标志。 这两组标志之间的区别在于,文件创建标志影响打开操作本身的语义,而文件状态标志影响后续 I/O 操作的语义。 可以检索和(在某些情况下(修改文件状态标志;有关详细信息,请参阅fcntl(2)
。
因此,与其检查您的flags
是否等于O_RDONLY
,您可能希望通过像这样对其进行位屏蔽来检查它们是否包含标志:
if (flags & O_RDONLY)
至于打印flags
的值,可能是可以做到的(未经测试(:
char fmt[] = "flags: %xn";
int flags = ctx->flags;
if (flags & O_RDONLY)
bpf_trace_printk(fmt, sizeof(fmt), flags);