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");
82 * Wait for an event. If there are no events for 10 seconds,
83 * treat this an error.
85 static int cg_wait_for(int fd
)
94 ret
= poll(&fds
, 1, 10000);
99 debug("Error: poll() failed\n");
103 if (ret
> 0 && fds
.revents
& POLLIN
) {
113 * Attach a task to the given cgroup and wait for a cgroup frozen event.
114 * All transient events (e.g. populated) are ignored.
116 static int cg_enter_and_wait_for_frozen(const char *cgroup
, int pid
,
122 fd
= cg_prepare_for_wait(cgroup
);
126 ret
= cg_enter(cgroup
, pid
);
130 for (attempts
= 0; attempts
< 10; attempts
++) {
131 ret
= cg_wait_for(fd
);
135 ret
= cg_check_frozen(cgroup
, frozen
);
146 * Freeze the given cgroup and wait for the inotify signal.
147 * If there are no events in 10 seconds, treat this as an error.
148 * Then check that the cgroup is in the desired state.
150 static int cg_freeze_wait(const char *cgroup
, bool freeze
)
154 fd
= cg_prepare_for_wait(cgroup
);
158 ret
= cg_freeze_nowait(cgroup
, freeze
);
160 debug("Error: cg_freeze_nowait() failed\n");
164 ret
= cg_wait_for(fd
);
168 ret
= cg_check_frozen(cgroup
, freeze
);
175 * A simple process running in a sleep loop until being
178 static int child_fn(const char *cgroup
, void *arg
)
180 int ppid
= getppid();
182 while (getppid() == ppid
)
185 return getppid() == ppid
;
189 * A simple test for the cgroup freezer: populated the cgroup with 100
190 * running processes and freeze it. Then unfreeze it. Then it kills all
191 * processes and destroys the cgroup.
193 static int test_cgfreezer_simple(const char *root
)
199 cgroup
= cg_name(root
, "cg_test_simple");
203 if (cg_create(cgroup
))
206 for (i
= 0; i
< 100; i
++)
207 cg_run_nowait(cgroup
, child_fn
, NULL
);
209 if (cg_wait_for_proc_count(cgroup
, 100))
212 if (cg_check_frozen(cgroup
, false))
215 if (cg_freeze_wait(cgroup
, true))
218 if (cg_freeze_wait(cgroup
, false))
231 * The test creates the following hierarchy:
242 * with a process in C, H and 3 processes in K.
243 * Then it tries to freeze and unfreeze the whole tree.
245 static int test_cgfreezer_tree(const char *root
)
247 char *cgroup
[10] = {0};
251 cgroup
[0] = cg_name(root
, "cg_test_tree_A");
255 cgroup
[1] = cg_name(cgroup
[0], "B");
259 cgroup
[2] = cg_name(cgroup
[1], "C");
263 cgroup
[3] = cg_name(cgroup
[1], "D");
267 cgroup
[4] = cg_name(cgroup
[0], "E");
271 cgroup
[5] = cg_name(cgroup
[4], "F");
275 cgroup
[6] = cg_name(cgroup
[5], "G");
279 cgroup
[7] = cg_name(cgroup
[6], "H");
283 cgroup
[8] = cg_name(cgroup
[0], "I");
287 cgroup
[9] = cg_name(cgroup
[0], "K");
291 for (i
= 0; i
< 10; i
++)
292 if (cg_create(cgroup
[i
]))
295 cg_run_nowait(cgroup
[2], child_fn
, NULL
);
296 cg_run_nowait(cgroup
[7], child_fn
, NULL
);
297 cg_run_nowait(cgroup
[9], child_fn
, NULL
);
298 cg_run_nowait(cgroup
[9], child_fn
, NULL
);
299 cg_run_nowait(cgroup
[9], child_fn
, NULL
);
302 * Wait until all child processes will enter
303 * corresponding cgroups.
306 if (cg_wait_for_proc_count(cgroup
[2], 1) ||
307 cg_wait_for_proc_count(cgroup
[7], 1) ||
308 cg_wait_for_proc_count(cgroup
[9], 3))
314 if (cg_freeze_wait(cgroup
[1], true))
320 if (cg_freeze_wait(cgroup
[5], true))
326 if (cg_freeze_wait(cgroup
[6], true))
330 * Check that A and E are not frozen.
332 if (cg_check_frozen(cgroup
[0], false))
335 if (cg_check_frozen(cgroup
[4], false))
339 * Freeze A. Check that A, B and E are frozen.
341 if (cg_freeze_wait(cgroup
[0], true))
344 if (cg_check_frozen(cgroup
[1], true))
347 if (cg_check_frozen(cgroup
[4], true))
351 * Unfreeze B, F and G
353 if (cg_freeze_nowait(cgroup
[1], false))
356 if (cg_freeze_nowait(cgroup
[5], false))
359 if (cg_freeze_nowait(cgroup
[6], false))
363 * Check that C and H are still frozen.
365 if (cg_check_frozen(cgroup
[2], true))
368 if (cg_check_frozen(cgroup
[7], true))
372 * Unfreeze A. Check that A, C and K are not frozen.
374 if (cg_freeze_wait(cgroup
[0], false))
377 if (cg_check_frozen(cgroup
[2], false))
380 if (cg_check_frozen(cgroup
[9], false))
386 for (i
= 9; i
>= 0 && cgroup
[i
]; i
--) {
387 cg_destroy(cgroup
[i
]);
395 * A fork bomb emulator.
397 static int forkbomb_fn(const char *cgroup
, void *arg
)
406 while (getppid() == ppid
)
409 return getppid() == ppid
;
413 * The test runs a fork bomb in a cgroup and tries to freeze it.
414 * Then it kills all processes and checks that cgroup isn't populated
417 static int test_cgfreezer_forkbomb(const char *root
)
422 cgroup
= cg_name(root
, "cg_forkbomb_test");
426 if (cg_create(cgroup
))
429 cg_run_nowait(cgroup
, forkbomb_fn
, NULL
);
433 if (cg_freeze_wait(cgroup
, true))
436 if (cg_killall(cgroup
))
439 if (cg_wait_for_proc_count(cgroup
, 0))
452 * The test creates a cgroups and freezes it. Then it creates a child cgroup
453 * and populates it with a task. After that it checks that the child cgroup
454 * is frozen and the parent cgroup remains frozen too.
456 static int test_cgfreezer_mkdir(const char *root
)
459 char *parent
, *child
= NULL
;
462 parent
= cg_name(root
, "cg_test_mkdir_A");
466 child
= cg_name(parent
, "cg_test_mkdir_B");
470 if (cg_create(parent
))
473 if (cg_freeze_wait(parent
, true))
476 if (cg_create(child
))
479 pid
= cg_run_nowait(child
, child_fn
, NULL
);
483 if (cg_wait_for_proc_count(child
, 1))
486 if (cg_check_frozen(child
, true))
489 if (cg_check_frozen(parent
, true))
505 * The test creates two nested cgroups, freezes the parent
506 * and removes the child. Then it checks that the parent cgroup
507 * remains frozen and it's possible to create a new child
508 * without unfreezing. The new child is frozen too.
510 static int test_cgfreezer_rmdir(const char *root
)
513 char *parent
, *child
= NULL
;
515 parent
= cg_name(root
, "cg_test_rmdir_A");
519 child
= cg_name(parent
, "cg_test_rmdir_B");
523 if (cg_create(parent
))
526 if (cg_create(child
))
529 if (cg_freeze_wait(parent
, true))
532 if (cg_destroy(child
))
535 if (cg_check_frozen(parent
, true))
538 if (cg_create(child
))
541 if (cg_check_frozen(child
, true))
557 * The test creates two cgroups: A and B, runs a process in A
558 * and performs several migrations:
559 * 1) A (running) -> B (frozen)
560 * 2) B (frozen) -> A (running)
561 * 3) A (frozen) -> B (frozen)
563 * On each step it checks the actual state of both cgroups.
565 static int test_cgfreezer_migrate(const char *root
)
568 char *cgroup
[2] = {0};
571 cgroup
[0] = cg_name(root
, "cg_test_migrate_A");
575 cgroup
[1] = cg_name(root
, "cg_test_migrate_B");
579 if (cg_create(cgroup
[0]))
582 if (cg_create(cgroup
[1]))
585 pid
= cg_run_nowait(cgroup
[0], child_fn
, NULL
);
589 if (cg_wait_for_proc_count(cgroup
[0], 1))
593 * Migrate from A (running) to B (frozen)
595 if (cg_freeze_wait(cgroup
[1], true))
598 if (cg_enter_and_wait_for_frozen(cgroup
[1], pid
, true))
601 if (cg_check_frozen(cgroup
[0], false))
605 * Migrate from B (frozen) to A (running)
607 if (cg_enter_and_wait_for_frozen(cgroup
[0], pid
, false))
610 if (cg_check_frozen(cgroup
[1], true))
614 * Migrate from A (frozen) to B (frozen)
616 if (cg_freeze_wait(cgroup
[0], true))
619 if (cg_enter_and_wait_for_frozen(cgroup
[1], pid
, true))
622 if (cg_check_frozen(cgroup
[0], true))
629 cg_destroy(cgroup
[0]);
632 cg_destroy(cgroup
[1]);
638 * The test checks that ptrace works with a tracing process in a frozen cgroup.
640 static int test_cgfreezer_ptrace(const char *root
)
647 cgroup
= cg_name(root
, "cg_test_ptrace");
651 if (cg_create(cgroup
))
654 pid
= cg_run_nowait(cgroup
, child_fn
, NULL
);
658 if (cg_wait_for_proc_count(cgroup
, 1))
661 if (cg_freeze_wait(cgroup
, true))
664 if (ptrace(PTRACE_SEIZE
, pid
, NULL
, NULL
))
667 if (ptrace(PTRACE_INTERRUPT
, pid
, NULL
, NULL
))
670 waitpid(pid
, NULL
, 0);
673 * Cgroup has to remain frozen, however the test task
674 * is in traced state.
676 if (cg_check_frozen(cgroup
, true))
679 if (ptrace(PTRACE_GETSIGINFO
, pid
, NULL
, &siginfo
))
682 if (ptrace(PTRACE_DETACH
, pid
, NULL
, NULL
))
685 if (cg_check_frozen(cgroup
, true))
698 * Check if the process is stopped.
700 static int proc_check_stopped(int pid
)
705 len
= proc_read_text(pid
, 0, "stat", buf
, sizeof(buf
));
707 debug("Can't get %d stat\n", pid
);
711 if (strstr(buf
, "(test_freezer) T ") == NULL
) {
712 debug("Process %d in the unexpected state: %s\n", pid
, buf
);
720 * Test that it's possible to freeze a cgroup with a stopped process.
722 static int test_cgfreezer_stopped(const char *root
)
724 int pid
, ret
= KSFT_FAIL
;
727 cgroup
= cg_name(root
, "cg_test_stopped");
731 if (cg_create(cgroup
))
734 pid
= cg_run_nowait(cgroup
, child_fn
, NULL
);
736 if (cg_wait_for_proc_count(cgroup
, 1))
739 if (kill(pid
, SIGSTOP
))
742 if (cg_check_frozen(cgroup
, false))
745 if (cg_freeze_wait(cgroup
, true))
748 if (cg_freeze_wait(cgroup
, false))
751 if (proc_check_stopped(pid
))
764 * Test that it's possible to freeze a cgroup with a ptraced process.
766 static int test_cgfreezer_ptraced(const char *root
)
768 int pid
, ret
= KSFT_FAIL
;
772 cgroup
= cg_name(root
, "cg_test_ptraced");
776 if (cg_create(cgroup
))
779 pid
= cg_run_nowait(cgroup
, child_fn
, NULL
);
781 if (cg_wait_for_proc_count(cgroup
, 1))
784 if (ptrace(PTRACE_SEIZE
, pid
, NULL
, NULL
))
787 if (ptrace(PTRACE_INTERRUPT
, pid
, NULL
, NULL
))
790 waitpid(pid
, NULL
, 0);
792 if (cg_check_frozen(cgroup
, false))
795 if (cg_freeze_wait(cgroup
, true))
799 * cg_check_frozen(cgroup, true) will fail here,
800 * because the task in in the TRACEd state.
802 if (cg_freeze_wait(cgroup
, false))
805 if (ptrace(PTRACE_GETSIGINFO
, pid
, NULL
, &siginfo
))
808 if (ptrace(PTRACE_DETACH
, pid
, NULL
, NULL
))
820 static int vfork_fn(const char *cgroup
, void *arg
)
832 * Test that it's possible to freeze a cgroup with a process,
833 * which called vfork() and is waiting for a child.
835 static int test_cgfreezer_vfork(const char *root
)
840 cgroup
= cg_name(root
, "cg_test_vfork");
844 if (cg_create(cgroup
))
847 cg_run_nowait(cgroup
, vfork_fn
, NULL
);
849 if (cg_wait_for_proc_count(cgroup
, 2))
852 if (cg_freeze_wait(cgroup
, true))
864 #define T(x) { x, #x }
865 struct cgfreezer_test
{
866 int (*fn
)(const char *root
);
869 T(test_cgfreezer_simple
),
870 T(test_cgfreezer_tree
),
871 T(test_cgfreezer_forkbomb
),
872 T(test_cgfreezer_mkdir
),
873 T(test_cgfreezer_rmdir
),
874 T(test_cgfreezer_migrate
),
875 T(test_cgfreezer_ptrace
),
876 T(test_cgfreezer_stopped
),
877 T(test_cgfreezer_ptraced
),
878 T(test_cgfreezer_vfork
),
882 int main(int argc
, char *argv
[])
885 int i
, ret
= EXIT_SUCCESS
;
887 if (cg_find_unified_root(root
, sizeof(root
)))
888 ksft_exit_skip("cgroup v2 isn't mounted\n");
889 for (i
= 0; i
< ARRAY_SIZE(tests
); i
++) {
890 switch (tests
[i
].fn(root
)) {
892 ksft_test_result_pass("%s\n", tests
[i
].name
);
895 ksft_test_result_skip("%s\n", tests
[i
].name
);
899 ksft_test_result_fail("%s\n", tests
[i
].name
);