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