1// SPDX-License-Identifier: GPL-2.0-only
2/* Copyright (c) 2016 Facebook
3 */
4#include <linux/unistd.h>
5#include <linux/bpf.h>
6
7#include <stdio.h>
8#include <stdint.h>
9#include <unistd.h>
10#include <string.h>
11#include <errno.h>
12#include <fcntl.h>
13
14#include <bpf/bpf.h>
15
16static void usage(void)
17{
18	printf("Usage: test_cgrp2_array_pin [...]\n");
19	printf("       -F <file>   File to pin an BPF cgroup array\n");
20	printf("       -U <file>   Update an already pinned BPF cgroup array\n");
21	printf("       -v <value>  Full path of the cgroup2\n");
22	printf("       -h          Display this help\n");
23}
24
25int main(int argc, char **argv)
26{
27	const char *pinned_file = NULL, *cg2 = NULL;
28	int create_array = 1;
29	int array_key = 0;
30	int array_fd = -1;
31	int cg2_fd = -1;
32	int ret = -1;
33	int opt;
34
35	while ((opt = getopt(argc, argv, "F:U:v:")) != -1) {
36		switch (opt) {
37		/* General args */
38		case 'F':
39			pinned_file = optarg;
40			break;
41		case 'U':
42			pinned_file = optarg;
43			create_array = 0;
44			break;
45		case 'v':
46			cg2 = optarg;
47			break;
48		default:
49			usage();
50			goto out;
51		}
52	}
53
54	if (!cg2 || !pinned_file) {
55		usage();
56		goto out;
57	}
58
59	cg2_fd = open(cg2, O_RDONLY);
60	if (cg2_fd < 0) {
61		fprintf(stderr, "open(%s,...): %s(%d)\n",
62			cg2, strerror(errno), errno);
63		goto out;
64	}
65
66	if (create_array) {
67		array_fd = bpf_map_create(BPF_MAP_TYPE_CGROUP_ARRAY, NULL,
68					  sizeof(uint32_t), sizeof(uint32_t),
69					  1, NULL);
70		if (array_fd < 0) {
71			fprintf(stderr,
72				"bpf_create_map(BPF_MAP_TYPE_CGROUP_ARRAY,...): %s(%d)\n",
73				strerror(errno), errno);
74			goto out;
75		}
76	} else {
77		array_fd = bpf_obj_get(pinned_file);
78		if (array_fd < 0) {
79			fprintf(stderr, "bpf_obj_get(%s): %s(%d)\n",
80				pinned_file, strerror(errno), errno);
81			goto out;
82		}
83	}
84
85	ret = bpf_map_update_elem(array_fd, &array_key, &cg2_fd, 0);
86	if (ret) {
87		perror("bpf_map_update_elem");
88		goto out;
89	}
90
91	if (create_array) {
92		ret = bpf_obj_pin(array_fd, pinned_file);
93		if (ret) {
94			fprintf(stderr, "bpf_obj_pin(..., %s): %s(%d)\n",
95				pinned_file, strerror(errno), errno);
96			goto out;
97		}
98	}
99
100out:
101	if (array_fd != -1)
102		close(array_fd);
103	if (cg2_fd != -1)
104		close(cg2_fd);
105	return ret;
106}
107