Skip to content

Commit fea3049

Browse files
unikzforceanakryiko
authored andcommitted
examples/c: add minimal_ns example demonstrating PID namespace translation
In namespaced environments like containers or WSL2 the `minimal` example would not work, because of namespace pid and real PID of userspace process not necessarily matching. Add `minimal_ns` example to show how to handle PID translation in namespaced environments. Signed-off-by: Hosein Bakhtiari <h.bakhtiary.z@gmail.com>
1 parent 500eba1 commit fea3049

File tree

3 files changed

+107
-0
lines changed

3 files changed

+107
-0
lines changed

README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,23 @@ $ sudo cat /sys/kernel/debug/tracing/trace_pipe
2222
`minimal` is great as a bare-bones experimental playground to quickly try out
2323
new ideas or BPF features.
2424

25+
## Minimal_ns
26+
27+
`minimal_ns` is as same as `minimal` but for namespaced environments.
28+
`minimal` would not work in environments that have namespace, like containers,
29+
or WSL2, because the perceived pid of the process in the namespace is not the
30+
actual pid of the process. For executing `minimal` in namespaced environments
31+
you need to use `minimal_ns` instead.
32+
33+
```shell
34+
$ cd examples/c
35+
$ make minimal_ns
36+
$ sudo ./minimal_ns
37+
$ sudo cat /sys/kernel/debug/tracing/trace_pipe
38+
<...>-3840345 [022] d...1 8804.331204: bpf_trace_printk: BPF triggered from PID 9087.
39+
<...>-3840345 [022] d...1 8804.331215: bpf_trace_printk: BPF triggered from PID 9087.
40+
```
41+
2542
## Minimal_Legacy
2643

2744
This version of `minimal` is modified to allow running on even older kernels

examples/c/minimal_ns.bpf.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2+
/* Copyright (c) 2023 Hosein Bakhtiari */
3+
#include <linux/bpf.h>
4+
#include <bpf/bpf_helpers.h>
5+
#include <linux/sched.h>
6+
7+
char LICENSE[] SEC("license") = "Dual BSD/GPL";
8+
9+
int my_pid = 0;
10+
unsigned long long dev;
11+
unsigned long long ino;
12+
13+
SEC("tp/syscalls/sys_enter_write")
14+
int handle_tp(void *ctx)
15+
{
16+
struct bpf_pidns_info ns;
17+
18+
bpf_get_ns_current_pid_tgid(dev, ino, &ns, sizeof(ns));
19+
if (ns.pid != my_pid)
20+
return 0;
21+
22+
bpf_printk("BPF triggered from PID %d.\n", ns.pid);
23+
24+
return 0;
25+
}

examples/c/minimal_ns.c

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
2+
/* Copyright (c) 2023 Hosein Bakhtiari */
3+
#include <stdio.h>
4+
#include <sys/stat.h>
5+
#include <unistd.h>
6+
#include <bpf/libbpf.h>
7+
#include "minimal_ns.skel.h"
8+
9+
static int libbpf_print_fn(enum libbpf_print_level level, const char *format, va_list args)
10+
{
11+
return vfprintf(stderr, format, args);
12+
}
13+
14+
int main(int argc, char **argv)
15+
{
16+
struct minimal_ns_bpf *skel;
17+
int err;
18+
struct stat sb;
19+
20+
/* Set up libbpf errors and debug info callback */
21+
libbpf_set_print(libbpf_print_fn);
22+
23+
/* Open BPF application */
24+
skel = minimal_ns_bpf__open();
25+
if (!skel) {
26+
fprintf(stderr, "Failed to open BPF skeleton\n");
27+
return 1;
28+
}
29+
30+
/* ensure BPF program only handles write() syscalls from our process */
31+
if (stat("/proc/self/ns/pid", &sb) == -1) {
32+
fprintf(stderr, "Failed to acquire namespace information");
33+
return 1;
34+
}
35+
skel->bss->dev = sb.st_dev;
36+
skel->bss->ino = sb.st_ino;
37+
skel->bss->my_pid = getpid();
38+
39+
/* Load & verify BPF programs */
40+
err = minimal_ns_bpf__load(skel);
41+
if (err) {
42+
fprintf(stderr, "Failed to load and verify BPF skeleton\n");
43+
goto cleanup;
44+
}
45+
46+
/* Attach tracepoint handler */
47+
err = minimal_ns_bpf__attach(skel);
48+
if (err) {
49+
fprintf(stderr, "Failed to attach BPF skeleton\n");
50+
goto cleanup;
51+
}
52+
53+
printf("Successfully started! Please run `sudo cat /sys/kernel/debug/tracing/trace_pipe` "
54+
"to see output of the BPF programs.\n");
55+
56+
for (;;) {
57+
/* trigger our BPF program */
58+
fprintf(stderr, ".");
59+
sleep(1);
60+
}
61+
62+
cleanup:
63+
minimal_ns_bpf__destroy(skel);
64+
return -err;
65+
}

0 commit comments

Comments
 (0)