bpf_has_kernel_btf() is used to check whether the kernel has BTF or not.
It's part of the logic that checks if kfunc and lsm programs are supported.
Before this commit it used libbpf_find_vmlinux_btf_id(), this function
calls btf__load_vmlinux_btf() that tries to load the BTF from different
places, the canonical vmlinux in sysfs and other locations.
This is not accurate as kfunc and lsm programs require to have the BTF
file exposed directly by the kernel (CONFIG_DEBUG_INFO_BTF should be set).
This commit updates that function to check if BTF is exposed directly
by the kernel.
This was causing opensnoop to try to use kfunc programs (instead of
kprobes) in systems where they are not supported:
$ ls /usr/lib/debug/boot/vmlinux-$(uname -r)
/usr/lib/debug/boot/vmlinux-5.11.0-38-generic
$ cat /boot/config-$(uname -r) | grep -i CONFIG_DEBUG_INFO_BTF
$ sudo stat /sys/kernel/btf/vmlinux
stat: cannot stat '/sys/kernel/btf/vmlinux': No such file or directory
$ sudo python3 /usr/share/bcc/tools/opensnoop
bpf: Failed to load program: Invalid argument
Traceback (most recent call last):
File "/usr/share/bcc/tools/opensnoop", line 321, in <module>
b = BPF(text=bpf_text)
File "/usr/lib/python3/dist-packages/bcc/__init__.py", line 483, in __init__
self._trace_autoload()
File "/usr/lib/python3/dist-packages/bcc/__init__.py", line 1466, in _trace_autoload
self.attach_kretfunc(fn_name=func_name)
File "/usr/lib/python3/dist-packages/bcc/__init__.py", line 1140, in attach_kretfunc
fn = self.load_func(fn_name, BPF.TRACING)
File "/usr/lib/python3/dist-packages/bcc/__init__.py", line 522, in load_func
raise Exception("Failed to load BPF program %s: %s" %
Exception: Failed to load BPF program b'kretfunc____x64_sys_open': Invalid argument
Fixes:
1ad2656a1d9c ("Add support_kfunc function to BPF object")
Signed-off-by: Mauricio Vásquez <mauricio@kinvolk.io>