1 // SPDX-License-Identifier: GPL-2.0
5 #include <linux/limits.h>
12 #include "../kselftest.h"
13 #include "cgroup_util.h"
15 static int run_success(const char *cgroup, void *arg)
20 static int run_pause(const char *cgroup, void *arg)
26 * This test checks that pids.max prevents forking new children above the
27 * specified limit in the cgroup.
29 static int test_pids_max(const char *root)
35 cg_pids = cg_name(root, "pids_test");
39 if (cg_create(cg_pids))
42 if (cg_read_strcmp(cg_pids, "pids.max", "max\n"))
45 if (cg_write(cg_pids, "pids.max", "2"))
48 if (cg_enter_current(cg_pids))
51 pid = cg_run_nowait(cg_pids, run_pause, NULL);
55 if (cg_run_nowait(cg_pids, run_success, NULL) != -1 || errno != EAGAIN)
58 if (kill(pid, SIGINT))
64 cg_enter_current(root);
72 * This test checks that pids.events are counted in cgroup associated with pids.max
74 static int test_pids_events(const char *root)
77 char *cg_parent = NULL, *cg_child = NULL;
80 cg_parent = cg_name(root, "pids_parent");
81 cg_child = cg_name(cg_parent, "pids_child");
82 if (!cg_parent || !cg_child)
85 if (cg_create(cg_parent))
87 if (cg_write(cg_parent, "cgroup.subtree_control", "+pids"))
89 if (cg_create(cg_child))
92 if (cg_write(cg_parent, "pids.max", "2"))
95 if (cg_read_strcmp(cg_child, "pids.max", "max\n"))
98 if (cg_enter_current(cg_child))
101 pid = cg_run_nowait(cg_child, run_pause, NULL);
105 if (cg_run_nowait(cg_child, run_success, NULL) != -1 || errno != EAGAIN)
108 if (kill(pid, SIGINT))
111 if (cg_read_key_long(cg_child, "pids.events", "max ") != 0)
113 if (cg_read_key_long(cg_parent, "pids.events", "max ") != 1)
120 cg_enter_current(root);
122 cg_destroy(cg_child);
124 cg_destroy(cg_parent);
133 #define T(x) { x, #x }
135 int (*fn)(const char *root);
143 int main(int argc, char **argv)
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");
153 * Check that pids controller is available:
154 * pids is listed in cgroup.controllers
156 if (cg_read_strstr(root, "cgroup.controllers", "pids"))
157 ksft_exit_skip("pids controller isn't available\n");
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");
163 for (int i = 0; i < ARRAY_SIZE(tests); i++) {
164 switch (tests[i].fn(root)) {
166 ksft_test_result_pass("%s\n", tests[i].name);
169 ksft_test_result_skip("%s\n", tests[i].name);
172 ksft_test_result_fail("%s\n", tests[i].name);