tools: cgroup filtering in execsnoop/opensnoop
Add a new option --cgroupmap in execsnoop and opensnoop to only display
results from processes that belong to one of the cgroups whose id,
returned by bpf_get_current_cgroup_id(), is in a pinned BPF hash map.
Examples of commands:
# opensnoop --cgroupmap /sys/fs/bpf/test01
# execsnoop --cgroupmap /sys/fs/bpf/test01
Cgroup ids can be discovered in userspace by the system call
name_to_handle_at(); an example of C program doing that is available in
examples/cgroupid/cgroupid.c.
More complete documentation is added in docs/filtering_by_cgroups.md
The documentation is independent from Kubernetes. However, my goal is to
use this feature in Kubernetes: I am preparing to use this in Inspektor
Gadget to select specific Kubernetes pods, depending on a Kubernetes
label selector. Kubernetes pods matching the label selector can come and
go during the execution of the bcc tools; Inspektor Gadget is updating
the BPF hash map used by the bcc tools accordingly.
diff --git a/tools/opensnoop.py b/tools/opensnoop.py
index 60d11c6..6d1388b 100755
--- a/tools/opensnoop.py
+++ b/tools/opensnoop.py
@@ -35,6 +35,7 @@
./opensnoop -n main # only print process names containing "main"
./opensnoop -e # show extended fields
./opensnoop -f O_WRONLY -f O_RDWR # only print calls for writing
+ ./opensnoop --cgroupmap ./mappath # only trace cgroups in this BPF map
"""
parser = argparse.ArgumentParser(
description="Trace open() syscalls",
@@ -50,6 +51,8 @@
help="trace this PID only")
parser.add_argument("-t", "--tid",
help="trace this TID only")
+parser.add_argument("--cgroupmap",
+ help="trace cgroups in this BPF map only")
parser.add_argument("-u", "--uid",
help="trace this UID only")
parser.add_argument("-d", "--duration",
@@ -99,6 +102,9 @@
int flags; // EXTENDED_STRUCT_MEMBER
};
+#if CGROUPSET
+BPF_TABLE_PINNED("hash", u64, u64, cgroupset, 1024, "CGROUPPATH");
+#endif
BPF_HASH(infotmp, u64, struct val_t);
BPF_PERF_OUTPUT(events);
@@ -113,6 +119,12 @@
PID_TID_FILTER
UID_FILTER
FLAGS_FILTER
+#if CGROUPSET
+ u64 cgroupid = bpf_get_current_cgroup_id();
+ if (cgroupset.lookup(&cgroupid) == NULL) {
+ return 0;
+ }
+#endif
if (bpf_get_current_comm(&val.comm, sizeof(val.comm)) == 0) {
val.id = id;
val.fname = filename;
@@ -163,6 +175,11 @@
'if (uid != %s) { return 0; }' % args.uid)
else:
bpf_text = bpf_text.replace('UID_FILTER', '')
+if args.cgroupmap:
+ bpf_text = bpf_text.replace('CGROUPSET', '1')
+ bpf_text = bpf_text.replace('CGROUPPATH', args.cgroupmap)
+else:
+ bpf_text = bpf_text.replace('CGROUPSET', '0')
if args.flag_filter:
bpf_text = bpf_text.replace('FLAGS_FILTER',
'if (!(flags & %d)) { return 0; }' % flag_filter_mask)