描述:

如何获取 namespace 中的进程ID

minimal_nsminimal 功能相同,但其适用于命名空间环境。

minimal 在存在命名空间的环境中(如容器或 WSL2)无法正常工作,原因是该环境下进程的 “感知 PID”(perceived pid)并非进程的 “实际 PID”(actual pid)。

代码梳理

The BPF side

SEC(“tp/syscalls/sys_enter_write”)

1
2
SEC("tp/syscalls/sys_enter_write")
int handle_tp(void *ctx)

bpf_get_ns_current_pid_tgid

1
2
3
4
5
6
7
int my_pid = 0;
unsigned long long dev;
unsigned long long ino;

bpf_get_ns_current_pid_tgid(dev, ino, &ns, sizeof(ns));
if (ns.pid != my_pid)
return 0;

The user-space side

/proc/self/ns/pid

1
2
3
4
5
6
7
8
/* ensure BPF program only handles write() syscalls from our process */
if (stat("/proc/self/ns/pid", &sb) == -1) {
fprintf(stderr, "Failed to acquire namespace information");
return 1;
}
skel->bss->dev = sb.st_dev;
skel->bss->ino = sb.st_ino;
skel->bss->my_pid = getpid();

stat("/proc/self/ns/pid", &sb) 用于获取当前进程所属的「PID 命名空间(PID Namespace)」的元数据,通过返回的 struct stat 结构体中的 st_ino(inode 号),识别当前进程的 PID 命名空间归属(判断两个进程是否在同一个 PID 命名空间)。