blob: bc94b7683557198d50527f184b33ff62ed42d2a3 [file] [log] [blame]
Garrett Cooper43088e12010-12-13 23:30:59 -08001/*************************************************************************/
2/* Copyright (c) Crackerjack Project., 2007 */
3/* */
4/* This program is free software; you can redistribute it and/or modify */
5/* it under the terms of the GNU General Public License as published by */
6/* the Free Software Foundation; either version 2 of the License, or */
7/* (at your option) any later version. */
8/* */
9/* This program is distributed in the hope that it will be useful, */
10/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
11/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
12/* the GNU General Public License for more details. */
13/* */
14/* You should have received a copy of the GNU General Public License */
15/* along with this program; if not, write to the Free Software */
Wanlong Gao4548c6c2012-10-19 18:03:36 +080016/* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA*/
Garrett Cooper43088e12010-12-13 23:30:59 -080017/* */
18/*************************************************************************/
19/*************************************************************************/
20/* */
21/* File: unshare01.c */
22/* */
23/* Description: This tests the unshare() syscall. */
Garrett Cooper2c282152010-12-16 00:55:50 -080024/* unshare() allows a process to disassociate parts of its */
subrata_modakad846c82009-05-29 12:32:43 +000025/* execution context that are currently being shared with other */
26/* processes. Part of the execution context, such as the namespace */
27/* ,is shared implicitly when a new process is created using */
28/* fork(2) or vfork(2), while other parts, such as virtual memory */
29/* , may be shared by explicit request when creating a process */
30/* using clone(2). */
31/* */
Garrett Cooper2c282152010-12-16 00:55:50 -080032/* The main use of unshare() is to allow a process to control its */
subrata_modakad846c82009-05-29 12:32:43 +000033/* shared execution context without creating a new process. */
Garrett Cooper43088e12010-12-13 23:30:59 -080034/* */
subrata_modakad846c82009-05-29 12:32:43 +000035/* */
36/* The flags argument is a bit mask that specifies which parts of */
37/* the execution context should be unshared. This argument is */
38/* specified by ORing together zero or more of the following cons- */
39/* tants: */
40/* */
41/* CLONE_FILES: */
42/* Reverse the effect of the clone(2) CLONE_FILES flag. */
43/* Unshare the file descriptor table, so that the calling */
44/* process no longer shares its file descriptors with any */
45/* other process. */
46/* CLONE_FS: */
47/* Reverse the effect of the clone(2) CLONE_FS flag.Unshare*/
48/* file system attributes, so that the calling process no */
49/* longer shares its root directory, current directory, or */
50/* umask attributes with any other process. */
51/* CLONE_NEWNS: */
Garrett Cooper2c282152010-12-16 00:55:50 -080052/* This flag has the same effect as the clone(2) CLONE_NEWNS*/
53/* flag. Unshare the namespace, so that the calling process*/
subrata_modakad846c82009-05-29 12:32:43 +000054/* has a private copy of its namespacei which is not shared*/
55/* with any other process. Specifying this flag automat- */
56/* ically implies CLONE_FS as well. */
57/* */
58/* If flags is specified as zero, then unshare() is a no-op; no */
59/* changes are made to the calling process's execution context. */
Garrett Cooper43088e12010-12-13 23:30:59 -080060/* */
61/* Usage: <for command-line> */
62/* unshare01 [-c n] [-e][-i n] [-I x] [-p x] [-t] */
63/* where, -c n : Run n copies concurrently. */
64/* -e : Turn on errno logging. */
65/* -i n : Execute test n times. */
66/* -I x : Execute test for x seconds. */
67/* -P x : Pause for x seconds between iterations. */
68/* -t : Turn on syscall timing. */
69/* */
70/* Total Tests: 1 */
71/* */
72/* Test Name: unshare01 */
73/* History: Porting from Crackerjack to LTP is done by */
74/* Manas Kumar Nayak maknayak@in.ibm.com> */
subrata_modakad846c82009-05-29 12:32:43 +000075/********************************************************************************/
76
Cyril Hrubis019ed6c2011-08-26 12:59:32 +020077#define _GNU_SOURCE
78
subrata_modakad846c82009-05-29 12:32:43 +000079#include <stdio.h>
80#include <sys/wait.h>
81#include <sys/types.h>
82#include <sched.h>
83#include <limits.h>
84#include <unistd.h>
85#include <sys/types.h>
86#include <sys/syscall.h>
87#include <errno.h>
88#include <pwd.h>
89#include <grp.h>
90#include <string.h>
91#include <sys/param.h>
92#include <stdio.h>
93
subrata_modakad846c82009-05-29 12:32:43 +000094#include "test.h"
subrata_modak4827e862009-08-25 07:39:15 +000095#include "config.h"
subrata_modakad846c82009-05-29 12:32:43 +000096
Cyril Hrubisfdce7d52013-04-04 18:35:48 +020097char *TCID = "unshare01";
Wanlong Gao354ebb42012-12-07 10:10:04 +080098int testno;
Cyril Hrubisfdce7d52013-04-04 18:35:48 +020099int TST_TOTAL = 1;
subrata_modakad846c82009-05-29 12:32:43 +0000100
subrata_modak4827e862009-08-25 07:39:15 +0000101#ifdef HAVE_UNSHARE
102
subrata_modakad846c82009-05-29 12:32:43 +0000103/* Extern Global Functions */
104/******************************************************************************/
Garrett Cooper43088e12010-12-13 23:30:59 -0800105/* */
106/* Function: cleanup */
107/* */
subrata_modakad846c82009-05-29 12:32:43 +0000108/* Description: Performs all one time clean up for this test on successful */
Garrett Cooper43088e12010-12-13 23:30:59 -0800109/* completion, premature exit or failure. Closes all temporary */
110/* files, removes all temporary directories exits the test with */
Garrett Cooper00d2a992011-02-15 22:47:34 -0800111/* appropriate return code by calling tst_exit() function. */
Garrett Cooper43088e12010-12-13 23:30:59 -0800112/* */
113/* Input: None. */
114/* */
115/* Output: None. */
116/* */
Garrett Cooper00d2a992011-02-15 22:47:34 -0800117/* Return: On failure - Exits calling tst_exit(). Non '0' return code. */
118/* On success - Exits calling tst_exit(). With '0' return code. */
Garrett Cooper43088e12010-12-13 23:30:59 -0800119/* */
subrata_modakad846c82009-05-29 12:32:43 +0000120/******************************************************************************/
Mike Frysingerc57fba52014-04-09 18:56:30 -0400121void cleanup(void)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800122{
Garrett Cooper2c282152010-12-16 00:55:50 -0800123
Garrett Cooper43088e12010-12-13 23:30:59 -0800124 tst_rmdir();
subrata_modakad846c82009-05-29 12:32:43 +0000125}
126
127/* Local Functions */
128/******************************************************************************/
Garrett Cooper43088e12010-12-13 23:30:59 -0800129/* */
130/* Function: setup */
131/* */
subrata_modakad846c82009-05-29 12:32:43 +0000132/* Description: Performs all one time setup for this test. This function is */
Garrett Cooper43088e12010-12-13 23:30:59 -0800133/* typically used to capture signals, create temporary dirs */
134/* and temporary files that may be used in the course of this */
135/* test. */
136/* */
137/* Input: None. */
138/* */
139/* Output: None. */
140/* */
141/* Return: On failure - Exits by calling cleanup(). */
Garrett Cooper00d2a992011-02-15 22:47:34 -0800142/* On success - returns 0. */
Garrett Cooper43088e12010-12-13 23:30:59 -0800143/* */
subrata_modakad846c82009-05-29 12:32:43 +0000144/******************************************************************************/
Mike Frysingerc57fba52014-04-09 18:56:30 -0400145void setup(void)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800146{
Garrett Cooper43088e12010-12-13 23:30:59 -0800147 /* Capture signals if any */
148 /* Create temporary directories */
149 TEST_PAUSE;
150 tst_tmpdir();
subrata_modakad846c82009-05-29 12:32:43 +0000151}
152
Wanlong Gao354ebb42012-12-07 10:10:04 +0800153int main(int ac, char **av)
154{
Garrett Cooper43088e12010-12-13 23:30:59 -0800155 pid_t pid1;
Cyril Hrubis89af32a2012-10-24 16:39:11 +0200156 int lc;
Garrett Cooper43088e12010-12-13 23:30:59 -0800157 int rval;
Cyril Hrubis0b9589f2014-05-27 17:40:33 +0200158 const char *msg;
Garrett Cooper2c282152010-12-16 00:55:50 -0800159
Garrett Cooper43088e12010-12-13 23:30:59 -0800160 if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL)
161 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
subrata_modakad846c82009-05-29 12:32:43 +0000162
Garrett Cooper43088e12010-12-13 23:30:59 -0800163 setup();
subrata_modakad846c82009-05-29 12:32:43 +0000164
Garrett Cooper43088e12010-12-13 23:30:59 -0800165 for (lc = 0; TEST_LOOPING(lc); ++lc) {
Caspar Zhangd59a6592013-03-07 14:59:12 +0800166 tst_count = 0;
Garrett Cooper43088e12010-12-13 23:30:59 -0800167 for (testno = 0; testno < TST_TOTAL; ++testno) {
subrata_modakad846c82009-05-29 12:32:43 +0000168
Wanlong Gao354ebb42012-12-07 10:10:04 +0800169 pid1 = fork(); //call to fork()
Garrett Cooper00d2a992011-02-15 22:47:34 -0800170 if (pid1 == -1) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800171 tst_brkm(TFAIL | TERRNO, cleanup,
172 "fork failed");
Garrett Cooper00d2a992011-02-15 22:47:34 -0800173 } else if (pid1 == 0) {
174 switch (unshare(CLONE_FILES)) {
175 case 0:
Garrett Cooper43088e12010-12-13 23:30:59 -0800176 printf("unshare with CLONE_FILES call "
Wanlong Gao354ebb42012-12-07 10:10:04 +0800177 "succeeded\n");
Garrett Cooper43088e12010-12-13 23:30:59 -0800178 rval = 0;
Garrett Cooper00d2a992011-02-15 22:47:34 -0800179 break;
180 case -1:
181 if (errno == ENOSYS)
Garrett Cooper43088e12010-12-13 23:30:59 -0800182 rval = 1;
Garrett Cooper00d2a992011-02-15 22:47:34 -0800183 else {
Garrett Cooper43088e12010-12-13 23:30:59 -0800184 perror("unshare failed");
185 rval = 2;
186 }
subrata_modak4827e862009-08-25 07:39:15 +0000187 }
Garrett Cooper43088e12010-12-13 23:30:59 -0800188 exit(rval);
189 } else {
Garrett Cooper00d2a992011-02-15 22:47:34 -0800190 if (wait(&rval) == -1)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800191 tst_brkm(TBROK | TERRNO, cleanup,
192 "wait failed");
Garrett Cooper43088e12010-12-13 23:30:59 -0800193 if (rval != 0 && WIFEXITED(rval)) {
194 switch (WEXITSTATUS(rval)) {
195 case 1:
196 tst_brkm(TCONF, cleanup,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800197 "unshare not supported in "
198 "kernel");
Garrett Cooper43088e12010-12-13 23:30:59 -0800199 break;
200 default:
201 tst_brkm(TFAIL, cleanup,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800202 "unshare failed");
Garrett Cooper43088e12010-12-13 23:30:59 -0800203 }
204 }
subrata_modakad846c82009-05-29 12:32:43 +0000205 }
206
Garrett Cooper53740502010-12-16 00:04:01 -0800207 pid1 = fork();
Garrett Cooper00d2a992011-02-15 22:47:34 -0800208 if (pid1 == -1) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800209 tst_brkm(TFAIL | TERRNO, cleanup,
210 "fork failed");
Garrett Cooper53740502010-12-16 00:04:01 -0800211 } else if (pid1 == 0) {
Garrett Cooper00d2a992011-02-15 22:47:34 -0800212 switch (unshare(CLONE_FS)) {
213 case 0:
Garrett Cooper53740502010-12-16 00:04:01 -0800214 printf("unshare with CLONE_FS call "
Wanlong Gao354ebb42012-12-07 10:10:04 +0800215 "succeeded\n");
Garrett Cooper43088e12010-12-13 23:30:59 -0800216 rval = 0;
Garrett Cooper00d2a992011-02-15 22:47:34 -0800217 break;
218 case -1:
219 if (errno == ENOSYS)
Garrett Cooper43088e12010-12-13 23:30:59 -0800220 rval = 1;
Garrett Cooper00d2a992011-02-15 22:47:34 -0800221 else {
Garrett Cooper43088e12010-12-13 23:30:59 -0800222 perror("unshare failed");
223 rval = 2;
224 }
subrata_modakad846c82009-05-29 12:32:43 +0000225 }
Garrett Cooper43088e12010-12-13 23:30:59 -0800226 exit(rval);
227 } else {
Garrett Cooper00d2a992011-02-15 22:47:34 -0800228 if (wait(&rval) == -1)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800229 tst_brkm(TBROK | TERRNO, cleanup,
230 "wait failed");
Garrett Cooper43088e12010-12-13 23:30:59 -0800231 if (rval != 0 && WIFEXITED(rval)) {
232 switch (WEXITSTATUS(rval)) {
233 case 1:
234 tst_brkm(TCONF, cleanup,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800235 "unshare not supported in "
236 "kernel");
Garrett Cooper43088e12010-12-13 23:30:59 -0800237 break;
238 default:
239 tst_brkm(TFAIL, cleanup,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800240 "unshare failed");
Garrett Cooper43088e12010-12-13 23:30:59 -0800241 }
242 }
subrata_modakad846c82009-05-29 12:32:43 +0000243 }
subrata_modakad846c82009-05-29 12:32:43 +0000244
Garrett Cooper53740502010-12-16 00:04:01 -0800245 pid1 = fork();
246 if (pid1 == -1) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800247 tst_brkm(TFAIL | TERRNO, cleanup,
248 "fork() failed.");
Garrett Cooper00d2a992011-02-15 22:47:34 -0800249 } else if (pid1 == 0) {
250 switch (unshare(CLONE_NEWNS)) {
251 case 0:
Garrett Cooper43088e12010-12-13 23:30:59 -0800252 printf("unshare call with CLONE_NEWNS "
Wanlong Gao354ebb42012-12-07 10:10:04 +0800253 "succeeded\n");
Garrett Cooper43088e12010-12-13 23:30:59 -0800254 rval = 0;
Garrett Cooper00d2a992011-02-15 22:47:34 -0800255 break;
256 case -1:
257 if (errno == ENOSYS)
Garrett Cooper43088e12010-12-13 23:30:59 -0800258 rval = 1;
Garrett Cooper00d2a992011-02-15 22:47:34 -0800259 else {
Garrett Cooper43088e12010-12-13 23:30:59 -0800260 perror("unshare failed");
261 rval = 2;
262 }
subrata_modakad846c82009-05-29 12:32:43 +0000263 }
Garrett Cooper870d30e2010-12-16 17:05:15 -0800264 exit(rval);
Garrett Cooper43088e12010-12-13 23:30:59 -0800265 } else {
Garrett Cooper00d2a992011-02-15 22:47:34 -0800266 if (wait(&rval) == -1)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800267 tst_brkm(TBROK | TERRNO, cleanup,
268 "wait failed");
Garrett Cooper43088e12010-12-13 23:30:59 -0800269 if (rval != 0 && WIFEXITED(rval)) {
270 switch (WEXITSTATUS(rval)) {
271 case 1:
272 tst_brkm(TCONF, cleanup,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800273 "unshare not supported in "
274 "kernel");
Garrett Cooper43088e12010-12-13 23:30:59 -0800275 break;
276 default:
277 tst_brkm(TFAIL, cleanup,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800278 "unshare failed");
Garrett Cooper43088e12010-12-13 23:30:59 -0800279 }
subrata_modakad846c82009-05-29 12:32:43 +0000280
Garrett Cooper43088e12010-12-13 23:30:59 -0800281 }
282
subrata_modakad846c82009-05-29 12:32:43 +0000283 }
284
Garrett Cooper43088e12010-12-13 23:30:59 -0800285 }
subrata_modakad846c82009-05-29 12:32:43 +0000286
Garrett Cooper43088e12010-12-13 23:30:59 -0800287 }
subrata_modakad846c82009-05-29 12:32:43 +0000288 cleanup();
289 tst_exit();
290}
subrata_modak4827e862009-08-25 07:39:15 +0000291#else
292int main(void)
293{
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100294 tst_brkm(TCONF, NULL, "unshare is undefined.");
subrata_modak4827e862009-08-25 07:39:15 +0000295}
Garrett Cooper00d2a992011-02-15 22:47:34 -0800296#endif