Skip to content

Commit 448f2e4

Browse files
coolgwpevik
authored andcommitted
cgroup_core03.c: New case test cgroup kill feature
Reviewed-by: Li Wang <[email protected]> Reviewed-by: Petr Vorel <[email protected]> Signed-off-by: Wei Gao <[email protected]>
1 parent 973da9f commit 448f2e4

File tree

4 files changed

+134
-0
lines changed

4 files changed

+134
-0
lines changed

lib/tst_cgroup.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ static const struct cgroup_file cgroup_ctrl_files[] = {
167167
{ "cgroup.controllers", NULL, 0 },
168168
{ "cgroup.subtree_control", NULL, 0 },
169169
{ "cgroup.clone_children", "cgroup.clone_children", 0 },
170+
{ "cgroup.kill", NULL, 0 },
170171
{ }
171172
};
172173

runtest/controllers

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#DESCRIPTION:Resource Management testing
22
cgroup_core01 cgroup_core01
33
cgroup_core02 cgroup_core02
4+
cgroup_core03 cgroup_core03
45
cgroup cgroup_regression_test.sh
56
memcg_regression memcg_regression_test.sh
67
memcg_test_3 memcg_test_3

testcases/kernel/controllers/cgroup/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
/cgroup_regression_getdelays
33
/cgroup_core01
44
/cgroup_core02
5+
/cgroup_core03
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
// SPDX-License-Identifier: GPL-2.0-or-later
2+
/*
3+
* Copyright (c) 2012 Christian Brauner <brauner-AT-kernel.org>
4+
* Copyright (c) 2023 SUSE LLC <[email protected]>
5+
*/
6+
7+
/*\
8+
* [Description]
9+
*
10+
* This test is copied from kselftest
11+
* tools/testing/selftests/cgroup/test_kill.c.
12+
*
13+
* Only simple test implemented within current case, the other cases such
14+
* as test_cgkill_tree and test_cgkill_forkbomb can be created later.
15+
*
16+
*/
17+
18+
#include <sys/wait.h>
19+
20+
#include "lapi/syscalls.h"
21+
#include "tst_test.h"
22+
23+
#define MAX_PID_NUM 100
24+
#define PID_NUM MIN(MAX_PID_NUM, (tst_ncpus_available() + 1))
25+
#define BUF_LEN (20 * PID_NUM)
26+
27+
static int *data_ptr;
28+
static char *buf;
29+
static struct tst_cg_group *cg_child_test_simple;
30+
31+
static int wait_for_pid(pid_t pid)
32+
{
33+
int status, ret;
34+
35+
again:
36+
ret = waitpid(pid, &status, 0);
37+
if (ret == -1) {
38+
if (errno == EINTR)
39+
goto again;
40+
41+
return -1;
42+
}
43+
44+
if (WIFSIGNALED(status))
45+
return 0;
46+
47+
return -1;
48+
}
49+
50+
static int cg_run_nowait(const struct tst_cg_group *const cg)
51+
{
52+
int pid;
53+
54+
pid = SAFE_FORK();
55+
if (pid == 0) {
56+
SAFE_CG_PRINTF(cg, "cgroup.procs", "%d", getpid());
57+
if (tst_atomic_inc(data_ptr) == PID_NUM)
58+
TST_CHECKPOINT_WAKE(0);
59+
pause();
60+
}
61+
62+
return pid;
63+
}
64+
65+
static int cg_count_procs(const struct tst_cg_group *cg)
66+
{
67+
char *ptr;
68+
69+
int nr = 0;
70+
71+
SAFE_CG_READ(cg, "cgroup.procs", buf, BUF_LEN);
72+
73+
for (ptr = buf; *ptr; ptr++)
74+
if (*ptr == '\n')
75+
nr++;
76+
77+
return nr;
78+
}
79+
80+
static void run(void)
81+
{
82+
pid_t pids[MAX_PID_NUM];
83+
int i;
84+
*data_ptr = 0;
85+
86+
cg_child_test_simple = tst_cg_group_mk(tst_cg, "cg_test_simple");
87+
88+
if (!SAFE_CG_HAS(cg_child_test_simple, "cgroup.kill")) {
89+
cg_child_test_simple = tst_cg_group_rm(cg_child_test_simple);
90+
tst_brk(TCONF, "cgroup.kill is not supported on your distribution");
91+
}
92+
93+
memset(buf, 0, BUF_LEN);
94+
95+
for (i = 0; i < PID_NUM; i++)
96+
pids[i] = cg_run_nowait(cg_child_test_simple);
97+
98+
TST_CHECKPOINT_WAIT(0);
99+
TST_EXP_VAL(cg_count_procs(cg_child_test_simple), PID_NUM);
100+
SAFE_CG_PRINTF(cg_child_test_simple, "cgroup.kill", "%d", 1);
101+
102+
for (i = 0; i < PID_NUM; i++)
103+
TST_EXP_PASS_SILENT(wait_for_pid(pids[i]));
104+
105+
TST_EXP_VAL(cg_count_procs(cg_child_test_simple), 0);
106+
cg_child_test_simple = tst_cg_group_rm(cg_child_test_simple);
107+
}
108+
109+
static void setup(void)
110+
{
111+
buf = tst_alloc(BUF_LEN);
112+
data_ptr = SAFE_MMAP(NULL, sizeof(uintptr_t), PROT_READ | PROT_WRITE,
113+
MAP_SHARED | MAP_ANONYMOUS, -1, 0);
114+
}
115+
116+
static void cleanup(void)
117+
{
118+
if (data_ptr)
119+
SAFE_MUNMAP(data_ptr, sizeof(uintptr_t));
120+
}
121+
122+
static struct tst_test test = {
123+
.test_all = run,
124+
.setup = setup,
125+
.cleanup = cleanup,
126+
.forks_child = 1,
127+
.max_runtime = 20,
128+
.needs_cgroup_ctrls = (const char *const []){ "base", NULL },
129+
.needs_cgroup_ver = TST_CG_V2,
130+
.needs_checkpoints = 1,
131+
};

0 commit comments

Comments
 (0)