Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /* Copyright (c) 2020 Facebook */
0003 
0004 #include <test_progs.h>
0005 #include <sys/stat.h>
0006 
0007 #include "test_link_pinning.skel.h"
0008 
0009 static int duration = 0;
0010 
0011 void test_link_pinning_subtest(struct bpf_program *prog,
0012                    struct test_link_pinning__bss *bss)
0013 {
0014     const char *link_pin_path = "/sys/fs/bpf/pinned_link_test";
0015     struct stat statbuf = {};
0016     struct bpf_link *link;
0017     int err, i;
0018 
0019     link = bpf_program__attach(prog);
0020     if (!ASSERT_OK_PTR(link, "link_attach"))
0021         goto cleanup;
0022 
0023     bss->in = 1;
0024     usleep(1);
0025     CHECK(bss->out != 1, "res_check1", "exp %d, got %d\n", 1, bss->out);
0026 
0027     /* pin link */
0028     err = bpf_link__pin(link, link_pin_path);
0029     if (CHECK(err, "link_pin", "err: %d\n", err))
0030         goto cleanup;
0031 
0032     CHECK(strcmp(link_pin_path, bpf_link__pin_path(link)), "pin_path1",
0033           "exp %s, got %s\n", link_pin_path, bpf_link__pin_path(link));
0034 
0035     /* check that link was pinned */
0036     err = stat(link_pin_path, &statbuf);
0037     if (CHECK(err, "stat_link", "err %d errno %d\n", err, errno))
0038         goto cleanup;
0039 
0040     bss->in = 2;
0041     usleep(1);
0042     CHECK(bss->out != 2, "res_check2", "exp %d, got %d\n", 2, bss->out);
0043 
0044     /* destroy link, pinned link should keep program attached */
0045     bpf_link__destroy(link);
0046     link = NULL;
0047 
0048     bss->in = 3;
0049     usleep(1);
0050     CHECK(bss->out != 3, "res_check3", "exp %d, got %d\n", 3, bss->out);
0051 
0052     /* re-open link from BPFFS */
0053     link = bpf_link__open(link_pin_path);
0054     if (!ASSERT_OK_PTR(link, "link_open"))
0055         goto cleanup;
0056 
0057     CHECK(strcmp(link_pin_path, bpf_link__pin_path(link)), "pin_path2",
0058           "exp %s, got %s\n", link_pin_path, bpf_link__pin_path(link));
0059 
0060     /* unpin link from BPFFS, program still attached */
0061     err = bpf_link__unpin(link);
0062     if (CHECK(err, "link_unpin", "err: %d\n", err))
0063         goto cleanup;
0064 
0065     /* still active, as we have FD open now */
0066     bss->in = 4;
0067     usleep(1);
0068     CHECK(bss->out != 4, "res_check4", "exp %d, got %d\n", 4, bss->out);
0069 
0070     bpf_link__destroy(link);
0071     link = NULL;
0072 
0073     /* Validate it's finally detached.
0074      * Actual detachment might get delayed a bit, so there is no reliable
0075      * way to validate it immediately here, let's count up for long enough
0076      * and see if eventually output stops being updated
0077      */
0078     for (i = 5; i < 10000; i++) {
0079         bss->in = i;
0080         usleep(1);
0081         if (bss->out == i - 1)
0082             break;
0083     }
0084     CHECK(i == 10000, "link_attached", "got to iteration #%d\n", i);
0085 
0086 cleanup:
0087     bpf_link__destroy(link);
0088 }
0089 
0090 void test_link_pinning(void)
0091 {
0092     struct test_link_pinning* skel;
0093 
0094     skel = test_link_pinning__open_and_load();
0095     if (CHECK(!skel, "skel_open", "failed to open skeleton\n"))
0096         return;
0097 
0098     if (test__start_subtest("pin_raw_tp"))
0099         test_link_pinning_subtest(skel->progs.raw_tp_prog, skel->bss);
0100     if (test__start_subtest("pin_tp_btf"))
0101         test_link_pinning_subtest(skel->progs.tp_btf_prog, skel->bss);
0102 
0103     test_link_pinning__destroy(skel);
0104 }