0001
0002
0003 #include <sys/types.h>
0004 #include <sys/stat.h>
0005 #include <unistd.h>
0006 #include <test_progs.h>
0007
0008 __u32 get_map_id(struct bpf_object *obj, const char *name)
0009 {
0010 struct bpf_map_info map_info = {};
0011 __u32 map_info_len, duration = 0;
0012 struct bpf_map *map;
0013 int err;
0014
0015 map_info_len = sizeof(map_info);
0016
0017 map = bpf_object__find_map_by_name(obj, name);
0018 if (CHECK(!map, "find map", "NULL map"))
0019 return 0;
0020
0021 err = bpf_obj_get_info_by_fd(bpf_map__fd(map),
0022 &map_info, &map_info_len);
0023 CHECK(err, "get map info", "err %d errno %d", err, errno);
0024 return map_info.id;
0025 }
0026
0027 void test_pinning(void)
0028 {
0029 const char *file_invalid = "./test_pinning_invalid.o";
0030 const char *custpinpath = "/sys/fs/bpf/custom/pinmap";
0031 const char *nopinpath = "/sys/fs/bpf/nopinmap";
0032 const char *nopinpath2 = "/sys/fs/bpf/nopinmap2";
0033 const char *custpath = "/sys/fs/bpf/custom";
0034 const char *pinpath = "/sys/fs/bpf/pinmap";
0035 const char *file = "./test_pinning.o";
0036 __u32 map_id, map_id2, duration = 0;
0037 struct stat statbuf = {};
0038 struct bpf_object *obj;
0039 struct bpf_map *map;
0040 int err, map_fd;
0041 DECLARE_LIBBPF_OPTS(bpf_object_open_opts, opts,
0042 .pin_root_path = custpath,
0043 );
0044
0045
0046 obj = bpf_object__open_file(file_invalid, NULL);
0047 err = libbpf_get_error(obj);
0048 if (CHECK(err != -EINVAL, "invalid open", "err %d errno %d\n", err, errno)) {
0049 obj = NULL;
0050 goto out;
0051 }
0052
0053
0054 obj = bpf_object__open_file(file, NULL);
0055 err = libbpf_get_error(obj);
0056 if (CHECK(err, "default open", "err %d errno %d\n", err, errno)) {
0057 obj = NULL;
0058 goto out;
0059 }
0060
0061 err = bpf_object__load(obj);
0062 if (CHECK(err, "default load", "err %d errno %d\n", err, errno))
0063 goto out;
0064
0065
0066 err = stat(pinpath, &statbuf);
0067 if (CHECK(err, "stat pinpath", "err %d errno %d\n", err, errno))
0068 goto out;
0069
0070
0071 err = stat(nopinpath, &statbuf);
0072 if (CHECK(!err || errno != ENOENT, "stat nopinpath",
0073 "err %d errno %d\n", err, errno))
0074 goto out;
0075
0076
0077 err = stat(nopinpath2, &statbuf);
0078 if (CHECK(!err || errno != ENOENT, "stat nopinpath2",
0079 "err %d errno %d\n", err, errno))
0080 goto out;
0081
0082 map_id = get_map_id(obj, "pinmap");
0083 if (!map_id)
0084 goto out;
0085
0086 bpf_object__close(obj);
0087
0088 obj = bpf_object__open_file(file, NULL);
0089 if (CHECK_FAIL(libbpf_get_error(obj))) {
0090 obj = NULL;
0091 goto out;
0092 }
0093
0094 err = bpf_object__load(obj);
0095 if (CHECK(err, "default load", "err %d errno %d\n", err, errno))
0096 goto out;
0097
0098
0099 map_id2 = get_map_id(obj, "pinmap");
0100 if (CHECK(map_id != map_id2, "check reuse",
0101 "err %d errno %d id %d id2 %d\n", err, errno, map_id, map_id2))
0102 goto out;
0103
0104
0105 map = bpf_object__find_map_by_name(obj, "pinmap");
0106 if (CHECK(!map, "find map", "NULL map"))
0107 goto out;
0108
0109 err = bpf_map__pin(map, NULL);
0110 if (CHECK(err, "re-pin map", "err %d errno %d\n", err, errno))
0111 goto out;
0112
0113
0114 err = bpf_map__pin(map, "/sys/fs/bpf/other");
0115 if (CHECK(!err, "pin map different", "err %d errno %d\n", err, errno))
0116 goto out;
0117
0118
0119 err = bpf_object__unpin_maps(obj, NULL);
0120 if (CHECK(err, "unpin maps", "err %d errno %d\n", err, errno))
0121 goto out;
0122
0123
0124 err = bpf_object__pin_maps(obj, NULL);
0125 if (CHECK(err, "pin maps", "err %d errno %d\n", err, errno))
0126 goto out;
0127
0128
0129 if (!ASSERT_STREQ(bpf_map__pin_path(map), pinpath, "get pin path"))
0130 goto out;
0131
0132
0133 map = bpf_object__find_map_by_name(obj, "nopinmap");
0134 if (CHECK(!map, "find map", "NULL map"))
0135 goto out;
0136
0137 err = bpf_map__set_pin_path(map, custpinpath);
0138 if (CHECK(err, "set pin path", "err %d errno %d\n", err, errno))
0139 goto out;
0140
0141
0142 if (!ASSERT_STREQ(bpf_map__pin_path(map), custpinpath,
0143 "get pin path after set"))
0144 goto out;
0145
0146
0147 err = bpf_object__pin_maps(obj, NULL);
0148 if (CHECK(err, "pin maps", "err %d errno %d\n", err, errno))
0149 goto out;
0150
0151
0152 err = stat(custpinpath, &statbuf);
0153 if (CHECK(err, "stat custpinpath", "err %d errno %d\n", err, errno))
0154 goto out;
0155
0156
0157 err = unlink(custpinpath);
0158 if (CHECK(err, "unlink custpinpath", "err %d errno %d\n", err, errno))
0159 goto out;
0160
0161 err = rmdir(custpath);
0162 if (CHECK(err, "rmdir custpindir", "err %d errno %d\n", err, errno))
0163 goto out;
0164
0165 bpf_object__close(obj);
0166
0167
0168 obj = bpf_object__open_file(file, NULL);
0169 err = libbpf_get_error(obj);
0170 if (CHECK(err, "default open", "err %d errno %d\n", err, errno)) {
0171 obj = NULL;
0172 goto out;
0173 }
0174
0175
0176
0177
0178
0179 bpf_object__for_each_map(map, obj) {
0180 if (!strcmp(bpf_map__name(map), "nopinmap"))
0181 err = bpf_map__set_pin_path(map, nopinpath2);
0182 else if (!strcmp(bpf_map__name(map), "nopinmap2"))
0183 err = bpf_map__set_pin_path(map, pinpath);
0184 else
0185 continue;
0186
0187 if (CHECK(err, "set pin path", "err %d errno %d\n", err, errno))
0188 goto out;
0189 }
0190
0191
0192 err = bpf_object__load(obj);
0193 if (CHECK(err != -EINVAL, "param mismatch load", "err %d errno %d\n", err, errno))
0194 goto out;
0195
0196
0197 err = stat(nopinpath2, &statbuf);
0198 if (CHECK(!err || errno != ENOENT, "stat nopinpath2",
0199 "err %d errno %d\n", err, errno))
0200 goto out;
0201
0202
0203 err = stat(pinpath, &statbuf);
0204 if (CHECK(err, "stat pinpath", "err %d errno %d\n", err, errno))
0205 goto out;
0206
0207 bpf_object__close(obj);
0208
0209
0210 obj = bpf_object__open_file(file, &opts);
0211 if (CHECK_FAIL(libbpf_get_error(obj))) {
0212 obj = NULL;
0213 goto out;
0214 }
0215
0216 err = bpf_object__load(obj);
0217 if (CHECK(err, "custom load", "err %d errno %d\n", err, errno))
0218 goto out;
0219
0220
0221 err = stat(custpinpath, &statbuf);
0222 if (CHECK(err, "stat custpinpath", "err %d errno %d\n", err, errno))
0223 goto out;
0224
0225
0226 err = unlink(custpinpath);
0227 if (CHECK(err, "unlink custpinpath", "err %d errno %d\n", err, errno))
0228 goto out;
0229
0230 err = rmdir(custpath);
0231 if (CHECK(err, "rmdir custpindir", "err %d errno %d\n", err, errno))
0232 goto out;
0233
0234 bpf_object__close(obj);
0235
0236
0237 obj = bpf_object__open_file(file, NULL);
0238 err = libbpf_get_error(obj);
0239 if (CHECK(err, "default open", "err %d errno %d\n", err, errno)) {
0240 obj = NULL;
0241 goto out;
0242 }
0243
0244 map_fd = bpf_map_create(BPF_MAP_TYPE_ARRAY, NULL, sizeof(__u32),
0245 sizeof(__u64), 1, NULL);
0246 if (CHECK(map_fd < 0, "create pinmap manually", "fd %d\n", map_fd))
0247 goto out;
0248
0249 map = bpf_object__find_map_by_name(obj, "pinmap");
0250 if (CHECK(!map, "find map", "NULL map"))
0251 goto close_map_fd;
0252
0253 err = bpf_map__reuse_fd(map, map_fd);
0254 if (CHECK(err, "reuse pinmap fd", "err %d errno %d\n", err, errno))
0255 goto close_map_fd;
0256
0257 err = bpf_map__set_pin_path(map, custpinpath);
0258 if (CHECK(err, "set pin path", "err %d errno %d\n", err, errno))
0259 goto close_map_fd;
0260
0261 err = bpf_object__load(obj);
0262 if (CHECK(err, "custom load", "err %d errno %d\n", err, errno))
0263 goto close_map_fd;
0264
0265
0266 err = stat(custpinpath, &statbuf);
0267 if (CHECK(err, "stat custpinpath", "err %d errno %d\n", err, errno))
0268 goto close_map_fd;
0269
0270 close_map_fd:
0271 close(map_fd);
0272 out:
0273 unlink(pinpath);
0274 unlink(nopinpath);
0275 unlink(nopinpath2);
0276 unlink(custpinpath);
0277 rmdir(custpath);
0278 if (obj)
0279 bpf_object__close(obj);
0280 }