libbpf: Add some details for BTF parsing failures
authorIan Rogers <irogers@google.com>
Thu, 25 Jan 2024 23:18:40 +0000 (15:18 -0800)
committerAndrii Nakryiko <andrii@kernel.org>
Tue, 30 Jan 2024 00:42:42 +0000 (16:42 -0800)
As CONFIG_DEBUG_INFO_BTF is default off the existing "failed to find
valid kernel BTF" message makes diagnosing the kernel build issue somewhat
cryptic. Add a little more detail with the hope of helping users.

Before:
```
libbpf: failed to find valid kernel BTF
libbpf: Error loading vmlinux BTF: -3
```

After not accessible:
```
libbpf: kernel BTF is missing at '/sys/kernel/btf/vmlinux', was CONFIG_DEBUG_INFO_BTF enabled?
libbpf: failed to find valid kernel BTF
libbpf: Error loading vmlinux BTF: -3
```

After not readable:
```
libbpf: failed to read kernel BTF from (/sys/kernel/btf/vmlinux): -1
```

Closes: https://lore.kernel.org/bpf/CAP-5=fU+DN_+Y=Y4gtELUsJxKNDDCOvJzPHvjUVaUoeFAzNnig@mail.gmail.com/

Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/bpf/20240125231840.1647951-1-irogers@google.com
tools/lib/bpf/btf.c

index ec92b87cae012d60c2421259c0712a083e48229c..95db88b36cf3108f362d0eea7bd1abd89c9ef82f 100644 (file)
@@ -4932,10 +4932,9 @@ static int btf_dedup_remap_types(struct btf_dedup *d)
  */
 struct btf *btf__load_vmlinux_btf(void)
 {
+       const char *sysfs_btf_path = "/sys/kernel/btf/vmlinux";
+       /* fall back locations, trying to find vmlinux on disk */
        const char *locations[] = {
-               /* try canonical vmlinux BTF through sysfs first */
-               "/sys/kernel/btf/vmlinux",
-               /* fall back to trying to find vmlinux on disk otherwise */
                "/boot/vmlinux-%1$s",
                "/lib/modules/%1$s/vmlinux-%1$s",
                "/lib/modules/%1$s/build/vmlinux",
@@ -4949,8 +4948,23 @@ struct btf *btf__load_vmlinux_btf(void)
        struct btf *btf;
        int i, err;
 
-       uname(&buf);
+       /* is canonical sysfs location accessible? */
+       if (faccessat(AT_FDCWD, sysfs_btf_path, F_OK, AT_EACCESS) < 0) {
+               pr_warn("kernel BTF is missing at '%s', was CONFIG_DEBUG_INFO_BTF enabled?\n",
+                       sysfs_btf_path);
+       } else {
+               btf = btf__parse(sysfs_btf_path, NULL);
+               if (!btf) {
+                       err = -errno;
+                       pr_warn("failed to read kernel BTF from '%s': %d\n", sysfs_btf_path, err);
+                       return libbpf_err_ptr(err);
+               }
+               pr_debug("loaded kernel BTF from '%s'\n", path);
+               return btf;
+       }
 
+       /* try fallback locations */
+       uname(&buf);
        for (i = 0; i < ARRAY_SIZE(locations); i++) {
                snprintf(path, PATH_MAX, locations[i], buf.release);