使用 BPF 工具对类型 'struct mnt_namespace' 的定义和前向声明不完整?
Incomplete definition and forward declaration of type 'struct mnt_namespace' using BPF tools?
我想要的:
向 execsnoop
bcc 工具添加一个网络名称空间选项,以便仅跟踪具有指定网络名称空间的日志,就像我们在许多其他 bcc 工具中有过滤器 PID 选项一样。例如:execsnoop -N "ns_id"
我试过的:
int syscall__execve(struct pt_regs *ctx,
const char __user *filename,
const char __user *const __user *__argv,
const char __user *const __user *__envp)
{
// create data here and pass to submit_arg to save stack space (#555)
struct data_t data = {};
struct task_struct *task;
data.pid = bpf_get_current_pid_tgid() >> 32;
task = (struct task_struct *)bpf_get_current_task();
// Some kernels, like Ubuntu 4.13.0-generic, return 0
// as the real_parent->tgid.
// We use the get_ppid function as a fallback in those cases. (#1883)
data.ppid = task->real_parent->tgid;
data.netns = task->nsproxy->mnt_ns->ns.inum; // I tried to mount namespace here
bpf_get_current_comm(&data.comm, sizeof(data.comm));
data.type = EVENT_ARG;
__submit_arg(ctx, (void *)filename, &data);
// skip first arg, as we submitted filename
#pragma unroll
for (int i = 1; i < MAXARG; i++) {
if (submit_arg(ctx, (void *)&__argv[i], &data) == 0)
goto out;
}
// handle truncated argument list
char ellipsis[] = "...";
__submit_arg(ctx, (void *)ellipsis, &data);
out:
return 0;
}
收到错误:
/virtual/main.c:98:39: error: incomplete definition of type 'struct mnt_namespace'
data.netns = task->nsproxy->mnt_ns->ns.inum;
~~~~~~~~~~~~~~~~~~~~~^
include/linux/nsproxy.h:8:8: note: forward declaration of 'struct mnt_namespace'
struct mnt_namespace;
^
1 error generated.
Traceback (most recent call last):
File "./execsnoop", line 230, in <module>
b = BPF(text=bpf_text)
File "/usr/lib/python2.7/dist-packages/bcc/__init__.py", line 325, in __init__
raise Exception("Failed to compile BPF text")
Exception: Failed to compile BPF text
我也尝试包含 mnt_namespace.h 头文件,但没有解决。
密件抄送工具 mountsnoop.py
似乎可以实现您想要实现的目标。他们重新定义了一些结构,注释如下:
/*
* XXX: struct mnt_namespace is defined in fs/mount.h, which is private to the
* VFS and not installed in any kernel-devel packages. So, let's duplicate the
* important part of the definition. There are actually more members in the
* real struct, but we don't need them, and they're more likely to change.
*/
struct mnt_namespace {
atomic_t count;
struct ns_common ns;
};
确实 fs/mount.h 中的结构没有导出。所以我怀疑你只需要在你的代码中做同样的事情:部分重新定义 struct mnt_namespace
.
我想要的:
向 execsnoop
bcc 工具添加一个网络名称空间选项,以便仅跟踪具有指定网络名称空间的日志,就像我们在许多其他 bcc 工具中有过滤器 PID 选项一样。例如:execsnoop -N "ns_id"
我试过的:
int syscall__execve(struct pt_regs *ctx,
const char __user *filename,
const char __user *const __user *__argv,
const char __user *const __user *__envp)
{
// create data here and pass to submit_arg to save stack space (#555)
struct data_t data = {};
struct task_struct *task;
data.pid = bpf_get_current_pid_tgid() >> 32;
task = (struct task_struct *)bpf_get_current_task();
// Some kernels, like Ubuntu 4.13.0-generic, return 0
// as the real_parent->tgid.
// We use the get_ppid function as a fallback in those cases. (#1883)
data.ppid = task->real_parent->tgid;
data.netns = task->nsproxy->mnt_ns->ns.inum; // I tried to mount namespace here
bpf_get_current_comm(&data.comm, sizeof(data.comm));
data.type = EVENT_ARG;
__submit_arg(ctx, (void *)filename, &data);
// skip first arg, as we submitted filename
#pragma unroll
for (int i = 1; i < MAXARG; i++) {
if (submit_arg(ctx, (void *)&__argv[i], &data) == 0)
goto out;
}
// handle truncated argument list
char ellipsis[] = "...";
__submit_arg(ctx, (void *)ellipsis, &data);
out:
return 0;
}
收到错误:
/virtual/main.c:98:39: error: incomplete definition of type 'struct mnt_namespace'
data.netns = task->nsproxy->mnt_ns->ns.inum;
~~~~~~~~~~~~~~~~~~~~~^
include/linux/nsproxy.h:8:8: note: forward declaration of 'struct mnt_namespace'
struct mnt_namespace;
^
1 error generated.
Traceback (most recent call last):
File "./execsnoop", line 230, in <module>
b = BPF(text=bpf_text)
File "/usr/lib/python2.7/dist-packages/bcc/__init__.py", line 325, in __init__
raise Exception("Failed to compile BPF text")
Exception: Failed to compile BPF text
我也尝试包含 mnt_namespace.h 头文件,但没有解决。
密件抄送工具 mountsnoop.py
似乎可以实现您想要实现的目标。他们重新定义了一些结构,注释如下:
/*
* XXX: struct mnt_namespace is defined in fs/mount.h, which is private to the
* VFS and not installed in any kernel-devel packages. So, let's duplicate the
* important part of the definition. There are actually more members in the
* real struct, but we don't need them, and they're more likely to change.
*/
struct mnt_namespace {
atomic_t count;
struct ns_common ns;
};
确实 fs/mount.h 中的结构没有导出。所以我怀疑你只需要在你的代码中做同样的事情:部分重新定义 struct mnt_namespace
.