// SPDX-License-Identifier: GPL-2.0

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <test_progs.h>

__u32 get_map_id(struct bpf_object *obj, const char *name)
{
	struct bpf_map_info map_info = {};
	__u32 map_info_len, duration = 0;
	struct bpf_map *map;
	int err;

	map_info_len = sizeof(map_info);

	map = bpf_object__find_map_by_name(obj, name);
	if (CHECK(!map, "find map", "NULL map"))
		return 0;

	err = bpf_obj_get_info_by_fd(bpf_map__fd(map),
				     &map_info, &map_info_len);
	CHECK(err, "get map info", "err %d errno %d", err, errno);
	return map_info.id;
}

void test_pinning(void)
{
	const char *file_invalid = "./test_pinning_invalid.o";
	const char *custpinpath = "/sys/fs/bpf/custom/pinmap";
	const char *nopinpath = "/sys/fs/bpf/nopinmap";
	const char *nopinpath2 = "/sys/fs/bpf/nopinmap2";
	const char *custpath = "/sys/fs/bpf/custom";
	const char *pinpath = "/sys/fs/bpf/pinmap";
	const char *file = "./test_pinning.o";
	__u32 map_id, map_id2, duration = 0;
	struct stat statbuf = {};
	struct bpf_object *obj;
	struct bpf_map *map;
	int err, map_fd;
	DECLARE_LIBBPF_OPTS(bpf_object_open_opts, opts,
		.pin_root_path = custpath,
	);

	/* check that opening fails with invalid pinning value in map def */
	obj = bpf_object__open_file(file_invalid, NULL);
	err = libbpf_get_error(obj);
	if (CHECK(err != -EINVAL, "invalid open", "err %d errno %d\n", err, errno)) {
		obj = NULL;
		goto out;
	}

	/* open the valid object file  */
	obj = bpf_object__open_file(file, NULL);
	err = libbpf_get_error(obj);
	if (CHECK(err, "default open", "err %d errno %d\n", err, errno)) {
		obj = NULL;
		goto out;
	}

	err = bpf_object__load(obj);
	if (CHECK(err, "default load", "err %d errno %d\n", err, errno))
		goto out;

	/* check that pinmap was pinned */
	err = stat(pinpath, &statbuf);
	if (CHECK(err, "stat pinpath", "err %d errno %d\n", err, errno))
		goto out;

	/* check that nopinmap was *not* pinned */
	err = stat(nopinpath, &statbuf);
	if (CHECK(!err || errno != ENOENT, "stat nopinpath",
		  "err %d errno %d\n", err, errno))
		goto out;

	/* check that nopinmap2 was *not* pinned */
	err = stat(nopinpath2, &statbuf);
	if (CHECK(!err || errno != ENOENT, "stat nopinpath2",
		  "err %d errno %d\n", err, errno))
		goto out;

	map_id = get_map_id(obj, "pinmap");
	if (!map_id)
		goto out;

	bpf_object__close(obj);

	obj = bpf_object__open_file(file, NULL);
	if (CHECK_FAIL(libbpf_get_error(obj))) {
		obj = NULL;
		goto out;
	}

	err = bpf_object__load(obj);
	if (CHECK(err, "default load", "err %d errno %d\n", err, errno))
		goto out;

	/* check that same map ID was reused for second load */
	map_id2 = get_map_id(obj, "pinmap");
	if (CHECK(map_id != map_id2, "check reuse",
		  "err %d errno %d id %d id2 %d\n", err, errno, map_id, map_id2))
		goto out;

	/* should be no-op to re-pin same map */
	map = bpf_object__find_map_by_name(obj, "pinmap");
	if (CHECK(!map, "find map", "NULL map"))
		goto out;

	err = bpf_map__pin(map, NULL);
	if (CHECK(err, "re-pin map", "err %d errno %d\n", err, errno))
		goto out;

	/* but error to pin at different location */
	err = bpf_map__pin(map, "/sys/fs/bpf/other");
	if (CHECK(!err, "pin map different", "err %d errno %d\n", err, errno))
		goto out;

	/* unpin maps with a pin_path set */
	err = bpf_object__unpin_maps(obj, NULL);
	if (CHECK(err, "unpin maps", "err %d errno %d\n", err, errno))
		goto out;

	/* and re-pin them... */
	err = bpf_object__pin_maps(obj, NULL);
	if (CHECK(err, "pin maps", "err %d errno %d\n", err, errno))
		goto out;

	/* set pinning path of other map and re-pin all */
	map = bpf_object__find_map_by_name(obj, "nopinmap");
	if (CHECK(!map, "find map", "NULL map"))
		goto out;

	err = bpf_map__set_pin_path(map, custpinpath);
	if (CHECK(err, "set pin path", "err %d errno %d\n", err, errno))
		goto out;

	/* should only pin the one unpinned map */
	err = bpf_object__pin_maps(obj, NULL);
	if (CHECK(err, "pin maps", "err %d errno %d\n", err, errno))
		goto out;

	/* check that nopinmap was pinned at the custom path */
	err = stat(custpinpath, &statbuf);
	if (CHECK(err, "stat custpinpath", "err %d errno %d\n", err, errno))
		goto out;

	/* remove the custom pin path to re-test it with auto-pinning below */
	err = unlink(custpinpath);
	if (CHECK(err, "unlink custpinpath", "err %d errno %d\n", err, errno))
		goto out;

	err = rmdir(custpath);
	if (CHECK(err, "rmdir custpindir", "err %d errno %d\n", err, errno))
		goto out;

	bpf_object__close(obj);

	/* open the valid object file again */
	obj = bpf_object__open_file(file, NULL);
	err = libbpf_get_error(obj);
	if (CHECK(err, "default open", "err %d errno %d\n", err, errno)) {
		obj = NULL;
		goto out;
	}

	/* set pin paths so that nopinmap2 will attempt to reuse the map at
	 * pinpath (which will fail), but not before pinmap has already been
	 * reused
	 */
	bpf_object__for_each_map(map, obj) {
		if (!strcmp(bpf_map__name(map), "nopinmap"))
			err = bpf_map__set_pin_path(map, nopinpath2);
		else if (!strcmp(bpf_map__name(map), "nopinmap2"))
			err = bpf_map__set_pin_path(map, pinpath);
		else
			continue;

		if (CHECK(err, "set pin path", "err %d errno %d\n", err, errno))
			goto out;
	}

	/* should fail because of map parameter mismatch */
	err = bpf_object__load(obj);
	if (CHECK(err != -EINVAL, "param mismatch load", "err %d errno %d\n", err, errno))
		goto out;

	/* nopinmap2 should have been pinned and cleaned up again */
	err = stat(nopinpath2, &statbuf);
	if (CHECK(!err || errno != ENOENT, "stat nopinpath2",
		  "err %d errno %d\n", err, errno))
		goto out;

	/* pinmap should still be there */
	err = stat(pinpath, &statbuf);
	if (CHECK(err, "stat pinpath", "err %d errno %d\n", err, errno))
		goto out;

	bpf_object__close(obj);

	/* test auto-pinning at custom path with open opt */
	obj = bpf_object__open_file(file, &opts);
	if (CHECK_FAIL(libbpf_get_error(obj))) {
		obj = NULL;
		goto out;
	}

	err = bpf_object__load(obj);
	if (CHECK(err, "custom load", "err %d errno %d\n", err, errno))
		goto out;

	/* check that pinmap was pinned at the custom path */
	err = stat(custpinpath, &statbuf);
	if (CHECK(err, "stat custpinpath", "err %d errno %d\n", err, errno))
		goto out;

	/* remove the custom pin path to re-test it with reuse fd below */
	err = unlink(custpinpath);
	if (CHECK(err, "unlink custpinpath", "err %d errno %d\n", err, errno))
		goto out;

	err = rmdir(custpath);
	if (CHECK(err, "rmdir custpindir", "err %d errno %d\n", err, errno))
		goto out;

	bpf_object__close(obj);

	/* test pinning at custom path with reuse fd */
	obj = bpf_object__open_file(file, NULL);
	err = libbpf_get_error(obj);
	if (CHECK(err, "default open", "err %d errno %d\n", err, errno)) {
		obj = NULL;
		goto out;
	}

	map_fd = bpf_create_map(BPF_MAP_TYPE_ARRAY, sizeof(__u32),
				sizeof(__u64), 1, 0);
	if (CHECK(map_fd < 0, "create pinmap manually", "fd %d\n", map_fd))
		goto out;

	map = bpf_object__find_map_by_name(obj, "pinmap");
	if (CHECK(!map, "find map", "NULL map"))
		goto close_map_fd;

	err = bpf_map__reuse_fd(map, map_fd);
	if (CHECK(err, "reuse pinmap fd", "err %d errno %d\n", err, errno))
		goto close_map_fd;

	err = bpf_map__set_pin_path(map, custpinpath);
	if (CHECK(err, "set pin path", "err %d errno %d\n", err, errno))
		goto close_map_fd;

	err = bpf_object__load(obj);
	if (CHECK(err, "custom load", "err %d errno %d\n", err, errno))
		goto close_map_fd;

	/* check that pinmap was pinned at the custom path */
	err = stat(custpinpath, &statbuf);
	if (CHECK(err, "stat custpinpath", "err %d errno %d\n", err, errno))
		goto close_map_fd;

close_map_fd:
	close(map_fd);
out:
	unlink(pinpath);
	unlink(nopinpath);
	unlink(nopinpath2);
	unlink(custpinpath);
	rmdir(custpath);
	if (obj)
		bpf_object__close(obj);
}
