12f4a32ccSToke Høiland-Jørgensen // SPDX-License-Identifier: GPL-2.0 22f4a32ccSToke Høiland-Jørgensen 32f4a32ccSToke Høiland-Jørgensen #include <sys/types.h> 42f4a32ccSToke Høiland-Jørgensen #include <sys/stat.h> 52f4a32ccSToke Høiland-Jørgensen #include <unistd.h> 62f4a32ccSToke Høiland-Jørgensen #include <test_progs.h> 72f4a32ccSToke Høiland-Jørgensen 82f4a32ccSToke Høiland-Jørgensen __u32 get_map_id(struct bpf_object *obj, const char *name) 92f4a32ccSToke Høiland-Jørgensen { 102f4a32ccSToke Høiland-Jørgensen struct bpf_map_info map_info = {}; 112f4a32ccSToke Høiland-Jørgensen __u32 map_info_len, duration = 0; 122f4a32ccSToke Høiland-Jørgensen struct bpf_map *map; 132f4a32ccSToke Høiland-Jørgensen int err; 142f4a32ccSToke Høiland-Jørgensen 152f4a32ccSToke Høiland-Jørgensen map_info_len = sizeof(map_info); 162f4a32ccSToke Høiland-Jørgensen 172f4a32ccSToke Høiland-Jørgensen map = bpf_object__find_map_by_name(obj, name); 182f4a32ccSToke Høiland-Jørgensen if (CHECK(!map, "find map", "NULL map")) 192f4a32ccSToke Høiland-Jørgensen return 0; 202f4a32ccSToke Høiland-Jørgensen 212f4a32ccSToke Høiland-Jørgensen err = bpf_obj_get_info_by_fd(bpf_map__fd(map), 222f4a32ccSToke Høiland-Jørgensen &map_info, &map_info_len); 232f4a32ccSToke Høiland-Jørgensen CHECK(err, "get map info", "err %d errno %d", err, errno); 242f4a32ccSToke Høiland-Jørgensen return map_info.id; 252f4a32ccSToke Høiland-Jørgensen } 262f4a32ccSToke Høiland-Jørgensen 272f4a32ccSToke Høiland-Jørgensen void test_pinning(void) 282f4a32ccSToke Høiland-Jørgensen { 29*afef88e6SDaniel Müller const char *file_invalid = "./test_pinning_invalid.bpf.o"; 302f4a32ccSToke Høiland-Jørgensen const char *custpinpath = "/sys/fs/bpf/custom/pinmap"; 312f4a32ccSToke Høiland-Jørgensen const char *nopinpath = "/sys/fs/bpf/nopinmap"; 322f4a32ccSToke Høiland-Jørgensen const char *nopinpath2 = "/sys/fs/bpf/nopinmap2"; 332f4a32ccSToke Høiland-Jørgensen const char *custpath = "/sys/fs/bpf/custom"; 342f4a32ccSToke Høiland-Jørgensen const char *pinpath = "/sys/fs/bpf/pinmap"; 35*afef88e6SDaniel Müller const char *file = "./test_pinning.bpf.o"; 362f4a32ccSToke Høiland-Jørgensen __u32 map_id, map_id2, duration = 0; 372f4a32ccSToke Høiland-Jørgensen struct stat statbuf = {}; 382f4a32ccSToke Høiland-Jørgensen struct bpf_object *obj; 392f4a32ccSToke Høiland-Jørgensen struct bpf_map *map; 4044c4aa2bSHangbin Liu int err, map_fd; 412f4a32ccSToke Høiland-Jørgensen DECLARE_LIBBPF_OPTS(bpf_object_open_opts, opts, 422f4a32ccSToke Høiland-Jørgensen .pin_root_path = custpath, 432f4a32ccSToke Høiland-Jørgensen ); 442f4a32ccSToke Høiland-Jørgensen 452f4a32ccSToke Høiland-Jørgensen /* check that opening fails with invalid pinning value in map def */ 462f4a32ccSToke Høiland-Jørgensen obj = bpf_object__open_file(file_invalid, NULL); 472f4a32ccSToke Høiland-Jørgensen err = libbpf_get_error(obj); 482f4a32ccSToke Høiland-Jørgensen if (CHECK(err != -EINVAL, "invalid open", "err %d errno %d\n", err, errno)) { 492f4a32ccSToke Høiland-Jørgensen obj = NULL; 502f4a32ccSToke Høiland-Jørgensen goto out; 512f4a32ccSToke Høiland-Jørgensen } 522f4a32ccSToke Høiland-Jørgensen 532f4a32ccSToke Høiland-Jørgensen /* open the valid object file */ 542f4a32ccSToke Høiland-Jørgensen obj = bpf_object__open_file(file, NULL); 552f4a32ccSToke Høiland-Jørgensen err = libbpf_get_error(obj); 562f4a32ccSToke Høiland-Jørgensen if (CHECK(err, "default open", "err %d errno %d\n", err, errno)) { 572f4a32ccSToke Høiland-Jørgensen obj = NULL; 582f4a32ccSToke Høiland-Jørgensen goto out; 592f4a32ccSToke Høiland-Jørgensen } 602f4a32ccSToke Høiland-Jørgensen 612f4a32ccSToke Høiland-Jørgensen err = bpf_object__load(obj); 622f4a32ccSToke Høiland-Jørgensen if (CHECK(err, "default load", "err %d errno %d\n", err, errno)) 632f4a32ccSToke Høiland-Jørgensen goto out; 642f4a32ccSToke Høiland-Jørgensen 652f4a32ccSToke Høiland-Jørgensen /* check that pinmap was pinned */ 662f4a32ccSToke Høiland-Jørgensen err = stat(pinpath, &statbuf); 672f4a32ccSToke Høiland-Jørgensen if (CHECK(err, "stat pinpath", "err %d errno %d\n", err, errno)) 682f4a32ccSToke Høiland-Jørgensen goto out; 692f4a32ccSToke Høiland-Jørgensen 702f4a32ccSToke Høiland-Jørgensen /* check that nopinmap was *not* pinned */ 712f4a32ccSToke Høiland-Jørgensen err = stat(nopinpath, &statbuf); 722f4a32ccSToke Høiland-Jørgensen if (CHECK(!err || errno != ENOENT, "stat nopinpath", 732f4a32ccSToke Høiland-Jørgensen "err %d errno %d\n", err, errno)) 742f4a32ccSToke Høiland-Jørgensen goto out; 752f4a32ccSToke Høiland-Jørgensen 762f4a32ccSToke Høiland-Jørgensen /* check that nopinmap2 was *not* pinned */ 772f4a32ccSToke Høiland-Jørgensen err = stat(nopinpath2, &statbuf); 782f4a32ccSToke Høiland-Jørgensen if (CHECK(!err || errno != ENOENT, "stat nopinpath2", 792f4a32ccSToke Høiland-Jørgensen "err %d errno %d\n", err, errno)) 802f4a32ccSToke Høiland-Jørgensen goto out; 812f4a32ccSToke Høiland-Jørgensen 822f4a32ccSToke Høiland-Jørgensen map_id = get_map_id(obj, "pinmap"); 832f4a32ccSToke Høiland-Jørgensen if (!map_id) 842f4a32ccSToke Høiland-Jørgensen goto out; 852f4a32ccSToke Høiland-Jørgensen 862f4a32ccSToke Høiland-Jørgensen bpf_object__close(obj); 872f4a32ccSToke Høiland-Jørgensen 882f4a32ccSToke Høiland-Jørgensen obj = bpf_object__open_file(file, NULL); 892f4a32ccSToke Høiland-Jørgensen if (CHECK_FAIL(libbpf_get_error(obj))) { 902f4a32ccSToke Høiland-Jørgensen obj = NULL; 912f4a32ccSToke Høiland-Jørgensen goto out; 922f4a32ccSToke Høiland-Jørgensen } 932f4a32ccSToke Høiland-Jørgensen 942f4a32ccSToke Høiland-Jørgensen err = bpf_object__load(obj); 952f4a32ccSToke Høiland-Jørgensen if (CHECK(err, "default load", "err %d errno %d\n", err, errno)) 962f4a32ccSToke Høiland-Jørgensen goto out; 972f4a32ccSToke Høiland-Jørgensen 982f4a32ccSToke Høiland-Jørgensen /* check that same map ID was reused for second load */ 992f4a32ccSToke Høiland-Jørgensen map_id2 = get_map_id(obj, "pinmap"); 1002f4a32ccSToke Høiland-Jørgensen if (CHECK(map_id != map_id2, "check reuse", 1012f4a32ccSToke Høiland-Jørgensen "err %d errno %d id %d id2 %d\n", err, errno, map_id, map_id2)) 1022f4a32ccSToke Høiland-Jørgensen goto out; 1032f4a32ccSToke Høiland-Jørgensen 1042f4a32ccSToke Høiland-Jørgensen /* should be no-op to re-pin same map */ 1052f4a32ccSToke Høiland-Jørgensen map = bpf_object__find_map_by_name(obj, "pinmap"); 1062f4a32ccSToke Høiland-Jørgensen if (CHECK(!map, "find map", "NULL map")) 1072f4a32ccSToke Høiland-Jørgensen goto out; 1082f4a32ccSToke Høiland-Jørgensen 1092f4a32ccSToke Høiland-Jørgensen err = bpf_map__pin(map, NULL); 1102f4a32ccSToke Høiland-Jørgensen if (CHECK(err, "re-pin map", "err %d errno %d\n", err, errno)) 1112f4a32ccSToke Høiland-Jørgensen goto out; 1122f4a32ccSToke Høiland-Jørgensen 1132f4a32ccSToke Høiland-Jørgensen /* but error to pin at different location */ 1142f4a32ccSToke Høiland-Jørgensen err = bpf_map__pin(map, "/sys/fs/bpf/other"); 1152f4a32ccSToke Høiland-Jørgensen if (CHECK(!err, "pin map different", "err %d errno %d\n", err, errno)) 1162f4a32ccSToke Høiland-Jørgensen goto out; 1172f4a32ccSToke Høiland-Jørgensen 1182f4a32ccSToke Høiland-Jørgensen /* unpin maps with a pin_path set */ 1192f4a32ccSToke Høiland-Jørgensen err = bpf_object__unpin_maps(obj, NULL); 1202f4a32ccSToke Høiland-Jørgensen if (CHECK(err, "unpin maps", "err %d errno %d\n", err, errno)) 1212f4a32ccSToke Høiland-Jørgensen goto out; 1222f4a32ccSToke Høiland-Jørgensen 1232f4a32ccSToke Høiland-Jørgensen /* and re-pin them... */ 1242f4a32ccSToke Høiland-Jørgensen err = bpf_object__pin_maps(obj, NULL); 1252f4a32ccSToke Høiland-Jørgensen if (CHECK(err, "pin maps", "err %d errno %d\n", err, errno)) 1262f4a32ccSToke Høiland-Jørgensen goto out; 1272f4a32ccSToke Høiland-Jørgensen 128e244d34dSEvgeniy Litvinenko /* get pinning path */ 129e244d34dSEvgeniy Litvinenko if (!ASSERT_STREQ(bpf_map__pin_path(map), pinpath, "get pin path")) 130e244d34dSEvgeniy Litvinenko goto out; 131e244d34dSEvgeniy Litvinenko 1322f4a32ccSToke Høiland-Jørgensen /* set pinning path of other map and re-pin all */ 1332f4a32ccSToke Høiland-Jørgensen map = bpf_object__find_map_by_name(obj, "nopinmap"); 1342f4a32ccSToke Høiland-Jørgensen if (CHECK(!map, "find map", "NULL map")) 1352f4a32ccSToke Høiland-Jørgensen goto out; 1362f4a32ccSToke Høiland-Jørgensen 1372f4a32ccSToke Høiland-Jørgensen err = bpf_map__set_pin_path(map, custpinpath); 1382f4a32ccSToke Høiland-Jørgensen if (CHECK(err, "set pin path", "err %d errno %d\n", err, errno)) 1392f4a32ccSToke Høiland-Jørgensen goto out; 1402f4a32ccSToke Høiland-Jørgensen 141e244d34dSEvgeniy Litvinenko /* get pinning path after set */ 142e244d34dSEvgeniy Litvinenko if (!ASSERT_STREQ(bpf_map__pin_path(map), custpinpath, 143e244d34dSEvgeniy Litvinenko "get pin path after set")) 144e244d34dSEvgeniy Litvinenko goto out; 145e244d34dSEvgeniy Litvinenko 1462f4a32ccSToke Høiland-Jørgensen /* should only pin the one unpinned map */ 1472f4a32ccSToke Høiland-Jørgensen err = bpf_object__pin_maps(obj, NULL); 1482f4a32ccSToke Høiland-Jørgensen if (CHECK(err, "pin maps", "err %d errno %d\n", err, errno)) 1492f4a32ccSToke Høiland-Jørgensen goto out; 1502f4a32ccSToke Høiland-Jørgensen 1512f4a32ccSToke Høiland-Jørgensen /* check that nopinmap was pinned at the custom path */ 1522f4a32ccSToke Høiland-Jørgensen err = stat(custpinpath, &statbuf); 1532f4a32ccSToke Høiland-Jørgensen if (CHECK(err, "stat custpinpath", "err %d errno %d\n", err, errno)) 1542f4a32ccSToke Høiland-Jørgensen goto out; 1552f4a32ccSToke Høiland-Jørgensen 1562f4a32ccSToke Høiland-Jørgensen /* remove the custom pin path to re-test it with auto-pinning below */ 1572f4a32ccSToke Høiland-Jørgensen err = unlink(custpinpath); 1582f4a32ccSToke Høiland-Jørgensen if (CHECK(err, "unlink custpinpath", "err %d errno %d\n", err, errno)) 1592f4a32ccSToke Høiland-Jørgensen goto out; 1602f4a32ccSToke Høiland-Jørgensen 1612f4a32ccSToke Høiland-Jørgensen err = rmdir(custpath); 1622f4a32ccSToke Høiland-Jørgensen if (CHECK(err, "rmdir custpindir", "err %d errno %d\n", err, errno)) 1632f4a32ccSToke Høiland-Jørgensen goto out; 1642f4a32ccSToke Høiland-Jørgensen 1652f4a32ccSToke Høiland-Jørgensen bpf_object__close(obj); 1662f4a32ccSToke Høiland-Jørgensen 1672f4a32ccSToke Høiland-Jørgensen /* open the valid object file again */ 1682f4a32ccSToke Høiland-Jørgensen obj = bpf_object__open_file(file, NULL); 1692f4a32ccSToke Høiland-Jørgensen err = libbpf_get_error(obj); 1702f4a32ccSToke Høiland-Jørgensen if (CHECK(err, "default open", "err %d errno %d\n", err, errno)) { 1712f4a32ccSToke Høiland-Jørgensen obj = NULL; 1722f4a32ccSToke Høiland-Jørgensen goto out; 1732f4a32ccSToke Høiland-Jørgensen } 1742f4a32ccSToke Høiland-Jørgensen 1759c4e395aSToke Høiland-Jørgensen /* set pin paths so that nopinmap2 will attempt to reuse the map at 1769c4e395aSToke Høiland-Jørgensen * pinpath (which will fail), but not before pinmap has already been 1779c4e395aSToke Høiland-Jørgensen * reused 1789c4e395aSToke Høiland-Jørgensen */ 1792f4a32ccSToke Høiland-Jørgensen bpf_object__for_each_map(map, obj) { 1802f4a32ccSToke Høiland-Jørgensen if (!strcmp(bpf_map__name(map), "nopinmap")) 1819c4e395aSToke Høiland-Jørgensen err = bpf_map__set_pin_path(map, nopinpath2); 1829c4e395aSToke Høiland-Jørgensen else if (!strcmp(bpf_map__name(map), "nopinmap2")) 1832f4a32ccSToke Høiland-Jørgensen err = bpf_map__set_pin_path(map, pinpath); 1842f4a32ccSToke Høiland-Jørgensen else 1852f4a32ccSToke Høiland-Jørgensen continue; 1862f4a32ccSToke Høiland-Jørgensen 1872f4a32ccSToke Høiland-Jørgensen if (CHECK(err, "set pin path", "err %d errno %d\n", err, errno)) 1882f4a32ccSToke Høiland-Jørgensen goto out; 1892f4a32ccSToke Høiland-Jørgensen } 1902f4a32ccSToke Høiland-Jørgensen 1912f4a32ccSToke Høiland-Jørgensen /* should fail because of map parameter mismatch */ 1922f4a32ccSToke Høiland-Jørgensen err = bpf_object__load(obj); 1932f4a32ccSToke Høiland-Jørgensen if (CHECK(err != -EINVAL, "param mismatch load", "err %d errno %d\n", err, errno)) 1942f4a32ccSToke Høiland-Jørgensen goto out; 1952f4a32ccSToke Høiland-Jørgensen 1969c4e395aSToke Høiland-Jørgensen /* nopinmap2 should have been pinned and cleaned up again */ 1979c4e395aSToke Høiland-Jørgensen err = stat(nopinpath2, &statbuf); 1989c4e395aSToke Høiland-Jørgensen if (CHECK(!err || errno != ENOENT, "stat nopinpath2", 1999c4e395aSToke Høiland-Jørgensen "err %d errno %d\n", err, errno)) 2009c4e395aSToke Høiland-Jørgensen goto out; 2019c4e395aSToke Høiland-Jørgensen 2029c4e395aSToke Høiland-Jørgensen /* pinmap should still be there */ 2039c4e395aSToke Høiland-Jørgensen err = stat(pinpath, &statbuf); 2049c4e395aSToke Høiland-Jørgensen if (CHECK(err, "stat pinpath", "err %d errno %d\n", err, errno)) 2059c4e395aSToke Høiland-Jørgensen goto out; 2069c4e395aSToke Høiland-Jørgensen 2072f4a32ccSToke Høiland-Jørgensen bpf_object__close(obj); 2082f4a32ccSToke Høiland-Jørgensen 2092f4a32ccSToke Høiland-Jørgensen /* test auto-pinning at custom path with open opt */ 2102f4a32ccSToke Høiland-Jørgensen obj = bpf_object__open_file(file, &opts); 2112f4a32ccSToke Høiland-Jørgensen if (CHECK_FAIL(libbpf_get_error(obj))) { 2122f4a32ccSToke Høiland-Jørgensen obj = NULL; 2132f4a32ccSToke Høiland-Jørgensen goto out; 2142f4a32ccSToke Høiland-Jørgensen } 2152f4a32ccSToke Høiland-Jørgensen 2162f4a32ccSToke Høiland-Jørgensen err = bpf_object__load(obj); 2172f4a32ccSToke Høiland-Jørgensen if (CHECK(err, "custom load", "err %d errno %d\n", err, errno)) 2182f4a32ccSToke Høiland-Jørgensen goto out; 2192f4a32ccSToke Høiland-Jørgensen 2202f4a32ccSToke Høiland-Jørgensen /* check that pinmap was pinned at the custom path */ 2212f4a32ccSToke Høiland-Jørgensen err = stat(custpinpath, &statbuf); 2222f4a32ccSToke Høiland-Jørgensen if (CHECK(err, "stat custpinpath", "err %d errno %d\n", err, errno)) 2232f4a32ccSToke Høiland-Jørgensen goto out; 2242f4a32ccSToke Høiland-Jørgensen 22544c4aa2bSHangbin Liu /* remove the custom pin path to re-test it with reuse fd below */ 22644c4aa2bSHangbin Liu err = unlink(custpinpath); 22744c4aa2bSHangbin Liu if (CHECK(err, "unlink custpinpath", "err %d errno %d\n", err, errno)) 22844c4aa2bSHangbin Liu goto out; 22944c4aa2bSHangbin Liu 23044c4aa2bSHangbin Liu err = rmdir(custpath); 23144c4aa2bSHangbin Liu if (CHECK(err, "rmdir custpindir", "err %d errno %d\n", err, errno)) 23244c4aa2bSHangbin Liu goto out; 23344c4aa2bSHangbin Liu 23444c4aa2bSHangbin Liu bpf_object__close(obj); 23544c4aa2bSHangbin Liu 23644c4aa2bSHangbin Liu /* test pinning at custom path with reuse fd */ 23744c4aa2bSHangbin Liu obj = bpf_object__open_file(file, NULL); 23844c4aa2bSHangbin Liu err = libbpf_get_error(obj); 23944c4aa2bSHangbin Liu if (CHECK(err, "default open", "err %d errno %d\n", err, errno)) { 24044c4aa2bSHangbin Liu obj = NULL; 24144c4aa2bSHangbin Liu goto out; 24244c4aa2bSHangbin Liu } 24344c4aa2bSHangbin Liu 2442fe256a4SAndrii Nakryiko map_fd = bpf_map_create(BPF_MAP_TYPE_ARRAY, NULL, sizeof(__u32), 2452fe256a4SAndrii Nakryiko sizeof(__u64), 1, NULL); 24644c4aa2bSHangbin Liu if (CHECK(map_fd < 0, "create pinmap manually", "fd %d\n", map_fd)) 24744c4aa2bSHangbin Liu goto out; 24844c4aa2bSHangbin Liu 24944c4aa2bSHangbin Liu map = bpf_object__find_map_by_name(obj, "pinmap"); 25044c4aa2bSHangbin Liu if (CHECK(!map, "find map", "NULL map")) 25144c4aa2bSHangbin Liu goto close_map_fd; 25244c4aa2bSHangbin Liu 25344c4aa2bSHangbin Liu err = bpf_map__reuse_fd(map, map_fd); 25444c4aa2bSHangbin Liu if (CHECK(err, "reuse pinmap fd", "err %d errno %d\n", err, errno)) 25544c4aa2bSHangbin Liu goto close_map_fd; 25644c4aa2bSHangbin Liu 25744c4aa2bSHangbin Liu err = bpf_map__set_pin_path(map, custpinpath); 25844c4aa2bSHangbin Liu if (CHECK(err, "set pin path", "err %d errno %d\n", err, errno)) 25944c4aa2bSHangbin Liu goto close_map_fd; 26044c4aa2bSHangbin Liu 26144c4aa2bSHangbin Liu err = bpf_object__load(obj); 26244c4aa2bSHangbin Liu if (CHECK(err, "custom load", "err %d errno %d\n", err, errno)) 26344c4aa2bSHangbin Liu goto close_map_fd; 26444c4aa2bSHangbin Liu 26544c4aa2bSHangbin Liu /* check that pinmap was pinned at the custom path */ 26644c4aa2bSHangbin Liu err = stat(custpinpath, &statbuf); 26744c4aa2bSHangbin Liu if (CHECK(err, "stat custpinpath", "err %d errno %d\n", err, errno)) 26844c4aa2bSHangbin Liu goto close_map_fd; 26944c4aa2bSHangbin Liu 27044c4aa2bSHangbin Liu close_map_fd: 27144c4aa2bSHangbin Liu close(map_fd); 2722f4a32ccSToke Høiland-Jørgensen out: 2732f4a32ccSToke Høiland-Jørgensen unlink(pinpath); 2742f4a32ccSToke Høiland-Jørgensen unlink(nopinpath); 2752f4a32ccSToke Høiland-Jørgensen unlink(nopinpath2); 2762f4a32ccSToke Høiland-Jørgensen unlink(custpinpath); 2772f4a32ccSToke Høiland-Jørgensen rmdir(custpath); 2782f4a32ccSToke Høiland-Jørgensen if (obj) 2792f4a32ccSToke Høiland-Jørgensen bpf_object__close(obj); 2802f4a32ccSToke Høiland-Jørgensen } 281