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
print_help(void)26 static void print_help(void)
27 {
28 int i;
29
30 printf("usage: tst_ns_create <%s", params[0].name);
31
32 for (i = 1; params[i].name; i++)
33 printf("|,%s", params[i].name);
34
35 printf(">\n");
36 }
37
child_fn(void)38 static void child_fn(void)
39 {
40 int i;
41
42 SAFE_SETSID();
43 SAFE_CHDIR("/");
44
45 for (i = 0; i < SAFE_SYSCONF(_SC_OPEN_MAX); i++)
46 close(i);
47
48 printf("pausing child\n");
49 pause();
50 }
51
main(int argc,char * argv[])52 int main(int argc, char *argv[])
53 {
54 struct tst_clone_args args = { .exit_signal = SIGCHLD };
55 char *token;
56 int pid;
57
58 if (argc < 2) {
59 print_help();
60 return 1;
61 }
62
63 while ((token = strsep(&argv[1], ","))) {
64 struct param *p = get_param(token);
65
66 if (!p) {
67 printf("Unknown namespace: %s\n", token);
68 print_help();
69 return 1;
70 }
71
72 args.flags |= p->flag;
73 }
74
75 pid = tst_clone(&args);
76 if (pid < 0) {
77 printf("clone() failed");
78 return 1;
79 }
80
81 if (!pid) {
82 child_fn();
83 return 0;
84 }
85
86 printf("%d", pid);
87
88 return 0;
89 }
90