Linux Audio

Check our new training course

Loading...
Note: File does not exist in v5.4.
  1// SPDX-License-Identifier: GPL-2.0
  2
  3#include <sys/types.h>
  4#include <sys/stat.h>
  5#include <unistd.h>
  6#include <test_progs.h>
  7
  8__u32 get_map_id(struct bpf_object *obj, const char *name)
  9{
 10	struct bpf_map_info map_info = {};
 11	__u32 map_info_len, duration = 0;
 12	struct bpf_map *map;
 13	int err;
 14
 15	map_info_len = sizeof(map_info);
 16
 17	map = bpf_object__find_map_by_name(obj, name);
 18	if (CHECK(!map, "find map", "NULL map"))
 19		return 0;
 20
 21	err = bpf_obj_get_info_by_fd(bpf_map__fd(map),
 22				     &map_info, &map_info_len);
 23	CHECK(err, "get map info", "err %d errno %d", err, errno);
 24	return map_info.id;
 25}
 26
 27void test_pinning(void)
 28{
 29	const char *file_invalid = "./test_pinning_invalid.o";
 30	const char *custpinpath = "/sys/fs/bpf/custom/pinmap";
 31	const char *nopinpath = "/sys/fs/bpf/nopinmap";
 32	const char *nopinpath2 = "/sys/fs/bpf/nopinmap2";
 33	const char *custpath = "/sys/fs/bpf/custom";
 34	const char *pinpath = "/sys/fs/bpf/pinmap";
 35	const char *file = "./test_pinning.o";
 36	__u32 map_id, map_id2, duration = 0;
 37	struct stat statbuf = {};
 38	struct bpf_object *obj;
 39	struct bpf_map *map;
 40	int err, map_fd;
 41	DECLARE_LIBBPF_OPTS(bpf_object_open_opts, opts,
 42		.pin_root_path = custpath,
 43	);
 44
 45	/* check that opening fails with invalid pinning value in map def */
 46	obj = bpf_object__open_file(file_invalid, NULL);
 47	err = libbpf_get_error(obj);
 48	if (CHECK(err != -EINVAL, "invalid open", "err %d errno %d\n", err, errno)) {
 49		obj = NULL;
 50		goto out;
 51	}
 52
 53	/* open the valid object file  */
 54	obj = bpf_object__open_file(file, NULL);
 55	err = libbpf_get_error(obj);
 56	if (CHECK(err, "default open", "err %d errno %d\n", err, errno)) {
 57		obj = NULL;
 58		goto out;
 59	}
 60
 61	err = bpf_object__load(obj);
 62	if (CHECK(err, "default load", "err %d errno %d\n", err, errno))
 63		goto out;
 64
 65	/* check that pinmap was pinned */
 66	err = stat(pinpath, &statbuf);
 67	if (CHECK(err, "stat pinpath", "err %d errno %d\n", err, errno))
 68		goto out;
 69
 70	/* check that nopinmap was *not* pinned */
 71	err = stat(nopinpath, &statbuf);
 72	if (CHECK(!err || errno != ENOENT, "stat nopinpath",
 73		  "err %d errno %d\n", err, errno))
 74		goto out;
 75
 76	/* check that nopinmap2 was *not* pinned */
 77	err = stat(nopinpath2, &statbuf);
 78	if (CHECK(!err || errno != ENOENT, "stat nopinpath2",
 79		  "err %d errno %d\n", err, errno))
 80		goto out;
 81
 82	map_id = get_map_id(obj, "pinmap");
 83	if (!map_id)
 84		goto out;
 85
 86	bpf_object__close(obj);
 87
 88	obj = bpf_object__open_file(file, NULL);
 89	if (CHECK_FAIL(libbpf_get_error(obj))) {
 90		obj = NULL;
 91		goto out;
 92	}
 93
 94	err = bpf_object__load(obj);
 95	if (CHECK(err, "default load", "err %d errno %d\n", err, errno))
 96		goto out;
 97
 98	/* check that same map ID was reused for second load */
 99	map_id2 = get_map_id(obj, "pinmap");
100	if (CHECK(map_id != map_id2, "check reuse",
101		  "err %d errno %d id %d id2 %d\n", err, errno, map_id, map_id2))
102		goto out;
103
104	/* should be no-op to re-pin same map */
105	map = bpf_object__find_map_by_name(obj, "pinmap");
106	if (CHECK(!map, "find map", "NULL map"))
107		goto out;
108
109	err = bpf_map__pin(map, NULL);
110	if (CHECK(err, "re-pin map", "err %d errno %d\n", err, errno))
111		goto out;
112
113	/* but error to pin at different location */
114	err = bpf_map__pin(map, "/sys/fs/bpf/other");
115	if (CHECK(!err, "pin map different", "err %d errno %d\n", err, errno))
116		goto out;
117
118	/* unpin maps with a pin_path set */
119	err = bpf_object__unpin_maps(obj, NULL);
120	if (CHECK(err, "unpin maps", "err %d errno %d\n", err, errno))
121		goto out;
122
123	/* and re-pin them... */
124	err = bpf_object__pin_maps(obj, NULL);
125	if (CHECK(err, "pin maps", "err %d errno %d\n", err, errno))
126		goto out;
127
128	/* set pinning path of other map and re-pin all */
129	map = bpf_object__find_map_by_name(obj, "nopinmap");
130	if (CHECK(!map, "find map", "NULL map"))
131		goto out;
132
133	err = bpf_map__set_pin_path(map, custpinpath);
134	if (CHECK(err, "set pin path", "err %d errno %d\n", err, errno))
135		goto out;
136
137	/* should only pin the one unpinned map */
138	err = bpf_object__pin_maps(obj, NULL);
139	if (CHECK(err, "pin maps", "err %d errno %d\n", err, errno))
140		goto out;
141
142	/* check that nopinmap was pinned at the custom path */
143	err = stat(custpinpath, &statbuf);
144	if (CHECK(err, "stat custpinpath", "err %d errno %d\n", err, errno))
145		goto out;
146
147	/* remove the custom pin path to re-test it with auto-pinning below */
148	err = unlink(custpinpath);
149	if (CHECK(err, "unlink custpinpath", "err %d errno %d\n", err, errno))
150		goto out;
151
152	err = rmdir(custpath);
153	if (CHECK(err, "rmdir custpindir", "err %d errno %d\n", err, errno))
154		goto out;
155
156	bpf_object__close(obj);
157
158	/* open the valid object file again */
159	obj = bpf_object__open_file(file, NULL);
160	err = libbpf_get_error(obj);
161	if (CHECK(err, "default open", "err %d errno %d\n", err, errno)) {
162		obj = NULL;
163		goto out;
164	}
165
166	/* set pin paths so that nopinmap2 will attempt to reuse the map at
167	 * pinpath (which will fail), but not before pinmap has already been
168	 * reused
169	 */
170	bpf_object__for_each_map(map, obj) {
171		if (!strcmp(bpf_map__name(map), "nopinmap"))
172			err = bpf_map__set_pin_path(map, nopinpath2);
173		else if (!strcmp(bpf_map__name(map), "nopinmap2"))
174			err = bpf_map__set_pin_path(map, pinpath);
175		else
176			continue;
177
178		if (CHECK(err, "set pin path", "err %d errno %d\n", err, errno))
179			goto out;
180	}
181
182	/* should fail because of map parameter mismatch */
183	err = bpf_object__load(obj);
184	if (CHECK(err != -EINVAL, "param mismatch load", "err %d errno %d\n", err, errno))
185		goto out;
186
187	/* nopinmap2 should have been pinned and cleaned up again */
188	err = stat(nopinpath2, &statbuf);
189	if (CHECK(!err || errno != ENOENT, "stat nopinpath2",
190		  "err %d errno %d\n", err, errno))
191		goto out;
192
193	/* pinmap should still be there */
194	err = stat(pinpath, &statbuf);
195	if (CHECK(err, "stat pinpath", "err %d errno %d\n", err, errno))
196		goto out;
197
198	bpf_object__close(obj);
199
200	/* test auto-pinning at custom path with open opt */
201	obj = bpf_object__open_file(file, &opts);
202	if (CHECK_FAIL(libbpf_get_error(obj))) {
203		obj = NULL;
204		goto out;
205	}
206
207	err = bpf_object__load(obj);
208	if (CHECK(err, "custom load", "err %d errno %d\n", err, errno))
209		goto out;
210
211	/* check that pinmap was pinned at the custom path */
212	err = stat(custpinpath, &statbuf);
213	if (CHECK(err, "stat custpinpath", "err %d errno %d\n", err, errno))
214		goto out;
215
216	/* remove the custom pin path to re-test it with reuse fd below */
217	err = unlink(custpinpath);
218	if (CHECK(err, "unlink custpinpath", "err %d errno %d\n", err, errno))
219		goto out;
220
221	err = rmdir(custpath);
222	if (CHECK(err, "rmdir custpindir", "err %d errno %d\n", err, errno))
223		goto out;
224
225	bpf_object__close(obj);
226
227	/* test pinning at custom path with reuse fd */
228	obj = bpf_object__open_file(file, NULL);
229	err = libbpf_get_error(obj);
230	if (CHECK(err, "default open", "err %d errno %d\n", err, errno)) {
231		obj = NULL;
232		goto out;
233	}
234
235	map_fd = bpf_create_map(BPF_MAP_TYPE_ARRAY, sizeof(__u32),
236				sizeof(__u64), 1, 0);
237	if (CHECK(map_fd < 0, "create pinmap manually", "fd %d\n", map_fd))
238		goto out;
239
240	map = bpf_object__find_map_by_name(obj, "pinmap");
241	if (CHECK(!map, "find map", "NULL map"))
242		goto close_map_fd;
243
244	err = bpf_map__reuse_fd(map, map_fd);
245	if (CHECK(err, "reuse pinmap fd", "err %d errno %d\n", err, errno))
246		goto close_map_fd;
247
248	err = bpf_map__set_pin_path(map, custpinpath);
249	if (CHECK(err, "set pin path", "err %d errno %d\n", err, errno))
250		goto close_map_fd;
251
252	err = bpf_object__load(obj);
253	if (CHECK(err, "custom load", "err %d errno %d\n", err, errno))
254		goto close_map_fd;
255
256	/* check that pinmap was pinned at the custom path */
257	err = stat(custpinpath, &statbuf);
258	if (CHECK(err, "stat custpinpath", "err %d errno %d\n", err, errno))
259		goto close_map_fd;
260
261close_map_fd:
262	close(map_fd);
263out:
264	unlink(pinpath);
265	unlink(nopinpath);
266	unlink(nopinpath2);
267	unlink(custpinpath);
268	rmdir(custpath);
269	if (obj)
270		bpf_object__close(obj);
271}