105 lines · c
1// SPDX-License-Identifier: GPL-2.02/* Copyright (c) 2020 Facebook */3 4#include <test_progs.h>5#include <sys/stat.h>6 7#include "test_link_pinning.skel.h"8 9static int duration = 0;10 11void test_link_pinning_subtest(struct bpf_program *prog,12 struct test_link_pinning__bss *bss)13{14 const char *link_pin_path = "/sys/fs/bpf/pinned_link_test";15 struct stat statbuf = {};16 struct bpf_link *link;17 int err, i;18 19 link = bpf_program__attach(prog);20 if (!ASSERT_OK_PTR(link, "link_attach"))21 goto cleanup;22 23 bss->in = 1;24 usleep(1);25 CHECK(bss->out != 1, "res_check1", "exp %d, got %d\n", 1, bss->out);26 27 /* pin link */28 err = bpf_link__pin(link, link_pin_path);29 if (CHECK(err, "link_pin", "err: %d\n", err))30 goto cleanup;31 32 CHECK(strcmp(link_pin_path, bpf_link__pin_path(link)), "pin_path1",33 "exp %s, got %s\n", link_pin_path, bpf_link__pin_path(link));34 35 /* check that link was pinned */36 err = stat(link_pin_path, &statbuf);37 if (CHECK(err, "stat_link", "err %d errno %d\n", err, errno))38 goto cleanup;39 40 bss->in = 2;41 usleep(1);42 CHECK(bss->out != 2, "res_check2", "exp %d, got %d\n", 2, bss->out);43 44 /* destroy link, pinned link should keep program attached */45 bpf_link__destroy(link);46 link = NULL;47 48 bss->in = 3;49 usleep(1);50 CHECK(bss->out != 3, "res_check3", "exp %d, got %d\n", 3, bss->out);51 52 /* re-open link from BPFFS */53 link = bpf_link__open(link_pin_path);54 if (!ASSERT_OK_PTR(link, "link_open"))55 goto cleanup;56 57 CHECK(strcmp(link_pin_path, bpf_link__pin_path(link)), "pin_path2",58 "exp %s, got %s\n", link_pin_path, bpf_link__pin_path(link));59 60 /* unpin link from BPFFS, program still attached */61 err = bpf_link__unpin(link);62 if (CHECK(err, "link_unpin", "err: %d\n", err))63 goto cleanup;64 65 /* still active, as we have FD open now */66 bss->in = 4;67 usleep(1);68 CHECK(bss->out != 4, "res_check4", "exp %d, got %d\n", 4, bss->out);69 70 bpf_link__destroy(link);71 link = NULL;72 73 /* Validate it's finally detached.74 * Actual detachment might get delayed a bit, so there is no reliable75 * way to validate it immediately here, let's count up for long enough76 * and see if eventually output stops being updated77 */78 for (i = 5; i < 10000; i++) {79 bss->in = i;80 usleep(1);81 if (bss->out == i - 1)82 break;83 }84 CHECK(i == 10000, "link_attached", "got to iteration #%d\n", i);85 86cleanup:87 bpf_link__destroy(link);88}89 90void test_link_pinning(void)91{92 struct test_link_pinning* skel;93 94 skel = test_link_pinning__open_and_load();95 if (CHECK(!skel, "skel_open", "failed to open skeleton\n"))96 return;97 98 if (test__start_subtest("pin_raw_tp"))99 test_link_pinning_subtest(skel->progs.raw_tp_prog, skel->bss);100 if (test__start_subtest("pin_tp_btf"))101 test_link_pinning_subtest(skel->progs.tp_btf_prog, skel->bss);102 103 test_link_pinning__destroy(skel);104}105