tools: bpftool: Restore message on failure to guess program type
authorQuentin Monnet <quentin@isovalent.com>
Wed, 11 Mar 2020 02:12:05 +0000 (02:12 +0000)
committerAlexei Starovoitov <ast@kernel.org>
Fri, 13 Mar 2020 19:49:51 +0000 (12:49 -0700)
In commit 4a3d6c6a6e4d ("libbpf: Reduce log level for custom section
names"), log level for messages for libbpf_attach_type_by_name() and
libbpf_prog_type_by_name() was downgraded from "info" to "debug". The
latter function, in particular, is used by bpftool when attempting to
load programs, and this change caused bpftool to exit with no hint or
error message when it fails to detect the type of the program to load
(unless "-d" option was provided).

To help users understand why bpftool fails to load the program, let's do
a second run of the function with log level in "debug" mode in case of
failure.

Before:

    # bpftool prog load sample_ret0.o /sys/fs/bpf/sample_ret0
    # echo $?
    255

Or really verbose with -d flag:

    # bpftool -d prog load sample_ret0.o /sys/fs/bpf/sample_ret0
    libbpf: loading sample_ret0.o
    libbpf: section(1) .strtab, size 134, link 0, flags 0, type=3
    libbpf: skip section(1) .strtab
    libbpf: section(2) .text, size 16, link 0, flags 6, type=1
    libbpf: found program .text
    libbpf: section(3) .debug_abbrev, size 55, link 0, flags 0, type=1
    libbpf: skip section(3) .debug_abbrev
    libbpf: section(4) .debug_info, size 75, link 0, flags 0, type=1
    libbpf: skip section(4) .debug_info
    libbpf: section(5) .rel.debug_info, size 32, link 14, flags 0, type=9
    libbpf: skip relo .rel.debug_info(5) for section(4)
    libbpf: section(6) .debug_str, size 150, link 0, flags 30, type=1
    libbpf: skip section(6) .debug_str
    libbpf: section(7) .BTF, size 155, link 0, flags 0, type=1
    libbpf: section(8) .BTF.ext, size 80, link 0, flags 0, type=1
    libbpf: section(9) .rel.BTF.ext, size 32, link 14, flags 0, type=9
    libbpf: skip relo .rel.BTF.ext(9) for section(8)
    libbpf: section(10) .debug_frame, size 40, link 0, flags 0, type=1
    libbpf: skip section(10) .debug_frame
    libbpf: section(11) .rel.debug_frame, size 16, link 14, flags 0, type=9
    libbpf: skip relo .rel.debug_frame(11) for section(10)
    libbpf: section(12) .debug_line, size 74, link 0, flags 0, type=1
    libbpf: skip section(12) .debug_line
    libbpf: section(13) .rel.debug_line, size 16, link 14, flags 0, type=9
    libbpf: skip relo .rel.debug_line(13) for section(12)
    libbpf: section(14) .symtab, size 96, link 1, flags 0, type=2
    libbpf: looking for externs among 4 symbols...
    libbpf: collected 0 externs total
    libbpf: failed to guess program type from ELF section '.text'
    libbpf: supported section(type) names are: socket sk_reuseport kprobe/ [...]

After:

    # bpftool prog load sample_ret0.o /sys/fs/bpf/sample_ret0
    libbpf: failed to guess program type from ELF section '.text'
    libbpf: supported section(type) names are: socket sk_reuseport kprobe/ [...]

Signed-off-by: Quentin Monnet <quentin@isovalent.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Acked-by: John Fastabend <john.fastabend@gmail.com>
Link: https://lore.kernel.org/bpf/20200311021205.9755-1-quentin@isovalent.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
tools/bpf/bpftool/common.c
tools/bpf/bpftool/main.c
tools/bpf/bpftool/main.h
tools/bpf/bpftool/prog.c

index ad634516ba8028c916d2f9284d0a244f31daca46..f2223dbdfb0af2bba35eb95f2072a39fabb4f73c 100644 (file)
@@ -572,3 +572,10 @@ int parse_u32_arg(int *argc, char ***argv, __u32 *val, const char *what)
 
        return 0;
 }
+
+int __printf(2, 0)
+print_all_levels(__maybe_unused enum libbpf_print_level level,
+                const char *format, va_list args)
+{
+       return vfprintf(stderr, format, args);
+}
index 6d41bbfc645937debb45753501c34f71802ffd2d..06449e846e4b8ba3b55fae7d8750337f8f050046 100644 (file)
@@ -79,13 +79,6 @@ static int do_version(int argc, char **argv)
        return 0;
 }
 
-static int __printf(2, 0)
-print_all_levels(__maybe_unused enum libbpf_print_level level,
-                const char *format, va_list args)
-{
-       return vfprintf(stderr, format, args);
-}
-
 int cmd_select(const struct cmd *cmds, int argc, char **argv,
               int (*help)(int argc, char **argv))
 {
index d57972dd0f2b60c38a8682dd7c480758bfb122f8..5f6dccd43622f9d7e01d8f3f29c855cb91af7a1b 100644 (file)
@@ -14,6 +14,8 @@
 #include <linux/hashtable.h>
 #include <tools/libc_compat.h>
 
+#include <bpf/libbpf.h>
+
 #include "json_writer.h"
 
 #define ptr_to_u64(ptr)        ((__u64)(unsigned long)(ptr))
@@ -229,4 +231,7 @@ struct tcmsg;
 int do_xdp_dump(struct ifinfomsg *ifinfo, struct nlattr **tb);
 int do_filter_dump(struct tcmsg *ifinfo, struct nlattr **tb, const char *kind,
                   const char *devname, int ifindex);
+
+int print_all_levels(__maybe_unused enum libbpf_print_level level,
+                    const char *format, va_list args);
 #endif
index d0966380ad0e7572678692abb88d4d7a9f74675f..f6a5974a7b0aec20ae366ecb38132c5181e8ffdf 100644 (file)
@@ -1247,6 +1247,25 @@ free_data_in:
        return err;
 }
 
+static int
+get_prog_type_by_name(const char *name, enum bpf_prog_type *prog_type,
+                     enum bpf_attach_type *expected_attach_type)
+{
+       libbpf_print_fn_t print_backup;
+       int ret;
+
+       ret = libbpf_prog_type_by_name(name, prog_type, expected_attach_type);
+       if (!ret)
+               return ret;
+
+       /* libbpf_prog_type_by_name() failed, let's re-run with debug level */
+       print_backup = libbpf_set_print(print_all_levels);
+       ret = libbpf_prog_type_by_name(name, prog_type, expected_attach_type);
+       libbpf_set_print(print_backup);
+
+       return ret;
+}
+
 static int load_with_options(int argc, char **argv, bool first_prog_only)
 {
        enum bpf_prog_type common_prog_type = BPF_PROG_TYPE_UNSPEC;
@@ -1296,8 +1315,8 @@ static int load_with_options(int argc, char **argv, bool first_prog_only)
                        strcat(type, *argv);
                        strcat(type, "/");
 
-                       err = libbpf_prog_type_by_name(type, &common_prog_type,
-                                                      &expected_attach_type);
+                       err = get_prog_type_by_name(type, &common_prog_type,
+                                                   &expected_attach_type);
                        free(type);
                        if (err < 0)
                                goto err_free_reuse_maps;
@@ -1396,8 +1415,8 @@ static int load_with_options(int argc, char **argv, bool first_prog_only)
                if (prog_type == BPF_PROG_TYPE_UNSPEC) {
                        const char *sec_name = bpf_program__title(pos, false);
 
-                       err = libbpf_prog_type_by_name(sec_name, &prog_type,
-                                                      &expected_attach_type);
+                       err = get_prog_type_by_name(sec_name, &prog_type,
+                                                   &expected_attach_type);
                        if (err < 0)
                                goto err_close_obj;
                }