1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (c) 2023 SUSE LLC <[email protected]>
4 */
5
6 /*\
7 * [Description]
8 *
9 * This test case check clone3 CLONE_INTO_CGROUP flag
10 *
11 */
12
13 #define _GNU_SOURCE
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <sys/wait.h>
17
18 #include "tst_test.h"
19 #include "lapi/sched.h"
20 #include "lapi/pidfd.h"
21
22 #define BUF_LEN 20
23
24 static struct tst_cg_group *cg_child_test_simple;
25 static int fd;
26 static struct tst_clone_args *args;
27
clone_into_cgroup(int cgroup_fd)28 static pid_t clone_into_cgroup(int cgroup_fd)
29 {
30
31 args->flags = CLONE_INTO_CGROUP;
32 args->exit_signal = SIGCHLD;
33 args->cgroup = cgroup_fd;
34
35 return tst_clone(args);
36 }
37
run(void)38 static void run(void)
39 {
40 pid_t pid;
41
42 pid = clone_into_cgroup(fd);
43
44 if (!pid) {
45 TST_CHECKPOINT_WAIT(0);
46 return;
47 }
48
49 char buf[BUF_LEN];
50
51 SAFE_CG_READ(cg_child_test_simple, "cgroup.procs", buf, BUF_LEN);
52
53 if (atoi(buf) == pid)
54 tst_res(TPASS, "clone3 case pass!");
55 else
56 tst_brk(TFAIL | TTERRNO, "clone3() failed !");
57
58 TST_CHECKPOINT_WAKE(0);
59
60 SAFE_WAITPID(pid, NULL, 0);
61
62 }
63
setup(void)64 static void setup(void)
65 {
66 clone3_supported_by_kernel();
67
68 cg_child_test_simple = tst_cg_group_mk(tst_cg, "cg_test_simple");
69
70 fd = tst_cg_group_unified_dir_fd(cg_child_test_simple);
71
72 if (fd < 0)
73 tst_brk(TBROK, "get dir fd failed!");
74 }
75
cleanup(void)76 static void cleanup(void)
77 {
78 cg_child_test_simple = tst_cg_group_rm(cg_child_test_simple);
79 }
80
81 static struct tst_test test = {
82 .test_all = run,
83 .setup = setup,
84 .cleanup = cleanup,
85 .forks_child = 1,
86 .needs_cgroup_ctrls = (const char *const []){ "base", NULL },
87 .needs_cgroup_ver = TST_CG_V2,
88 .needs_checkpoints = 1,
89 .min_kver = "5.7",
90 .bufs = (struct tst_buffers []) {
91 {&args, .size = sizeof(*args)},
92 {},
93 }
94 };
95