Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
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     /* check that opening fails with invalid pinning value in map def */
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     /* open the valid object file  */
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     /* check that pinmap was pinned */
0066     err = stat(pinpath, &statbuf);
0067     if (CHECK(err, "stat pinpath", "err %d errno %d\n", err, errno))
0068         goto out;
0069 
0070     /* check that nopinmap was *not* pinned */
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     /* check that nopinmap2 was *not* pinned */
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     /* check that same map ID was reused for second load */
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     /* should be no-op to re-pin same map */
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     /* but error to pin at different location */
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     /* unpin maps with a pin_path set */
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     /* and re-pin them... */
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     /* get pinning path */
0129     if (!ASSERT_STREQ(bpf_map__pin_path(map), pinpath, "get pin path"))
0130         goto out;
0131 
0132     /* set pinning path of other map and re-pin all */
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     /* get pinning path after set */
0142     if (!ASSERT_STREQ(bpf_map__pin_path(map), custpinpath,
0143               "get pin path after set"))
0144         goto out;
0145 
0146     /* should only pin the one unpinned map */
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     /* check that nopinmap was pinned at the custom path */
0152     err = stat(custpinpath, &statbuf);
0153     if (CHECK(err, "stat custpinpath", "err %d errno %d\n", err, errno))
0154         goto out;
0155 
0156     /* remove the custom pin path to re-test it with auto-pinning below */
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     /* open the valid object file again */
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     /* set pin paths so that nopinmap2 will attempt to reuse the map at
0176      * pinpath (which will fail), but not before pinmap has already been
0177      * reused
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     /* should fail because of map parameter mismatch */
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     /* nopinmap2 should have been pinned and cleaned up again */
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     /* pinmap should still be there */
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     /* test auto-pinning at custom path with open opt */
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     /* check that pinmap was pinned at the custom path */
0221     err = stat(custpinpath, &statbuf);
0222     if (CHECK(err, "stat custpinpath", "err %d errno %d\n", err, errno))
0223         goto out;
0224 
0225     /* remove the custom pin path to re-test it with reuse fd below */
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     /* test pinning at custom path with reuse fd */
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     /* check that pinmap was pinned at the custom path */
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 }