1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (c) 2015 Red Hat, Inc.
4 * Matus Marhefka <mmarhefk@redhat.com>
5 * Copyright (C) 2023 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
6 * Copyright (c) Linux Test Project, 2020-2023
7 */
8
9 /*\
10 * [Description]
11 *
12 * Creates a child process in the new specified namespace(s), child is then
13 * daemonized and is running in the background. PID of the daemonized child
14 * process is printed on the stdout. As the new namespace(s) is(are) maintained
15 * by the daemonized child process it(they) can be removed by killing this
16 * process.
17 */
18
19 #define TST_NO_DEFAULT_MAIN
20
21 #include <stdio.h>
22 #include <string.h>
23 #include "tst_test.h"
24 #include "tst_ns_common.h"
25
26 extern struct tst_test *tst_test;
27
28 static struct tst_test test = {
29 .forks_child = 1, /* Needed by SAFE_CLONE */
30 };
31
print_help(void)32 static void print_help(void)
33 {
34 int i;
35
36 printf("usage: tst_ns_create <%s", params[0].name);
37
38 for (i = 1; params[i].name; i++)
39 printf("|,%s", params[i].name);
40
41 printf(">\n");
42 }
43
child_fn(void)44 static void child_fn(void)
45 {
46 int i;
47
48 SAFE_SETSID();
49 SAFE_CHDIR("/");
50
51 for (i = 0; i < SAFE_SYSCONF(_SC_OPEN_MAX); i++)
52 close(i);
53
54 printf("pausing child\n");
55 pause();
56 }
57
main(int argc,char * argv[])58 int main(int argc, char *argv[])
59 {
60 struct tst_clone_args args = { 0, SIGCHLD };
61 char *token;
62 int pid;
63
64 if (argc < 2) {
65 print_help();
66 return 1;
67 }
68
69 tst_test = &test;
70
71 while ((token = strsep(&argv[1], ","))) {
72 struct param *p = get_param(token);
73
74 if (!p) {
75 printf("Unknown namespace: %s\n", token);
76 print_help();
77 return 1;
78 }
79
80 args.flags |= p->flag;
81 }
82
83 pid = SAFE_CLONE(&args);
84 if (!pid) {
85 child_fn();
86 return 0;
87 }
88
89 printf("%d", pid);
90
91 return 0;
92 }
93