1 // SPDX-License-Identifier: GPL-2.0
6 #include <test_progs.h>
8 __u32
get_map_id(struct bpf_object
*obj
, const char *name
)
10 struct bpf_map_info map_info
= {};
11 __u32 map_info_len
, duration
= 0;
15 map_info_len
= sizeof(map_info
);
17 map
= bpf_object__find_map_by_name(obj
, name
);
18 if (CHECK(!map
, "find map", "NULL map"))
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
);
27 void test_pinning(void)
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
;
41 DECLARE_LIBBPF_OPTS(bpf_object_open_opts
, opts
,
42 .pin_root_path
= custpath
,
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
)) {
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
)) {
61 err
= bpf_object__load(obj
);
62 if (CHECK(err
, "default load", "err %d errno %d\n", err
, errno
))
65 /* check that pinmap was pinned */
66 err
= stat(pinpath
, &statbuf
);
67 if (CHECK(err
, "stat pinpath", "err %d errno %d\n", err
, errno
))
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
))
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
))
82 map_id
= get_map_id(obj
, "pinmap");
86 bpf_object__close(obj
);
88 obj
= bpf_object__open_file(file
, NULL
);
89 if (CHECK_FAIL(libbpf_get_error(obj
))) {
94 err
= bpf_object__load(obj
);
95 if (CHECK(err
, "default load", "err %d errno %d\n", err
, errno
))
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
))
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"))
109 err
= bpf_map__pin(map
, NULL
);
110 if (CHECK(err
, "re-pin map", "err %d errno %d\n", err
, errno
))
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
))
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
))
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
))
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"))
133 err
= bpf_map__set_pin_path(map
, custpinpath
);
134 if (CHECK(err
, "set pin path", "err %d errno %d\n", err
, errno
))
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
))
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
))
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
))
152 err
= rmdir(custpath
);
153 if (CHECK(err
, "rmdir custpindir", "err %d errno %d\n", err
, errno
))
156 bpf_object__close(obj
);
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
)) {
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
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
);
178 if (CHECK(err
, "set pin path", "err %d errno %d\n", err
, errno
))
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
))
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
))
193 /* pinmap should still be there */
194 err
= stat(pinpath
, &statbuf
);
195 if (CHECK(err
, "stat pinpath", "err %d errno %d\n", err
, errno
))
198 bpf_object__close(obj
);
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
))) {
207 err
= bpf_object__load(obj
);
208 if (CHECK(err
, "custom load", "err %d errno %d\n", err
, errno
))
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
))
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
))
221 err
= rmdir(custpath
);
222 if (CHECK(err
, "rmdir custpindir", "err %d errno %d\n", err
, errno
))
225 bpf_object__close(obj
);
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
)) {
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
))
240 map
= bpf_object__find_map_by_name(obj
, "pinmap");
241 if (CHECK(!map
, "find map", "NULL map"))
244 err
= bpf_map__reuse_fd(map
, map_fd
);
245 if (CHECK(err
, "reuse pinmap fd", "err %d errno %d\n", err
, errno
))
248 err
= bpf_map__set_pin_path(map
, custpinpath
);
249 if (CHECK(err
, "set pin path", "err %d errno %d\n", err
, errno
))
252 err
= bpf_object__load(obj
);
253 if (CHECK(err
, "custom load", "err %d errno %d\n", err
, errno
))
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
))
270 bpf_object__close(obj
);