// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2023 Meta Platforms, Inc. and affiliates. */
#include <errno.h>
#include <sys/syscall.h>
#include <unistd.h>
#include "test_global_map_resize.skel.h"
#include "test_progs.h"

static void run_prog_bss_array_sum(void)
{
	(void)syscall(__NR_getpid);
}

static void run_prog_data_array_sum(void)
{
	(void)syscall(__NR_getuid);
}

static void global_map_resize_bss_subtest(void)
{
	int err;
	struct test_global_map_resize *skel;
	struct bpf_map *map;
	const __u32 desired_sz = sizeof(skel->bss->sum) + sysconf(_SC_PAGE_SIZE) * 2;
	size_t array_len, actual_sz, new_sz;

	skel = test_global_map_resize__open();
	if (!ASSERT_OK_PTR(skel, "test_global_map_resize__open"))
		goto teardown;

	/* set some initial value before resizing.
	 * it is expected this non-zero value will be preserved
	 * while resizing.
	 */
	skel->bss->array[0] = 1;

	/* resize map value and verify the new size */
	map = skel->maps.bss;
	err = bpf_map__set_value_size(map, desired_sz);
	if (!ASSERT_OK(err, "bpf_map__set_value_size"))
		goto teardown;
	if (!ASSERT_EQ(bpf_map__value_size(map), desired_sz, "resize"))
		goto teardown;

	new_sz = sizeof(skel->data_percpu_arr->percpu_arr[0]) * libbpf_num_possible_cpus();
	err = bpf_map__set_value_size(skel->maps.data_percpu_arr, new_sz);
	ASSERT_OK(err, "percpu_arr_resize");

	/* set the expected number of elements based on the resized array */
	array_len = (desired_sz - sizeof(skel->bss->sum)) / sizeof(skel->bss->array[0]);
	if (!ASSERT_GT(array_len, 1, "array_len"))
		goto teardown;

	skel->bss = bpf_map__initial_value(skel->maps.bss, &actual_sz);
	if (!ASSERT_OK_PTR(skel->bss, "bpf_map__initial_value (ptr)"))
		goto teardown;
	if (!ASSERT_EQ(actual_sz, desired_sz, "bpf_map__initial_value (size)"))
		goto teardown;

	/* fill the newly resized array with ones,
	 * skipping the first element which was previously set
	 */
	for (int i = 1; i < array_len; i++)
		skel->bss->array[i] = 1;

	/* set global const values before loading */
	skel->rodata->pid = getpid();
	skel->rodata->bss_array_len = array_len;
	skel->rodata->data_array_len = 1;

	err = test_global_map_resize__load(skel);
	if (!ASSERT_OK(err, "test_global_map_resize__load"))
		goto teardown;
	err = test_global_map_resize__attach(skel);
	if (!ASSERT_OK(err, "test_global_map_resize__attach"))
		goto teardown;

	/* run the bpf program which will sum the contents of the array.
	 * since the array was filled with ones,verify the sum equals array_len
	 */
	run_prog_bss_array_sum();
	if (!ASSERT_EQ(skel->bss->sum, array_len, "sum"))
		goto teardown;

teardown:
	test_global_map_resize__destroy(skel);
}

static void global_map_resize_data_subtest(void)
{
	struct test_global_map_resize *skel;
	struct bpf_map *map;
	const __u32 desired_sz = sysconf(_SC_PAGE_SIZE) * 2;
	size_t array_len, actual_sz, new_sz;
	int err;

	skel = test_global_map_resize__open();
	if (!ASSERT_OK_PTR(skel, "test_global_map_resize__open"))
		goto teardown;

	/* set some initial value before resizing.
	 * it is expected this non-zero value will be preserved
	 * while resizing.
	 */
	skel->data_custom->my_array[0] = 1;

	/* resize map value and verify the new size */
	map = skel->maps.data_custom;
	err = bpf_map__set_value_size(map, desired_sz);
	if (!ASSERT_OK(err, "bpf_map__set_value_size"))
		goto teardown;
	if (!ASSERT_EQ(bpf_map__value_size(map), desired_sz, "resize"))
		goto teardown;

	new_sz = sizeof(skel->data_percpu_arr->percpu_arr[0]) * libbpf_num_possible_cpus();
	err = bpf_map__set_value_size(skel->maps.data_percpu_arr, new_sz);
	ASSERT_OK(err, "percpu_arr_resize");

	/* set the expected number of elements based on the resized array */
	array_len = (desired_sz - sizeof(skel->bss->sum)) / sizeof(skel->data_custom->my_array[0]);
	if (!ASSERT_GT(array_len, 1, "array_len"))
		goto teardown;

	skel->data_custom = bpf_map__initial_value(skel->maps.data_custom, &actual_sz);
	if (!ASSERT_OK_PTR(skel->data_custom, "bpf_map__initial_value (ptr)"))
		goto teardown;
	if (!ASSERT_EQ(actual_sz, desired_sz, "bpf_map__initial_value (size)"))
		goto teardown;

	/* fill the newly resized array with ones,
	 * skipping the first element which was previously set
	 */
	for (int i = 1; i < array_len; i++)
		skel->data_custom->my_array[i] = 1;

	/* set global const values before loading */
	skel->rodata->pid = getpid();
	skel->rodata->bss_array_len = 1;
	skel->rodata->data_array_len = array_len;

	err = test_global_map_resize__load(skel);
	if (!ASSERT_OK(err, "test_global_map_resize__load"))
		goto teardown;
	err = test_global_map_resize__attach(skel);
	if (!ASSERT_OK(err, "test_global_map_resize__attach"))
		goto teardown;

	/* run the bpf program which will sum the contents of the array.
	 * since the array was filled with ones,verify the sum equals array_len
	 */
	run_prog_data_array_sum();
	if (!ASSERT_EQ(skel->bss->sum, array_len, "sum"))
		goto teardown;

teardown:
	test_global_map_resize__destroy(skel);
}

static void global_map_resize_invalid_subtest(void)
{
	int err;
	struct test_global_map_resize *skel;
	struct bpf_map *map;
	__u32 element_sz, desired_sz;

	skel = test_global_map_resize__open();
	if (!ASSERT_OK_PTR(skel, "test_global_map_resize__open"))
		return;

	 /* attempt to resize a global datasec map to size
	  * which does NOT align with array
	  */
	map = skel->maps.data_custom;
	if (!ASSERT_NEQ(bpf_map__btf_value_type_id(map), 0, ".data.custom initial btf"))
		goto teardown;
	/* set desired size a fraction of element size beyond an aligned size */
	element_sz = sizeof(skel->data_custom->my_array[0]);
	desired_sz = element_sz + element_sz / 2;
	/* confirm desired size does NOT align with array */
	if (!ASSERT_NEQ(desired_sz % element_sz, 0, "my_array alignment"))
		goto teardown;
	err = bpf_map__set_value_size(map, desired_sz);
	/* confirm resize is OK but BTF info is cleared */
	if (!ASSERT_OK(err, ".data.custom bpf_map__set_value_size") ||
	    !ASSERT_EQ(bpf_map__btf_key_type_id(map), 0, ".data.custom clear btf key") ||
	    !ASSERT_EQ(bpf_map__btf_value_type_id(map), 0, ".data.custom clear btf val"))
		goto teardown;

	/* attempt to resize a global datasec map whose only var is NOT an array */
	map = skel->maps.data_non_array;
	if (!ASSERT_NEQ(bpf_map__btf_value_type_id(map), 0, ".data.non_array initial btf"))
		goto teardown;
	/* set desired size to arbitrary value */
	desired_sz = 1024;
	err = bpf_map__set_value_size(map, desired_sz);
	/* confirm resize is OK but BTF info is cleared */
	if (!ASSERT_OK(err, ".data.non_array bpf_map__set_value_size") ||
	    !ASSERT_EQ(bpf_map__btf_key_type_id(map), 0, ".data.non_array clear btf key") ||
	    !ASSERT_EQ(bpf_map__btf_value_type_id(map), 0, ".data.non_array clear btf val"))
		goto teardown;

	/* attempt to resize a global datasec map
	 * whose last var is NOT an array
	 */
	map = skel->maps.data_array_not_last;
	if (!ASSERT_NEQ(bpf_map__btf_value_type_id(map), 0, ".data.array_not_last initial btf"))
		goto teardown;
	/* set desired size to a multiple of element size */
	element_sz = sizeof(skel->data_array_not_last->my_array_first[0]);
	desired_sz = element_sz * 8;
	/* confirm desired size aligns with array */
	if (!ASSERT_EQ(desired_sz % element_sz, 0, "my_array_first alignment"))
		goto teardown;
	err = bpf_map__set_value_size(map, desired_sz);
	/* confirm resize is OK but BTF info is cleared */
	if (!ASSERT_OK(err, ".data.array_not_last bpf_map__set_value_size") ||
	    !ASSERT_EQ(bpf_map__btf_key_type_id(map), 0, ".data.array_not_last clear btf key") ||
	    !ASSERT_EQ(bpf_map__btf_value_type_id(map), 0, ".data.array_not_last clear btf val"))
		goto teardown;

teardown:
	test_global_map_resize__destroy(skel);
}

void test_global_map_resize(void)
{
	if (test__start_subtest("global_map_resize_bss"))
		global_map_resize_bss_subtest();

	if (test__start_subtest("global_map_resize_data"))
		global_map_resize_data_subtest();

	if (test__start_subtest("global_map_resize_invalid"))
		global_map_resize_invalid_subtest();
}
