Reputation: 23
I am using ebpf to capture process creation. I am using ringbuf for kernel 5.8 and above and would like to use perfbuf for older kernels in the same ebpf kernel file. There is a great blog about it https://nakryiko.com/posts/bpf-core-reference-guide/#linux-kernel-version, according to it I can use a code like:
if (LINUX_KERNEL_VERSION < KERNEL_VERSION(5, 8, 0))
{
// use the perfbuf
}
else
{
// use the ringbuf
}
and the loader ignores the dead code. The issue is how to declare the ring buffer map under such a condition, because it is declared in a global scope and not inside a function:
struct {
__uint(type, BPF_MAP_TYPE_RINGBUF);
__uint(max_entries, 64 * 4096);
} rb SEC(".maps");
In kernels before 5.8 BPF_MAP_TYPE_RINGBUF is not defined and the load fails. Is there some Initialization function that is called that I can define and add the map in there according to the kernel version?
Upvotes: 2
Views: 1508
Reputation: 7968
The creation of maps like this is always performed by the loader. So you can declare both a ring buffer and perf buffer and write your userspace program in such a way as to only load one of the two.
In general it isn't recommended to use kernel versions to detect feature support since some distros will backport certain features to older kernel versions (RedHat enterprise for example).
So if at all possible, its recommended to use feature probes provided by bpftool
or cilium/ebpf.
In the case of bpftool
it is also possible to ask the command to output C macros which allow you to use #ifdef
pre-processor statements in your eBPF code (though this will require compiling on the target).
Upvotes: 1