When rollbacking, the prepared trampolines should be reverted.

In this test, the first bpf prog will be attached with the trampoline, and
the second bpf prog won't be attached because the bpf prog has been
attached by a fentry.multi prog, that causes the rollback procedure.

Assisted-by: Codex:gpt-5.5
Signed-off-by: Leon Hwang <[email protected]>
---
 .../selftests/bpf/prog_tests/tracing_multi.c  | 63 +++++++++++++++++++
 1 file changed, 63 insertions(+)

diff --git a/tools/testing/selftests/bpf/prog_tests/tracing_multi.c 
b/tools/testing/selftests/bpf/prog_tests/tracing_multi.c
index bcf933760bc5..dfa24e229ff7 100644
--- a/tools/testing/selftests/bpf/prog_tests/tracing_multi.c
+++ b/tools/testing/selftests/bpf/prog_tests/tracing_multi.c
@@ -1308,6 +1308,67 @@ static void test_attach_api_bpf_prog_fails(void)
        free(ids);
 }
 
+static void test_rollback_bpf_prog(void)
+{
+       int token_fd, prog_fd, fd = -1, pre_fd = -1;
+       LIBBPF_OPTS(bpf_link_create_opts, lopts);
+       struct tracing_multi_bpf *skel = NULL;
+       __u32 target_ids[2], ids[2];
+       int target_fds[2], fds[2];
+       struct bpf_program *prog;
+       int first, second;
+
+       skel = tracing_multi_bpf__open_and_load();
+       if (!ASSERT_OK_PTR(skel, "tracing_multi_bpf__open_and_load"))
+               return;
+
+       token_fd = bpf_object__token_fd(skel->obj);
+       token_fd = token_fd < 0 ? 0 : token_fd;
+       target_fds[0] = bpf_program__fd(skel->progs.target_1);
+       target_fds[1] = bpf_program__fd(skel->progs.target_2);
+       target_ids[0] = libbpf_find_prog_btf_id("target_1", target_fds[0], 
token_fd);
+       if (!ASSERT_GT(target_ids[0], 0, "target_1_btf_id"))
+               goto cleanup;
+       target_ids[1] = libbpf_find_prog_btf_id("target_2", target_fds[1], 
token_fd);
+       if (!ASSERT_GT(target_ids[1], 0, "target_2_btf_id"))
+               goto cleanup;
+
+       first = target_fds[0] < target_fds[1] ? 0 : 1;
+       second = 1 - first;
+       fds[0] = target_fds[first];
+       fds[1] = target_fds[second];
+       ids[0] = target_ids[first];
+       ids[1] = target_ids[second];
+
+       prog_fd = bpf_program__fd(skel->progs.test_fentry);
+       lopts.tracing_multi.ids = &ids[1];
+       lopts.tracing_multi.fds = &fds[1];
+       lopts.tracing_multi.cnt = 1;
+       pre_fd = bpf_link_create(prog_fd, 0, BPF_TRACE_FENTRY_MULTI, &lopts);
+       if (!ASSERT_GE(pre_fd, 0, "pre_attach"))
+               goto cleanup;
+
+       lopts.tracing_multi.ids = ids;
+       lopts.tracing_multi.fds = fds;
+       lopts.tracing_multi.cnt = ARRAY_SIZE(ids);
+
+       fd = bpf_link_create(prog_fd, 0, BPF_TRACE_FENTRY_MULTI, &lopts);
+       if (!ASSERT_EQ(fd, -EBUSY, "bpf_link_create"))
+               goto cleanup;
+
+       prog = first == 0 ? skel->progs.target_1 : skel->progs.target_2;
+       if (run_bpf_target(prog, first + 1, "rollback_target"))
+               goto cleanup;
+       ASSERT_EQ(skel->bss->test_result_fentry, 0, "test_result_fentry");
+
+cleanup:
+       if (fd >= 0)
+               close(fd);
+       if (pre_fd >= 0)
+               close(pre_fd);
+       tracing_multi_bpf__destroy(skel);
+}
+
 void test_tracing_multi_prog_test(void)
 {
        if (test__start_subtest("link_api"))
@@ -1316,4 +1377,6 @@ void test_tracing_multi_prog_test(void)
                test_attach_api_bpf_prog_fails();
        if (test__start_subtest("cookies"))
                test_link_api_bpf_prog(true);
+       if (test__start_subtest("rollback"))
+               test_rollback_bpf_prog();
 }
-- 
2.55.0


Reply via email to