Subject: [PATCH bpf-next] libbpf: Show possible section(type) names on when failed to guess a type

From: Taeung Song <[email-masked]>
Date: Wed, 19 Dec 2018 17:52:40 +0900

We need to let users check their wrong section name
with proper section names when failed to get proper type from it.
Because there is no knowing what kind of section name can be used.
For example, when a 'cgroup' section name of a BPF program is used,

Before:

    $ bpftool prog load bpf-prog.o /sys/fs/bpf/prog1
    Error: failed to guess program type based on section name cgroup

After:

    libbpf: failed to guess program type based on section name 'cgroup'
    libbpf: possible section(type) names are: socket kprobe/ kretprobe/ classifier action tracepoint/ raw_tracepoint/ xdp perf_event lwt_in lwt_out lwt_xmit lwt_seg6local cgroup_skb/ingress cgroup_skb/egress cgroup/skb cgroup/sock cgroup/post_bind4 cgroup/post_bind6 cgroup/dev sockops sk_skb/stream_parser sk_skb/stream_verdict sk_skb sk_msg lirc_mode2 flow_dissector cgroup/bind4 cgroup/bind6 cgroup/connect4 cgroup/connect6 cgroup/sendmsg4 cgroup/sendmsg6

Cc: Jakub Kicinski <[email-masked]>
Cc: Andrey Ignatov <[email-masked]>
Signed-off-by: Taeung Song <[email-masked]>
---
 tools/bpf/bpftool/prog.c                       | 10 +++-------
 tools/lib/bpf/libbpf.c                         | 18 ++++++++++++++++--
 .../testing/selftests/bpf/test_socket_cookie.c |  4 +---
 3 files changed, 20 insertions(+), 12 deletions(-)

diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c
index 2d1bb7d6ff51..0640e9bc0ada 100644
--- a/tools/bpf/bpftool/prog.c
+++ b/tools/bpf/bpftool/prog.c
@@ -930,10 +930,9 @@ static int load_with_options(int argc, char **argv, bool first_prog_only)
 			err = libbpf_prog_type_by_name(type, &attr.prog_type,
 						       &expected_attach_type);
 			free(type);
-			if (err < 0) {
-				p_err("unknown program type '%s'", *argv);
+			if (err < 0)
 				goto err_free_reuse_maps;
-			}
+
 			NEXT_ARG();
 		} else if (is_prefix(*argv, "map")) {
 			void *new_map_replace;
@@ -1028,11 +1027,8 @@ static int load_with_options(int argc, char **argv, bool first_prog_only)
 
 			err = libbpf_prog_type_by_name(sec_name, &prog_type,
 						       &expected_attach_type);
-			if (err < 0) {
-				p_err("failed to guess program type based on section name %s\n",
-				      sec_name);
+			if (err < 0)
 				goto err_close_obj;
-			}
 		}
 
 		bpf_program__set_ifindex(pos, ifindex);
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 169e347c76f6..ad274ac8d630 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -78,6 +78,7 @@ do {				\
 #define pr_warning(fmt, ...)	__pr(__pr_warning, fmt, ##__VA_ARGS__)
 #define pr_info(fmt, ...)	__pr(__pr_info, fmt, ##__VA_ARGS__)
 #define pr_debug(fmt, ...)	__pr(__pr_debug, fmt, ##__VA_ARGS__)
+#define pr_out(fmt, ...)	__base_pr(fmt, ##__VA_ARGS__)
 
 void libbpf_set_print(libbpf_print_fn_t warn,
 		      libbpf_print_fn_t info,
@@ -2682,6 +2683,13 @@ int libbpf_prog_type_by_name(const char *name, enum bpf_prog_type *prog_type,
 		*expected_attach_type = section_names[i].expected_attach_type;
 		return 0;
 	}
+
+	pr_warning("failed to guess program type based on section name '%s'\n", name);
+	pr_info("possible section(type) names are:");
+	for (i = 0; i < ARRAY_SIZE(section_names); i++) {
+		pr_out(" %s", section_names[i].sec);
+	}
+	pr_out("\n");
 	return -EINVAL;
 }
 
@@ -2701,6 +2709,14 @@ int libbpf_attach_type_by_name(const char *name,
 		*attach_type = section_names[i].attach_type;
 		return 0;
 	}
+
+	pr_warning("failed to guess attach type based on section name '%s'\n", name);
+	pr_info("attachable section(type) names are:");
+	for (i = 0; i < ARRAY_SIZE(section_names); i++) {
+		if (section_names[i].is_attachable)
+			pr_out(" %s", section_names[i].sec);
+	}
+	pr_out("\n");
 	return -EINVAL;
 }
 
@@ -2907,8 +2923,6 @@ int bpf_prog_load_xattr(const struct bpf_prog_load_attr *attr,
 			err = bpf_program__identify_section(prog, &prog_type,
 							    &expected_attach_type);
 			if (err < 0) {
-				pr_warning("failed to guess program type based on section name %s\n",
-					   prog->section_name);
 				bpf_object__close(obj);
 				return -EINVAL;
 			}
diff --git a/tools/testing/selftests/bpf/test_socket_cookie.c b/tools/testing/selftests/bpf/test_socket_cookie.c
index b6c2c605d8c0..27c1576198d7 100644
--- a/tools/testing/selftests/bpf/test_socket_cookie.c
+++ b/tools/testing/selftests/bpf/test_socket_cookie.c
@@ -158,10 +158,8 @@ static int run_test(int cgfd)
 	bpf_object__for_each_program(prog, pobj) {
 		prog_name = bpf_program__title(prog, /*needs_copy*/ false);
 
-		if (libbpf_attach_type_by_name(prog_name, &attach_type)) {
-			log_err("Unexpected prog: %s", prog_name);
+		if (libbpf_attach_type_by_name(prog_name, &attach_type))
 			goto err;
-		}
 
 		err = bpf_prog_attach(bpf_program__fd(prog), cgfd, attach_type,
 				      BPF_F_ALLOW_OVERRIDE);
-- 
2.17.1