/* SPDX-License-Identifier: GPL-2.0 */

#include <errno.h>
#include <linux/limits.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

#include "kselftest.h"
#include "../pidfd/pidfd.h"
#include "cgroup_util.h"

/*
 * Kill the given cgroup and wait for the inotify signal.
 * If there are no events in 10 seconds, treat this as an error.
 * Then check that the cgroup is in the desired state.
 */
static int cg_kill_wait(const char *cgroup)
{
	int fd, ret = -1;

	fd = cg_prepare_for_wait(cgroup);
	if (fd < 0)
		return fd;

	ret = cg_write(cgroup, "cgroup.kill", "1");
	if (ret)
		goto out;

	ret = cg_wait_for(fd);
	if (ret)
		goto out;

out:
	close(fd);
	return ret;
}

/*
 * A simple process running in a sleep loop until being
 * re-parented.
 */
static int child_fn(const char *cgroup, void *arg)
{
	int ppid = getppid();

	while (getppid() == ppid)
		usleep(1000);

	return getppid() == ppid;
}

static int test_cgkill_simple(const char *root)
{
	pid_t pids[100];
	int ret = KSFT_FAIL;
	char *cgroup = NULL;
	int i;

	cgroup = cg_name(root, "cg_test_simple");
	if (!cgroup)
		goto cleanup;

	if (cg_create(cgroup))
		goto cleanup;

	for (i = 0; i < 100; i++)
		pids[i] = cg_run_nowait(cgroup, child_fn, NULL);

	if (cg_wait_for_proc_count(cgroup, 100))
		goto cleanup;

	if (cg_read_strcmp(cgroup, "cgroup.events", "populated 1\n"))
		goto cleanup;

	if (cg_kill_wait(cgroup))
		goto cleanup;

	ret = KSFT_PASS;

cleanup:
	for (i = 0; i < 100; i++)
		wait_for_pid(pids[i]);

	if (ret == KSFT_PASS &&
	    cg_read_strcmp_wait(cgroup, "cgroup.events", "populated 0\n"))
		ret = KSFT_FAIL;

	if (cgroup)
		cg_destroy(cgroup);
	free(cgroup);
	return ret;
}

/*
 * The test creates the following hierarchy:
 *       A
 *    / / \ \
 *   B  E  I K
 *  /\  |
 * C  D F
 *      |
 *      G
 *      |
 *      H
 *
 * with a process in C, H and 3 processes in K.
 * Then it tries to kill the whole tree.
 */
static int test_cgkill_tree(const char *root)
{
	pid_t pids[5];
	char *cgroup[10] = {0};
	int ret = KSFT_FAIL;
	int i;

	cgroup[0] = cg_name(root, "cg_test_tree_A");
	if (!cgroup[0])
		goto cleanup;

	cgroup[1] = cg_name(cgroup[0], "B");
	if (!cgroup[1])
		goto cleanup;

	cgroup[2] = cg_name(cgroup[1], "C");
	if (!cgroup[2])
		goto cleanup;

	cgroup[3] = cg_name(cgroup[1], "D");
	if (!cgroup[3])
		goto cleanup;

	cgroup[4] = cg_name(cgroup[0], "E");
	if (!cgroup[4])
		goto cleanup;

	cgroup[5] = cg_name(cgroup[4], "F");
	if (!cgroup[5])
		goto cleanup;

	cgroup[6] = cg_name(cgroup[5], "G");
	if (!cgroup[6])
		goto cleanup;

	cgroup[7] = cg_name(cgroup[6], "H");
	if (!cgroup[7])
		goto cleanup;

	cgroup[8] = cg_name(cgroup[0], "I");
	if (!cgroup[8])
		goto cleanup;

	cgroup[9] = cg_name(cgroup[0], "K");
	if (!cgroup[9])
		goto cleanup;

	for (i = 0; i < 10; i++)
		if (cg_create(cgroup[i]))
			goto cleanup;

	pids[0] = cg_run_nowait(cgroup[2], child_fn, NULL);
	pids[1] = cg_run_nowait(cgroup[7], child_fn, NULL);
	pids[2] = cg_run_nowait(cgroup[9], child_fn, NULL);
	pids[3] = cg_run_nowait(cgroup[9], child_fn, NULL);
	pids[4] = cg_run_nowait(cgroup[9], child_fn, NULL);

	/*
	 * Wait until all child processes will enter
	 * corresponding cgroups.
	 */

	if (cg_wait_for_proc_count(cgroup[2], 1) ||
	    cg_wait_for_proc_count(cgroup[7], 1) ||
	    cg_wait_for_proc_count(cgroup[9], 3))
		goto cleanup;

	/*
	 * Kill A and check that we get an empty notification.
	 */
	if (cg_kill_wait(cgroup[0]))
		goto cleanup;

	ret = KSFT_PASS;

cleanup:
	for (i = 0; i < 5; i++)
		wait_for_pid(pids[i]);

	if (ret == KSFT_PASS &&
	    cg_read_strcmp_wait(cgroup[0], "cgroup.events",
				   "populated 0\n"))
		ret = KSFT_FAIL;

	for (i = 9; i >= 0 && cgroup[i]; i--) {
		cg_destroy(cgroup[i]);
		free(cgroup[i]);
	}

	return ret;
}

static int forkbomb_fn(const char *cgroup, void *arg)
{
	int ppid;

	fork();
	fork();

	ppid = getppid();

	while (getppid() == ppid)
		usleep(1000);

	return getppid() == ppid;
}

/*
 * The test runs a fork bomb in a cgroup and tries to kill it.
 */
static int test_cgkill_forkbomb(const char *root)
{
	int ret = KSFT_FAIL;
	char *cgroup = NULL;
	pid_t pid = -ESRCH;

	cgroup = cg_name(root, "cg_forkbomb_test");
	if (!cgroup)
		goto cleanup;

	if (cg_create(cgroup))
		goto cleanup;

	pid = cg_run_nowait(cgroup, forkbomb_fn, NULL);
	if (pid < 0)
		goto cleanup;

	usleep(100000);

	if (cg_kill_wait(cgroup))
		goto cleanup;

	if (cg_wait_for_proc_count(cgroup, 0))
		goto cleanup;

	ret = KSFT_PASS;

cleanup:
	if (pid > 0)
		wait_for_pid(pid);

	if (ret == KSFT_PASS &&
	    cg_read_strcmp_wait(cgroup, "cgroup.events", "populated 0\n"))
		ret = KSFT_FAIL;

	if (cgroup)
		cg_destroy(cgroup);
	free(cgroup);
	return ret;
}

/*
 * Test that a cgroup that was killed in the past can still be the target
 * of clone3(CLONE_INTO_CGROUP): writing cgroup.kill must only kill the
 * tasks in the cgroup at the time of the write, not tasks cloned into
 * it afterwards.
 */
static int test_cgkill_clone_into_killed(const char *root)
{
	pid_t pid;
	int cgroup_fd = -EBADF;
	int ret = KSFT_FAIL;
	char *cgroup = NULL;

	cgroup = cg_name(root, "cg_test_clone_into_killed");
	if (!cgroup)
		goto cleanup;

	if (cg_create(cgroup))
		goto cleanup;

	/* Kill the cgroup while it is still empty. */
	if (cg_write(cgroup, "cgroup.kill", "1"))
		goto cleanup;

	cgroup_fd = dirfd_open_opath(cgroup);
	if (cgroup_fd < 0)
		goto cleanup;

	pid = clone_into_cgroup(cgroup_fd);
	if (pid < 0) {
		if (errno == ENOSYS)
			ret = KSFT_SKIP;
		goto cleanup;
	}

	if (pid == 0)
		exit(EXIT_SUCCESS);

	/* The child must not be SIGKILLed; it has to exit cleanly. */
	if (clone_reap(pid, WEXITED) != EXIT_SUCCESS)
		goto cleanup;

	ret = KSFT_PASS;

cleanup:
	if (cgroup_fd >= 0)
		close(cgroup_fd);
	if (cgroup)
		cg_destroy(cgroup);
	free(cgroup);
	return ret;
}

#define T(x) { x, #x }
struct cgkill_test {
	int (*fn)(const char *root);
	const char *name;
} tests[] = {
	T(test_cgkill_simple),
	T(test_cgkill_tree),
	T(test_cgkill_forkbomb),
	T(test_cgkill_clone_into_killed),
};
#undef T

int main(int argc, char *argv[])
{
	char root[PATH_MAX];
	int i;

	ksft_print_header();
	if (cg_find_unified_root(root, sizeof(root), NULL))
		ksft_exit_skip("cgroup v2 isn't mounted\n");
	ksft_set_plan(ARRAY_SIZE(tests));
	for (i = 0; i < ARRAY_SIZE(tests); i++) {
		switch (tests[i].fn(root)) {
		case KSFT_PASS:
			ksft_test_result_pass("%s\n", tests[i].name);
			break;
		case KSFT_SKIP:
			ksft_test_result_skip("%s\n", tests[i].name);
			break;
		default:
			ksft_test_result_fail("%s\n", tests[i].name);
			break;
		}
	}

	ksft_finished();
}
