1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0
2f08c3bdfSopenharmony_ci/*\
3f08c3bdfSopenharmony_ci *
4f08c3bdfSopenharmony_ci * [Description]
5f08c3bdfSopenharmony_ci *
6f08c3bdfSopenharmony_ci * Conversion of the first kself test in cgroup/test_memcontrol.c.
7f08c3bdfSopenharmony_ci * This test creates two nested cgroups with and without enabling the
8f08c3bdfSopenharmony_ci * memory controller.
9f08c3bdfSopenharmony_ci *
10f08c3bdfSopenharmony_ci * The LTP API automatically adds controllers to subtree_control when
11f08c3bdfSopenharmony_ci * a child cgroup is added. So unlike the kselftest we remove the
12f08c3bdfSopenharmony_ci * controller after it being added automatically.
13f08c3bdfSopenharmony_ci */
14f08c3bdfSopenharmony_ci#define _GNU_SOURCE
15f08c3bdfSopenharmony_ci
16f08c3bdfSopenharmony_ci#include <stdio.h>
17f08c3bdfSopenharmony_ci
18f08c3bdfSopenharmony_ci#include "tst_test.h"
19f08c3bdfSopenharmony_ci
20f08c3bdfSopenharmony_cistatic struct tst_cg_group *parent, *child;
21f08c3bdfSopenharmony_cistatic struct tst_cg_group *parent2, *child2;
22f08c3bdfSopenharmony_ci
23f08c3bdfSopenharmony_cistatic void test_memcg_subtree_control(void)
24f08c3bdfSopenharmony_ci{
25f08c3bdfSopenharmony_ci	parent = tst_cg_group_mk(tst_cg, "memcg_test_0");
26f08c3bdfSopenharmony_ci	child = tst_cg_group_mk(parent, "memcg_test_1");
27f08c3bdfSopenharmony_ci	parent2 = tst_cg_group_mk(tst_cg, "memcg_test_2");
28f08c3bdfSopenharmony_ci	child2 = tst_cg_group_mk(parent2, "memcg_test_3");
29f08c3bdfSopenharmony_ci
30f08c3bdfSopenharmony_ci	SAFE_CG_PRINT(parent2, "cgroup.subtree_control", "-memory");
31f08c3bdfSopenharmony_ci
32f08c3bdfSopenharmony_ci	TST_EXP_POSITIVE(
33f08c3bdfSopenharmony_ci		SAFE_CG_OCCURSIN(child, "cgroup.controllers", "memory"),
34f08c3bdfSopenharmony_ci		"child should have memory controller");
35f08c3bdfSopenharmony_ci	TST_EXP_POSITIVE(
36f08c3bdfSopenharmony_ci		!SAFE_CG_OCCURSIN(child2, "cgroup.controllers", "memory"),
37f08c3bdfSopenharmony_ci		"child2 should not have memory controller");
38f08c3bdfSopenharmony_ci
39f08c3bdfSopenharmony_ci	child2 = tst_cg_group_rm(child2);
40f08c3bdfSopenharmony_ci	parent2 = tst_cg_group_rm(parent2);
41f08c3bdfSopenharmony_ci	child = tst_cg_group_rm(child);
42f08c3bdfSopenharmony_ci	parent = tst_cg_group_rm(parent);
43f08c3bdfSopenharmony_ci}
44f08c3bdfSopenharmony_ci
45f08c3bdfSopenharmony_cistatic void cleanup(void)
46f08c3bdfSopenharmony_ci{
47f08c3bdfSopenharmony_ci	if (child2)
48f08c3bdfSopenharmony_ci		child2 = tst_cg_group_rm(child2);
49f08c3bdfSopenharmony_ci	if (parent2)
50f08c3bdfSopenharmony_ci		parent2 = tst_cg_group_rm(parent2);
51f08c3bdfSopenharmony_ci	if (child)
52f08c3bdfSopenharmony_ci		child = tst_cg_group_rm(child);
53f08c3bdfSopenharmony_ci	if (parent)
54f08c3bdfSopenharmony_ci		parent = tst_cg_group_rm(parent);
55f08c3bdfSopenharmony_ci}
56f08c3bdfSopenharmony_ci
57f08c3bdfSopenharmony_cistatic struct tst_test test = {
58f08c3bdfSopenharmony_ci	.cleanup = cleanup,
59f08c3bdfSopenharmony_ci	.test_all = test_memcg_subtree_control,
60f08c3bdfSopenharmony_ci	.needs_cgroup_ver = TST_CG_V2,
61f08c3bdfSopenharmony_ci	.needs_cgroup_ctrls = (const char *const []){ "memory", NULL },
62f08c3bdfSopenharmony_ci};
63