bpftrace
bpftrace copied to clipboard
Getting a cgroup path from cgroup ID
Is your feature request related to a problem? Please describe.
Use case: My host machine has multiple running docker containers. Inside a docker container, there is a medic process that can report container health.
I'm looking to extend oomkill.bt to notify the medic process whenever there is an OOM event. bpftrace provides a built-in variable "cgroup" which is a cgroup ID. I'm looking to convert cgroup ID to a full cgroup path. Since the full cgroup path has docker container ID, I can use the path to notify the medic process in the correct container.
Describe the solution you'd like
A new BPF helper function that calls task_cgroup_path
Describe alternative solutions or features you've considered
An alternative is to pass cgroup id to a separate program that can convert cgroup id to cgroup path using a similar approach.
Getting filesystem paths through bpf is notoriously tricky b/c you need to take locks. IIUC from following the kernel discussions, the main issue is deadlocks b/c the bpf prog could try to take a lock in an already locked context. @olsajiri probably has the most insight into feasibility of a cgroup_path() helper.
cgroup id is just inode # in cgroupfs so one workaround could look like this:
$ sudo ./build/src/bpftrace -e 'BEGIN { print(cgroup) }'
Attaching 1 probe...
5505
^C
$ find /sys/fs/cgroup -inum 5505
/sys/fs/cgroup/user.slice/user-1000.slice/[email protected]/gnome-launched-alacritty-9823.scope
cgroup id is just inode # in cgroupfs so one workaround could look like this:
Hm @danobi .. it does not make much sense, but my find /sys/fs/cgroup -inum 1730 for one service returns multiple paths.. 🤔 Why? I thought inode number is unique.
/sys/fs/cgroup/blkio/system.slice/fwupd.service/blkio.throttle.io_service_bytes_recursive
/sys/fs/cgroup/cpu,cpuacct/system.slice/systemd-logind.service/cpuacct.usage_percpu
/sys/fs/cgroup/cpu,cpuacct/system.slice/systemd-logind.service/cpuacct.usage_percpu
/sys/fs/cgroup/unified/system.slice/docker.service
Code https://github.com/bwplotka/ebpf_exporter/blob/exp/decoder/cgroup.go#L38
(invoking find inside container)
@bwplotka It looks like you're using hybrid cgroup1 + cgroup2 setup on your host. I believe under cgroup1, a process may be in multiple cgroups. Under cgroup2, a process may only be in 1 cgroup.
There is now the cgroup_path builtin that allows this (implemented in #2055).