libbpf: Add uprobe multi link detection
authorJiri Olsa <jolsa@kernel.org>
Wed, 9 Aug 2023 08:34:28 +0000 (10:34 +0200)
committerAlexei Starovoitov <ast@kernel.org>
Mon, 21 Aug 2023 22:51:26 +0000 (15:51 -0700)
Adding uprobe-multi link detection. It will be used later in
bpf_program__attach_usdt function to check and use uprobe_multi
link over standard uprobe links.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Link: https://lore.kernel.org/r/20230809083440.3209381-17-jolsa@kernel.org
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
tools/lib/bpf/libbpf.c
tools/lib/bpf/libbpf_internal.h

index c9c3905..07b6cbe 100644 (file)
@@ -4829,6 +4829,39 @@ static int probe_perf_link(void)
        return link_fd < 0 && err == -EBADF;
 }
 
+static int probe_uprobe_multi_link(void)
+{
+       LIBBPF_OPTS(bpf_prog_load_opts, load_opts,
+               .expected_attach_type = BPF_TRACE_UPROBE_MULTI,
+       );
+       LIBBPF_OPTS(bpf_link_create_opts, link_opts);
+       struct bpf_insn insns[] = {
+               BPF_MOV64_IMM(BPF_REG_0, 0),
+               BPF_EXIT_INSN(),
+       };
+       int prog_fd, link_fd, err;
+       unsigned long offset = 0;
+
+       prog_fd = bpf_prog_load(BPF_PROG_TYPE_KPROBE, NULL, "GPL",
+                               insns, ARRAY_SIZE(insns), &load_opts);
+       if (prog_fd < 0)
+               return -errno;
+
+       /* Creating uprobe in '/' binary should fail with -EBADF. */
+       link_opts.uprobe_multi.path = "/";
+       link_opts.uprobe_multi.offsets = &offset;
+       link_opts.uprobe_multi.cnt = 1;
+
+       link_fd = bpf_link_create(prog_fd, -1, BPF_TRACE_UPROBE_MULTI, &link_opts);
+       err = -errno; /* close() can clobber errno */
+
+       if (link_fd >= 0)
+               close(link_fd);
+       close(prog_fd);
+
+       return link_fd < 0 && err == -EBADF;
+}
+
 static int probe_kern_bpf_cookie(void)
 {
        struct bpf_insn insns[] = {
@@ -4925,6 +4958,9 @@ static struct kern_feature_desc {
        [FEAT_SYSCALL_WRAPPER] = {
                "Kernel using syscall wrapper", probe_kern_syscall_wrapper,
        },
+       [FEAT_UPROBE_MULTI_LINK] = {
+               "BPF multi-uprobe link support", probe_uprobe_multi_link,
+       },
 };
 
 bool kernel_supports(const struct bpf_object *obj, enum kern_feature_id feat_id)
index ead5513..f0f0863 100644 (file)
@@ -355,6 +355,8 @@ enum kern_feature_id {
        FEAT_BTF_ENUM64,
        /* Kernel uses syscall wrapper (CONFIG_ARCH_HAS_SYSCALL_WRAPPER) */
        FEAT_SYSCALL_WRAPPER,
+       /* BPF multi-uprobe link support */
+       FEAT_UPROBE_MULTI_LINK,
        __FEAT_CNT,
 };