Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 | // SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2017 Facebook */ #include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <stdlib.h> #include <string.h> #include <linux/perf_event.h> #include <errno.h> #include <sys/resource.h> #include <bpf/libbpf.h> #include <bpf/bpf.h> /* This program verifies bpf attachment to tracepoint sys_enter_* and sys_exit_*. * This requires kernel CONFIG_FTRACE_SYSCALLS to be set. */ static void usage(const char *cmd) { printf("USAGE: %s [-i num_progs] [-h]\n", cmd); printf(" -i num_progs # number of progs of the test\n"); printf(" -h # help\n"); } static void verify_map(int map_id) { __u32 key = 0; __u32 val; if (bpf_map_lookup_elem(map_id, &key, &val) != 0) { fprintf(stderr, "map_lookup failed: %s\n", strerror(errno)); return; } if (val == 0) { fprintf(stderr, "failed: map #%d returns value 0\n", map_id); return; } val = 0; if (bpf_map_update_elem(map_id, &key, &val, BPF_ANY) != 0) { fprintf(stderr, "map_update failed: %s\n", strerror(errno)); return; } } static int test(char *filename, int num_progs) { int map0_fds[num_progs], map1_fds[num_progs], fd, i, j = 0; struct bpf_link *links[num_progs * 4]; struct bpf_object *objs[num_progs]; struct bpf_program *prog; for (i = 0; i < num_progs; i++) { objs[i] = bpf_object__open_file(filename, NULL); if (libbpf_get_error(objs[i])) { fprintf(stderr, "opening BPF object file failed\n"); objs[i] = NULL; goto cleanup; } /* load BPF program */ if (bpf_object__load(objs[i])) { fprintf(stderr, "loading BPF object file failed\n"); goto cleanup; } map0_fds[i] = bpf_object__find_map_fd_by_name(objs[i], "enter_open_map"); map1_fds[i] = bpf_object__find_map_fd_by_name(objs[i], "exit_open_map"); if (map0_fds[i] < 0 || map1_fds[i] < 0) { fprintf(stderr, "finding a map in obj file failed\n"); goto cleanup; } bpf_object__for_each_program(prog, objs[i]) { links[j] = bpf_program__attach(prog); if (libbpf_get_error(links[j])) { fprintf(stderr, "bpf_program__attach failed\n"); links[j] = NULL; goto cleanup; } j++; } printf("prog #%d: map ids %d %d\n", i, map0_fds[i], map1_fds[i]); } /* current load_bpf_file has perf_event_open default pid = -1 * and cpu = 0, which permits attached bpf execution on * all cpus for all pid's. bpf program execution ignores * cpu affinity. */ /* trigger some "open" operations */ fd = open(filename, O_RDONLY); if (fd < 0) { fprintf(stderr, "open failed: %s\n", strerror(errno)); return 1; } close(fd); /* verify the map */ for (i = 0; i < num_progs; i++) { verify_map(map0_fds[i]); verify_map(map1_fds[i]); } cleanup: for (j--; j >= 0; j--) bpf_link__destroy(links[j]); for (i--; i >= 0; i--) bpf_object__close(objs[i]); return 0; } int main(int argc, char **argv) { struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY}; int opt, num_progs = 1; char filename[256]; while ((opt = getopt(argc, argv, "i:h")) != -1) { switch (opt) { case 'i': num_progs = atoi(optarg); break; case 'h': default: usage(argv[0]); return 0; } } setrlimit(RLIMIT_MEMLOCK, &r); snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]); return test(filename, num_progs); } |