• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "tst_cgroup.h"
9 
10 static char *only_mount_v1;
11 static char *no_cleanup;
12 static struct tst_option opts[] = {
13 	{"v", &only_mount_v1, "-v\tOnly try to mount CGroups V1"},
14 	{"n", &no_cleanup, "-n\tLeave CGroups created by test"},
15 	{NULL, NULL, NULL},
16 };
17 static struct tst_cgroup_opts cgopts;
18 static const struct tst_cgroup_group *cg;
19 static const struct tst_cgroup_group *cg_drain;
20 static struct tst_cgroup_group *cg_child;
21 
do_test(void)22 static void do_test(void)
23 {
24 	char buf[BUFSIZ];
25 	size_t mem;
26 
27 	if (!TST_CGROUP_VER_IS_V1(cg, "memory"))
28 		SAFE_CGROUP_PRINT(cg, "cgroup.subtree_control", "+memory");
29 	if (!TST_CGROUP_VER_IS_V1(cg, "cpuset"))
30 		SAFE_CGROUP_PRINT(cg, "cgroup.subtree_control", "+cpuset");
31 
32 	cg_child = tst_cgroup_group_mk(cg, "child");
33 	if (!SAFE_FORK()) {
34 		SAFE_CGROUP_PRINTF(cg_child, "cgroup.procs", "%d", getpid());
35 
36 		SAFE_CGROUP_SCANF(cg_child, "memory.current", "%zu", &mem);
37 		tst_res(TPASS, "child/memory.current = %zu", mem);
38 		SAFE_CGROUP_PRINTF(cg_child, "memory.max",
39 				   "%zu", (1UL << 24) - 1);
40 		SAFE_CGROUP_PRINTF(cg_child, "memory.swap.max",
41 				   "%zu", 1UL << 31);
42 
43 		SAFE_CGROUP_READ(cg_child, "cpuset.mems", buf, sizeof(buf));
44 		tst_res(TPASS, "child/cpuset.mems = %s", buf);
45 		SAFE_CGROUP_PRINT(cg_child, "cpuset.mems", buf);
46 
47 		exit(0);
48 	}
49 
50 	SAFE_CGROUP_PRINTF(cg, "memory.max", "%zu", (1UL << 24) - 1);
51 	SAFE_CGROUP_PRINTF(cg_child, "cgroup.procs", "%d", getpid());
52 	SAFE_CGROUP_SCANF(cg, "memory.current", "%zu", &mem);
53 	tst_res(TPASS, "memory.current = %zu", mem);
54 
55 	tst_reap_children();
56 	SAFE_CGROUP_PRINTF(cg_drain, "cgroup.procs", "%d", getpid());
57 	cg_child = tst_cgroup_group_rm(cg_child);
58 }
59 
setup(void)60 static void setup(void)
61 {
62 	cgopts.only_mount_v1 = !!only_mount_v1,
63 
64 	tst_cgroup_scan();
65 	tst_cgroup_print_config();
66 
67 	tst_cgroup_require("memory", &cgopts);
68 	tst_cgroup_require("cpuset", &cgopts);
69 
70 	cg = tst_cgroup_get_test_group();
71 	cg_drain = tst_cgroup_get_drain_group();
72 }
73 
cleanup(void)74 static void cleanup(void)
75 {
76 	if (cg_child) {
77 		SAFE_CGROUP_PRINTF(cg_drain, "cgroup.procs", "%d", getpid());
78 		cg_child = tst_cgroup_group_rm(cg_child);
79 	}
80 	if (!no_cleanup)
81 		tst_cgroup_cleanup();
82 }
83 
84 static struct tst_test test = {
85 	.test_all = do_test,
86 	.setup = setup,
87 	.cleanup = cleanup,
88 	.options = opts,
89 	.forks_child = 1,
90 };
91