xref: /aosp_15_r20/external/ltp/testcases/kernel/containers/utsname/utsname03.c (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (c) International Business Machines Corp., 2007
4  * Copyright (C) 2023 SUSE LLC Andrea Cervesato <[email protected]>
5  */
6 
7 /*\
8  * [Description]
9  *
10  * Clone two processes using CLONE_NEWUTS, change hostname from the first
11  * container and check if hostname didn't change inside the second one.
12  */
13 
14 #define _GNU_SOURCE
15 
16 #include "tst_test.h"
17 #include "lapi/sched.h"
18 
19 #define HOSTNAME "LTP_HOSTNAME"
20 
21 static char *str_op;
22 static char *hostname1;
23 static char *hostname2;
24 static char originalhost[HOST_NAME_MAX];
25 
reset_hostname(void)26 static void reset_hostname(void)
27 {
28 	SAFE_SETHOSTNAME(originalhost, strlen(originalhost));
29 }
30 
child1_run(void)31 static void child1_run(void)
32 {
33 	SAFE_SETHOSTNAME(HOSTNAME, strlen(HOSTNAME));
34 	SAFE_GETHOSTNAME(hostname1, HOST_NAME_MAX);
35 
36 	TST_CHECKPOINT_WAKE(0);
37 }
38 
child2_run(void)39 static void child2_run(void)
40 {
41 	TST_CHECKPOINT_WAIT(0);
42 
43 	SAFE_GETHOSTNAME(hostname2, HOST_NAME_MAX);
44 }
45 
run(void)46 static void run(void)
47 {
48 	const struct tst_clone_args cargs = {
49 		.flags = CLONE_NEWUTS,
50 		.exit_signal = SIGCHLD,
51 	};
52 
53 	memset(hostname1, 0, HOST_NAME_MAX);
54 	memset(hostname2, 0, HOST_NAME_MAX);
55 
56 	if (!str_op || !strcmp(str_op, "clone")) {
57 		tst_res(TINFO, "clone() with CLONE_NEWUTS");
58 
59 		if (!SAFE_CLONE(&cargs)) {
60 			child1_run();
61 			return;
62 		}
63 
64 		if (!SAFE_CLONE(&cargs)) {
65 			child2_run();
66 			return;
67 		}
68 	} else {
69 		tst_res(TINFO, "unshare() with CLONE_NEWUTS");
70 
71 		if (!SAFE_FORK()) {
72 			SAFE_UNSHARE(CLONE_NEWUTS);
73 			child1_run();
74 			return;
75 		}
76 
77 		if (!SAFE_FORK()) {
78 			SAFE_UNSHARE(CLONE_NEWUTS);
79 			child2_run();
80 			return;
81 		}
82 	}
83 
84 	tst_reap_children();
85 
86 	TST_EXP_PASS(strcmp(hostname1, HOSTNAME));
87 	TST_EXP_PASS(strcmp(hostname2, originalhost));
88 
89 	reset_hostname();
90 }
91 
setup(void)92 static void setup(void)
93 {
94 	hostname1 = SAFE_MMAP(NULL, HOST_NAME_MAX, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
95 	hostname2 = SAFE_MMAP(NULL, HOST_NAME_MAX, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
96 
97 	memset(originalhost, 0, HOST_NAME_MAX);
98 
99 	SAFE_GETHOSTNAME(originalhost, HOST_NAME_MAX);
100 }
101 
cleanup(void)102 static void cleanup(void)
103 {
104 	SAFE_MUNMAP(hostname1, HOST_NAME_MAX);
105 	SAFE_MUNMAP(hostname2, HOST_NAME_MAX);
106 
107 	reset_hostname();
108 }
109 
110 static struct tst_test test = {
111 	.test_all = run,
112 	.setup = setup,
113 	.cleanup = cleanup,
114 	.needs_root = 1,
115 	.forks_child = 1,
116 	.needs_checkpoints = 1,
117 	.options = (struct tst_option[]) {
118 		{ "m:", &str_op, "Test execution mode <clone|unshare>" },
119 		{},
120 	},
121 };
122