brintos

brintos / linux-shallow public Read only

0
0
Text · 3.5 KiB · 9ecb83c Raw
179 lines · c
1// SPDX-License-Identifier: GPL-2.02#define _GNU_SOURCE3 4#include <errno.h>5#include <linux/limits.h>6#include <signal.h>7#include <string.h>8#include <sys/stat.h>9#include <sys/types.h>10#include <unistd.h>11 12#include "../kselftest.h"13#include "cgroup_util.h"14 15static int run_success(const char *cgroup, void *arg)16{17	return 0;18}19 20static int run_pause(const char *cgroup, void *arg)21{22	return pause();23}24 25/*26 * This test checks that pids.max prevents forking new children above the27 * specified limit in the cgroup.28 */29static int test_pids_max(const char *root)30{31	int ret = KSFT_FAIL;32	char *cg_pids;33	int pid;34 35	cg_pids = cg_name(root, "pids_test");36	if (!cg_pids)37		goto cleanup;38 39	if (cg_create(cg_pids))40		goto cleanup;41 42	if (cg_read_strcmp(cg_pids, "pids.max", "max\n"))43		goto cleanup;44 45	if (cg_write(cg_pids, "pids.max", "2"))46		goto cleanup;47 48	if (cg_enter_current(cg_pids))49		goto cleanup;50 51	pid = cg_run_nowait(cg_pids, run_pause, NULL);52	if (pid < 0)53		goto cleanup;54 55	if (cg_run_nowait(cg_pids, run_success, NULL) != -1 || errno != EAGAIN)56		goto cleanup;57 58	if (kill(pid, SIGINT))59		goto cleanup;60 61	ret = KSFT_PASS;62 63cleanup:64	cg_enter_current(root);65	cg_destroy(cg_pids);66	free(cg_pids);67 68	return ret;69}70 71/*72 * This test checks that pids.events are counted in cgroup associated with pids.max73 */74static int test_pids_events(const char *root)75{76	int ret = KSFT_FAIL;77	char *cg_parent = NULL, *cg_child = NULL;78	int pid;79 80	cg_parent = cg_name(root, "pids_parent");81	cg_child = cg_name(cg_parent, "pids_child");82	if (!cg_parent || !cg_child)83		goto cleanup;84 85	if (cg_create(cg_parent))86		goto cleanup;87	if (cg_write(cg_parent, "cgroup.subtree_control", "+pids"))88		goto cleanup;89	if (cg_create(cg_child))90		goto cleanup;91 92	if (cg_write(cg_parent, "pids.max", "2"))93		goto cleanup;94 95	if (cg_read_strcmp(cg_child, "pids.max", "max\n"))96		goto cleanup;97 98	if (cg_enter_current(cg_child))99		goto cleanup;100 101	pid = cg_run_nowait(cg_child, run_pause, NULL);102	if (pid < 0)103		goto cleanup;104 105	if (cg_run_nowait(cg_child, run_success, NULL) != -1 || errno != EAGAIN)106		goto cleanup;107 108	if (kill(pid, SIGINT))109		goto cleanup;110 111	if (cg_read_key_long(cg_child, "pids.events", "max ") != 0)112		goto cleanup;113	if (cg_read_key_long(cg_parent, "pids.events", "max ") != 1)114		goto cleanup;115 116 117	ret = KSFT_PASS;118 119cleanup:120	cg_enter_current(root);121	if (cg_child)122		cg_destroy(cg_child);123	if (cg_parent)124		cg_destroy(cg_parent);125	free(cg_child);126	free(cg_parent);127 128	return ret;129}130 131 132 133#define T(x) { x, #x }134struct pids_test {135	int (*fn)(const char *root);136	const char *name;137} tests[] = {138	T(test_pids_max),139	T(test_pids_events),140};141#undef T142 143int main(int argc, char **argv)144{145	char root[PATH_MAX];146 147	ksft_print_header();148	ksft_set_plan(ARRAY_SIZE(tests));149	if (cg_find_unified_root(root, sizeof(root), NULL))150		ksft_exit_skip("cgroup v2 isn't mounted\n");151 152	/*153	 * Check that pids controller is available:154	 * pids is listed in cgroup.controllers155	 */156	if (cg_read_strstr(root, "cgroup.controllers", "pids"))157		ksft_exit_skip("pids controller isn't available\n");158 159	if (cg_read_strstr(root, "cgroup.subtree_control", "pids"))160		if (cg_write(root, "cgroup.subtree_control", "+pids"))161			ksft_exit_skip("Failed to set pids controller\n");162 163	for (int i = 0; i < ARRAY_SIZE(tests); i++) {164		switch (tests[i].fn(root)) {165		case KSFT_PASS:166			ksft_test_result_pass("%s\n", tests[i].name);167			break;168		case KSFT_SKIP:169			ksft_test_result_skip("%s\n", tests[i].name);170			break;171		default:172			ksft_test_result_fail("%s\n", tests[i].name);173			break;174		}175	}176 177	ksft_finished();178}179