1 /* SPDX-License-Identifier: GPL-2.0 */
4 #include <linux/limits.h>
12 #include "../kselftest.h"
13 #include "../pidfd/pidfd.h"
14 #include "cgroup_util.h"
17 * Kill the given cgroup and wait for the inotify signal.
18 * If there are no events in 10 seconds, treat this as an error.
19 * Then check that the cgroup is in the desired state.
21 static int cg_kill_wait(const char *cgroup
)
25 fd
= cg_prepare_for_wait(cgroup
);
29 ret
= cg_write(cgroup
, "cgroup.kill", "1");
33 ret
= cg_wait_for(fd
);
43 * A simple process running in a sleep loop until being
46 static int child_fn(const char *cgroup
, void *arg
)
50 while (getppid() == ppid
)
53 return getppid() == ppid
;
56 static int test_cgkill_simple(const char *root
)
63 cgroup
= cg_name(root
, "cg_test_simple");
67 if (cg_create(cgroup
))
70 for (i
= 0; i
< 100; i
++)
71 pids
[i
] = cg_run_nowait(cgroup
, child_fn
, NULL
);
73 if (cg_wait_for_proc_count(cgroup
, 100))
76 if (cg_read_strcmp(cgroup
, "cgroup.events", "populated 1\n"))
79 if (cg_kill_wait(cgroup
))
85 for (i
= 0; i
< 100; i
++)
86 wait_for_pid(pids
[i
]);
88 if (ret
== KSFT_PASS
&&
89 cg_read_strcmp(cgroup
, "cgroup.events", "populated 0\n"))
99 * The test creates the following hierarchy:
110 * with a process in C, H and 3 processes in K.
111 * Then it tries to kill the whole tree.
113 static int test_cgkill_tree(const char *root
)
116 char *cgroup
[10] = {0};
120 cgroup
[0] = cg_name(root
, "cg_test_tree_A");
124 cgroup
[1] = cg_name(cgroup
[0], "B");
128 cgroup
[2] = cg_name(cgroup
[1], "C");
132 cgroup
[3] = cg_name(cgroup
[1], "D");
136 cgroup
[4] = cg_name(cgroup
[0], "E");
140 cgroup
[5] = cg_name(cgroup
[4], "F");
144 cgroup
[6] = cg_name(cgroup
[5], "G");
148 cgroup
[7] = cg_name(cgroup
[6], "H");
152 cgroup
[8] = cg_name(cgroup
[0], "I");
156 cgroup
[9] = cg_name(cgroup
[0], "K");
160 for (i
= 0; i
< 10; i
++)
161 if (cg_create(cgroup
[i
]))
164 pids
[0] = cg_run_nowait(cgroup
[2], child_fn
, NULL
);
165 pids
[1] = cg_run_nowait(cgroup
[7], child_fn
, NULL
);
166 pids
[2] = cg_run_nowait(cgroup
[9], child_fn
, NULL
);
167 pids
[3] = cg_run_nowait(cgroup
[9], child_fn
, NULL
);
168 pids
[4] = cg_run_nowait(cgroup
[9], child_fn
, NULL
);
171 * Wait until all child processes will enter
172 * corresponding cgroups.
175 if (cg_wait_for_proc_count(cgroup
[2], 1) ||
176 cg_wait_for_proc_count(cgroup
[7], 1) ||
177 cg_wait_for_proc_count(cgroup
[9], 3))
181 * Kill A and check that we get an empty notification.
183 if (cg_kill_wait(cgroup
[0]))
189 for (i
= 0; i
< 5; i
++)
190 wait_for_pid(pids
[i
]);
192 if (ret
== KSFT_PASS
&&
193 cg_read_strcmp(cgroup
[0], "cgroup.events", "populated 0\n"))
196 for (i
= 9; i
>= 0 && cgroup
[i
]; i
--) {
197 cg_destroy(cgroup
[i
]);
204 static int forkbomb_fn(const char *cgroup
, void *arg
)
213 while (getppid() == ppid
)
216 return getppid() == ppid
;
220 * The test runs a fork bomb in a cgroup and tries to kill it.
222 static int test_cgkill_forkbomb(const char *root
)
228 cgroup
= cg_name(root
, "cg_forkbomb_test");
232 if (cg_create(cgroup
))
235 pid
= cg_run_nowait(cgroup
, forkbomb_fn
, NULL
);
241 if (cg_kill_wait(cgroup
))
244 if (cg_wait_for_proc_count(cgroup
, 0))
253 if (ret
== KSFT_PASS
&&
254 cg_read_strcmp(cgroup
, "cgroup.events", "populated 0\n"))
263 #define T(x) { x, #x }
265 int (*fn
)(const char *root
);
268 T(test_cgkill_simple
),
270 T(test_cgkill_forkbomb
),
274 int main(int argc
, char *argv
[])
277 int i
, ret
= EXIT_SUCCESS
;
279 if (cg_find_unified_root(root
, sizeof(root
), NULL
))
280 ksft_exit_skip("cgroup v2 isn't mounted\n");
281 for (i
= 0; i
< ARRAY_SIZE(tests
); i
++) {
282 switch (tests
[i
].fn(root
)) {
284 ksft_test_result_pass("%s\n", tests
[i
].name
);
287 ksft_test_result_skip("%s\n", tests
[i
].name
);
291 ksft_test_result_fail("%s\n", tests
[i
].name
);