1 /* SPDX-License-Identifier: GPL-2.0 */
3 #include <linux/limits.h>
4 #include <sys/ptrace.h>
12 #include <sys/inotify.h>
16 #include "../kselftest.h"
17 #include "cgroup_util.h"
21 #define debug(args...) fprintf(stderr, args)
23 #define debug(args...)
27 * Check if the cgroup is frozen by looking at the cgroup.events::frozen value.
29 static int cg_check_frozen(const char *cgroup
, bool frozen
)
32 if (cg_read_strstr(cgroup
, "cgroup.events", "frozen 1") != 0) {
33 debug("Cgroup %s isn't frozen\n", cgroup
);
38 * Check the cgroup.events::frozen value.
40 if (cg_read_strstr(cgroup
, "cgroup.events", "frozen 0") != 0) {
41 debug("Cgroup %s is frozen\n", cgroup
);
50 * Freeze the given cgroup.
52 static int cg_freeze_nowait(const char *cgroup
, bool freeze
)
54 return cg_write(cgroup
, "cgroup.freeze", freeze
? "1" : "0");
58 * Prepare for waiting on cgroup.events file.
60 static int cg_prepare_for_wait(const char *cgroup
)
64 fd
= inotify_init1(0);
66 debug("Error: inotify_init1() failed\n");
70 ret
= inotify_add_watch(fd
, cg_control(cgroup
, "cgroup.events"),
73 debug("Error: inotify_add_watch() failed\n");
81 * Wait for an event. If there are no events for 10 seconds,
82 * treat this an error.
84 static int cg_wait_for(int fd
)
93 ret
= poll(&fds
, 1, 10000);
98 debug("Error: poll() failed\n");
102 if (ret
> 0 && fds
.revents
& POLLIN
) {
112 * Attach a task to the given cgroup and wait for a cgroup frozen event.
113 * All transient events (e.g. populated) are ignored.
115 static int cg_enter_and_wait_for_frozen(const char *cgroup
, int pid
,
121 fd
= cg_prepare_for_wait(cgroup
);
125 ret
= cg_enter(cgroup
, pid
);
129 for (attempts
= 0; attempts
< 10; attempts
++) {
130 ret
= cg_wait_for(fd
);
134 ret
= cg_check_frozen(cgroup
, frozen
);
145 * Freeze the given cgroup and wait for the inotify signal.
146 * If there are no events in 10 seconds, treat this as an error.
147 * Then check that the cgroup is in the desired state.
149 static int cg_freeze_wait(const char *cgroup
, bool freeze
)
153 fd
= cg_prepare_for_wait(cgroup
);
157 ret
= cg_freeze_nowait(cgroup
, freeze
);
159 debug("Error: cg_freeze_nowait() failed\n");
163 ret
= cg_wait_for(fd
);
167 ret
= cg_check_frozen(cgroup
, freeze
);
174 * A simple process running in a sleep loop until being
177 static int child_fn(const char *cgroup
, void *arg
)
179 int ppid
= getppid();
181 while (getppid() == ppid
)
184 return getppid() == ppid
;
188 * A simple test for the cgroup freezer: populated the cgroup with 100
189 * running processes and freeze it. Then unfreeze it. Then it kills all
190 * processes and destroys the cgroup.
192 static int test_cgfreezer_simple(const char *root
)
198 cgroup
= cg_name(root
, "cg_test_simple");
202 if (cg_create(cgroup
))
205 for (i
= 0; i
< 100; i
++)
206 cg_run_nowait(cgroup
, child_fn
, NULL
);
208 if (cg_wait_for_proc_count(cgroup
, 100))
211 if (cg_check_frozen(cgroup
, false))
214 if (cg_freeze_wait(cgroup
, true))
217 if (cg_freeze_wait(cgroup
, false))
230 * The test creates the following hierarchy:
241 * with a process in C, H and 3 processes in K.
242 * Then it tries to freeze and unfreeze the whole tree.
244 static int test_cgfreezer_tree(const char *root
)
246 char *cgroup
[10] = {0};
250 cgroup
[0] = cg_name(root
, "cg_test_tree_A");
254 cgroup
[1] = cg_name(cgroup
[0], "B");
258 cgroup
[2] = cg_name(cgroup
[1], "C");
262 cgroup
[3] = cg_name(cgroup
[1], "D");
266 cgroup
[4] = cg_name(cgroup
[0], "E");
270 cgroup
[5] = cg_name(cgroup
[4], "F");
274 cgroup
[6] = cg_name(cgroup
[5], "G");
278 cgroup
[7] = cg_name(cgroup
[6], "H");
282 cgroup
[8] = cg_name(cgroup
[0], "I");
286 cgroup
[9] = cg_name(cgroup
[0], "K");
290 for (i
= 0; i
< 10; i
++)
291 if (cg_create(cgroup
[i
]))
294 cg_run_nowait(cgroup
[2], child_fn
, NULL
);
295 cg_run_nowait(cgroup
[7], child_fn
, NULL
);
296 cg_run_nowait(cgroup
[9], child_fn
, NULL
);
297 cg_run_nowait(cgroup
[9], child_fn
, NULL
);
298 cg_run_nowait(cgroup
[9], child_fn
, NULL
);
301 * Wait until all child processes will enter
302 * corresponding cgroups.
305 if (cg_wait_for_proc_count(cgroup
[2], 1) ||
306 cg_wait_for_proc_count(cgroup
[7], 1) ||
307 cg_wait_for_proc_count(cgroup
[9], 3))
313 if (cg_freeze_wait(cgroup
[1], true))
319 if (cg_freeze_wait(cgroup
[5], true))
325 if (cg_freeze_wait(cgroup
[6], true))
329 * Check that A and E are not frozen.
331 if (cg_check_frozen(cgroup
[0], false))
334 if (cg_check_frozen(cgroup
[4], false))
338 * Freeze A. Check that A, B and E are frozen.
340 if (cg_freeze_wait(cgroup
[0], true))
343 if (cg_check_frozen(cgroup
[1], true))
346 if (cg_check_frozen(cgroup
[4], true))
350 * Unfreeze B, F and G
352 if (cg_freeze_nowait(cgroup
[1], false))
355 if (cg_freeze_nowait(cgroup
[5], false))
358 if (cg_freeze_nowait(cgroup
[6], false))
362 * Check that C and H are still frozen.
364 if (cg_check_frozen(cgroup
[2], true))
367 if (cg_check_frozen(cgroup
[7], true))
371 * Unfreeze A. Check that A, C and K are not frozen.
373 if (cg_freeze_wait(cgroup
[0], false))
376 if (cg_check_frozen(cgroup
[2], false))
379 if (cg_check_frozen(cgroup
[9], false))
385 for (i
= 9; i
>= 0 && cgroup
[i
]; i
--) {
386 cg_destroy(cgroup
[i
]);
394 * A fork bomb emulator.
396 static int forkbomb_fn(const char *cgroup
, void *arg
)
405 while (getppid() == ppid
)
408 return getppid() == ppid
;
412 * The test runs a fork bomb in a cgroup and tries to freeze it.
413 * Then it kills all processes and checks that cgroup isn't populated
416 static int test_cgfreezer_forkbomb(const char *root
)
421 cgroup
= cg_name(root
, "cg_forkbomb_test");
425 if (cg_create(cgroup
))
428 cg_run_nowait(cgroup
, forkbomb_fn
, NULL
);
432 if (cg_freeze_wait(cgroup
, true))
435 if (cg_killall(cgroup
))
438 if (cg_wait_for_proc_count(cgroup
, 0))
451 * The test creates two nested cgroups, freezes the parent
452 * and removes the child. Then it checks that the parent cgroup
453 * remains frozen and it's possible to create a new child
454 * without unfreezing. The new child is frozen too.
456 static int test_cgfreezer_rmdir(const char *root
)
459 char *parent
, *child
= NULL
;
461 parent
= cg_name(root
, "cg_test_rmdir_A");
465 child
= cg_name(parent
, "cg_test_rmdir_B");
469 if (cg_create(parent
))
472 if (cg_create(child
))
475 if (cg_freeze_wait(parent
, true))
478 if (cg_destroy(child
))
481 if (cg_check_frozen(parent
, true))
484 if (cg_create(child
))
487 if (cg_check_frozen(child
, true))
503 * The test creates two cgroups: A and B, runs a process in A
504 * and performs several migrations:
505 * 1) A (running) -> B (frozen)
506 * 2) B (frozen) -> A (running)
507 * 3) A (frozen) -> B (frozen)
509 * On each step it checks the actual state of both cgroups.
511 static int test_cgfreezer_migrate(const char *root
)
514 char *cgroup
[2] = {0};
517 cgroup
[0] = cg_name(root
, "cg_test_migrate_A");
521 cgroup
[1] = cg_name(root
, "cg_test_migrate_B");
525 if (cg_create(cgroup
[0]))
528 if (cg_create(cgroup
[1]))
531 pid
= cg_run_nowait(cgroup
[0], child_fn
, NULL
);
535 if (cg_wait_for_proc_count(cgroup
[0], 1))
539 * Migrate from A (running) to B (frozen)
541 if (cg_freeze_wait(cgroup
[1], true))
544 if (cg_enter_and_wait_for_frozen(cgroup
[1], pid
, true))
547 if (cg_check_frozen(cgroup
[0], false))
551 * Migrate from B (frozen) to A (running)
553 if (cg_enter_and_wait_for_frozen(cgroup
[0], pid
, false))
556 if (cg_check_frozen(cgroup
[1], true))
560 * Migrate from A (frozen) to B (frozen)
562 if (cg_freeze_wait(cgroup
[0], true))
565 if (cg_enter_and_wait_for_frozen(cgroup
[1], pid
, true))
568 if (cg_check_frozen(cgroup
[0], true))
575 cg_destroy(cgroup
[0]);
578 cg_destroy(cgroup
[1]);
584 * The test checks that ptrace works with a tracing process in a frozen cgroup.
586 static int test_cgfreezer_ptrace(const char *root
)
593 cgroup
= cg_name(root
, "cg_test_ptrace");
597 if (cg_create(cgroup
))
600 pid
= cg_run_nowait(cgroup
, child_fn
, NULL
);
604 if (cg_wait_for_proc_count(cgroup
, 1))
607 if (cg_freeze_wait(cgroup
, true))
610 if (ptrace(PTRACE_SEIZE
, pid
, NULL
, NULL
))
613 if (ptrace(PTRACE_INTERRUPT
, pid
, NULL
, NULL
))
616 waitpid(pid
, NULL
, 0);
619 * Cgroup has to remain frozen, however the test task
620 * is in traced state.
622 if (cg_check_frozen(cgroup
, true))
625 if (ptrace(PTRACE_GETSIGINFO
, pid
, NULL
, &siginfo
))
628 if (ptrace(PTRACE_DETACH
, pid
, NULL
, NULL
))
631 if (cg_check_frozen(cgroup
, true))
644 * Check if the process is stopped.
646 static int proc_check_stopped(int pid
)
651 len
= proc_read_text(pid
, "stat", buf
, sizeof(buf
));
653 debug("Can't get %d stat\n", pid
);
657 if (strstr(buf
, "(test_freezer) T ") == NULL
) {
658 debug("Process %d in the unexpected state: %s\n", pid
, buf
);
666 * Test that it's possible to freeze a cgroup with a stopped process.
668 static int test_cgfreezer_stopped(const char *root
)
670 int pid
, ret
= KSFT_FAIL
;
673 cgroup
= cg_name(root
, "cg_test_stopped");
677 if (cg_create(cgroup
))
680 pid
= cg_run_nowait(cgroup
, child_fn
, NULL
);
682 if (cg_wait_for_proc_count(cgroup
, 1))
685 if (kill(pid
, SIGSTOP
))
688 if (cg_check_frozen(cgroup
, false))
691 if (cg_freeze_wait(cgroup
, true))
694 if (cg_freeze_wait(cgroup
, false))
697 if (proc_check_stopped(pid
))
710 * Test that it's possible to freeze a cgroup with a ptraced process.
712 static int test_cgfreezer_ptraced(const char *root
)
714 int pid
, ret
= KSFT_FAIL
;
718 cgroup
= cg_name(root
, "cg_test_ptraced");
722 if (cg_create(cgroup
))
725 pid
= cg_run_nowait(cgroup
, child_fn
, NULL
);
727 if (cg_wait_for_proc_count(cgroup
, 1))
730 if (ptrace(PTRACE_SEIZE
, pid
, NULL
, NULL
))
733 if (ptrace(PTRACE_INTERRUPT
, pid
, NULL
, NULL
))
736 waitpid(pid
, NULL
, 0);
738 if (cg_check_frozen(cgroup
, false))
741 if (cg_freeze_wait(cgroup
, true))
745 * cg_check_frozen(cgroup, true) will fail here,
746 * because the task in in the TRACEd state.
748 if (cg_freeze_wait(cgroup
, false))
751 if (ptrace(PTRACE_GETSIGINFO
, pid
, NULL
, &siginfo
))
754 if (ptrace(PTRACE_DETACH
, pid
, NULL
, NULL
))
766 static int vfork_fn(const char *cgroup
, void *arg
)
778 * Test that it's possible to freeze a cgroup with a process,
779 * which called vfork() and is waiting for a child.
781 static int test_cgfreezer_vfork(const char *root
)
786 cgroup
= cg_name(root
, "cg_test_vfork");
790 if (cg_create(cgroup
))
793 cg_run_nowait(cgroup
, vfork_fn
, NULL
);
795 if (cg_wait_for_proc_count(cgroup
, 2))
798 if (cg_freeze_wait(cgroup
, true))
810 #define T(x) { x, #x }
811 struct cgfreezer_test
{
812 int (*fn
)(const char *root
);
815 T(test_cgfreezer_simple
),
816 T(test_cgfreezer_tree
),
817 T(test_cgfreezer_forkbomb
),
818 T(test_cgfreezer_rmdir
),
819 T(test_cgfreezer_migrate
),
820 T(test_cgfreezer_ptrace
),
821 T(test_cgfreezer_stopped
),
822 T(test_cgfreezer_ptraced
),
823 T(test_cgfreezer_vfork
),
827 int main(int argc
, char *argv
[])
830 int i
, ret
= EXIT_SUCCESS
;
832 if (cg_find_unified_root(root
, sizeof(root
)))
833 ksft_exit_skip("cgroup v2 isn't mounted\n");
834 for (i
= 0; i
< ARRAY_SIZE(tests
); i
++) {
835 switch (tests
[i
].fn(root
)) {
837 ksft_test_result_pass("%s\n", tests
[i
].name
);
840 ksft_test_result_skip("%s\n", tests
[i
].name
);
844 ksft_test_result_fail("%s\n", tests
[i
].name
);