On Thu, Apr 28, 2022 at 8:17 AM Daniel Borkmann <daniel@xxxxxxxxxxxxx> wrote: > > On 4/28/22 1:14 PM, Larysa Zaremba wrote: > > Currently, dumping almost all BTFs specified by id requires > > using the -B option to pass the base BTF. For most cases > > the vmlinux BTF sysfs path should work. > > > > This patch simplifies dumping by ID usage by attempting to > > use vmlinux BTF from sysfs, if the first try of loading BTF by ID > > fails with certain conditions. > > > > Signed-off-by: Larysa Zaremba <larysa.zaremba@xxxxxxxxx> > > Reviewed-by: Alexander Lobakin <alexandr.lobakin@xxxxxxxxx> > > --- > > tools/bpf/bpftool/btf.c | 35 ++++++++++++++++++++++++++--------- > > 1 file changed, 26 insertions(+), 9 deletions(-) > > > > diff --git a/tools/bpf/bpftool/btf.c b/tools/bpf/bpftool/btf.c > > index a2c665beda87..557f65e2de5c 100644 > > --- a/tools/bpf/bpftool/btf.c > > +++ b/tools/bpf/bpftool/btf.c > > @@ -459,6 +459,22 @@ static int dump_btf_c(const struct btf *btf, > > return err; > > } > > > > +static const char sysfs_vmlinux[] = "/sys/kernel/btf/vmlinux"; > > + > > +static struct btf *get_vmlinux_btf_from_sysfs(void) > > +{ > > + struct btf *base; > > + > > + base = btf__parse(sysfs_vmlinux, NULL); > > + if (libbpf_get_error(base)) { > > + p_err("failed to parse vmlinux BTF at '%s': %ld\n", > > + sysfs_vmlinux, libbpf_get_error(base)); > > + base = NULL; > > + } > > Could we reuse libbpf's btf__load_vmlinux_btf() which probes well-known > locations? Systems that don't have /sys/kernel/btf/vmlinux exposed definitely don't support base BTF, so there is no point in trying to find vmlinux BTF anywhere else (which is only necessary for old kernels). So I think it should be fine as is, except we shouldn't guess when base BTF is needed, it should always be for kernel module BTFs only. > > > + return base; > > +} > > + > > static int do_dump(int argc, char **argv) > > { > > struct btf *btf = NULL, *base = NULL; > > @@ -536,18 +552,11 @@ static int do_dump(int argc, char **argv) > > NEXT_ARG(); > > } else if (is_prefix(src, "file")) { > > const char sysfs_prefix[] = "/sys/kernel/btf/"; > > - const char sysfs_vmlinux[] = "/sys/kernel/btf/vmlinux"; > > > > if (!base_btf && > > strncmp(*argv, sysfs_prefix, sizeof(sysfs_prefix) - 1) == 0 && > > - strcmp(*argv, sysfs_vmlinux) != 0) { > > - base = btf__parse(sysfs_vmlinux, NULL); > > - if (libbpf_get_error(base)) { > > - p_err("failed to parse vmlinux BTF at '%s': %ld\n", > > - sysfs_vmlinux, libbpf_get_error(base)); > > - base = NULL; > > - } > > - } > > + strcmp(*argv, sysfs_vmlinux)) > > + base = get_vmlinux_btf_from_sysfs(); > > > > btf = btf__parse_split(*argv, base ?: base_btf); > > err = libbpf_get_error(btf); > > @@ -593,6 +602,14 @@ static int do_dump(int argc, char **argv) > > if (!btf) { > > btf = btf__load_from_kernel_by_id_split(btf_id, base_btf); > > err = libbpf_get_error(btf); > > + if (err == -EINVAL && !base_btf) { > > + btf__free(base); > > + base = get_vmlinux_btf_from_sysfs(); > > + p_info("Warning: valid base BTF was not specified with -B option, falling back on standard base BTF (sysfs vmlinux)"); > > + btf = btf__load_from_kernel_by_id_split(btf_id, base); > > + err = libbpf_get_error(btf); > > + } > > + > > if (err) { > > p_err("get btf by id (%u): %s", btf_id, strerror(err)); > > goto done; > > >