1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* Copyright (c) 2021 SUSE LLC */
3
4 #include <stdlib.h>
5 #include <stdio.h>
6
7 #include "tst_test.h"
8
9 static char *only_mount_v1;
10 static char *no_cleanup;
11 static struct tst_option opts[] = {
12 {"v", &only_mount_v1, "-v\tOnly try to mount CGroups V1"},
13 {"n", &no_cleanup, "-n\tLeave CGroups created by test"},
14 {NULL, NULL, NULL},
15 };
16 static struct tst_cg_opts cgopts;
17 static struct tst_cg_group *cg_child;
18
do_test(void)19 static void do_test(void)
20 {
21 char buf[BUFSIZ];
22 size_t mem;
23
24 if (!TST_CG_VER_IS_V1(tst_cg, "memory"))
25 SAFE_CG_PRINT(tst_cg, "cgroup.subtree_control", "+memory");
26 if (!TST_CG_VER_IS_V1(tst_cg, "cpuset"))
27 SAFE_CG_PRINT(tst_cg, "cgroup.subtree_control", "+cpuset");
28
29 cg_child = tst_cg_group_mk(tst_cg, "child");
30 if (!SAFE_FORK()) {
31 SAFE_CG_PRINTF(cg_child, "cgroup.procs", "%d", getpid());
32
33 SAFE_CG_SCANF(cg_child, "memory.current", "%zu", &mem);
34 tst_res(TPASS, "child/memory.current = %zu", mem);
35 SAFE_CG_PRINTF(cg_child, "memory.max",
36 "%zu", (1UL << 24) - 1);
37 SAFE_CG_PRINTF(cg_child, "memory.swap.max",
38 "%zu", 1UL << 31);
39
40 SAFE_CG_READ(cg_child, "cpuset.mems", buf, sizeof(buf));
41 tst_res(TPASS, "child/cpuset.mems = %s", buf);
42 SAFE_CG_PRINT(cg_child, "cpuset.mems", buf);
43
44 exit(0);
45 }
46
47 SAFE_CG_PRINTF(tst_cg, "memory.max", "%zu", (1UL << 24) - 1);
48 SAFE_CG_PRINTF(cg_child, "cgroup.procs", "%d", getpid());
49 SAFE_CG_SCANF(tst_cg, "memory.current", "%zu", &mem);
50 tst_res(TPASS, "memory.current = %zu", mem);
51
52 tst_reap_children();
53 SAFE_CG_PRINTF(tst_cg_drain, "cgroup.procs", "%d", getpid());
54 cg_child = tst_cg_group_rm(cg_child);
55 }
56
setup(void)57 static void setup(void)
58 {
59 cgopts.needs_ver = !!only_mount_v1 ? TST_CG_V1 : 0;
60
61 tst_cg_scan();
62 tst_cg_print_config();
63
64 tst_cg_require("memory", &cgopts);
65 tst_cg_require("cpuset", &cgopts);
66
67 tst_cg_init();
68 }
69
cleanup(void)70 static void cleanup(void)
71 {
72 if (cg_child) {
73 SAFE_CG_PRINTF(tst_cg_drain,
74 "cgroup.procs", "%d", getpid());
75 cg_child = tst_cg_group_rm(cg_child);
76 }
77 if (!no_cleanup)
78 tst_cg_cleanup();
79 }
80
81 static struct tst_test test = {
82 .test_all = do_test,
83 .setup = setup,
84 .cleanup = cleanup,
85 .options = opts,
86 .forks_child = 1,
87 };
88