brintos

brintos / linux-shallow public Read only

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