• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* *************************************************************************
2 * Copyright (c) International Business Machines Corp., 2009
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
11 * the GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15 *
16 * Author: Veerendra C <vechandr@in.ibm.com>
17 *
18 * Test Assertion:
19 * This testcase verifies the Shared Memory isoloation in 2 containers.
20 * It tries to create/access a Shared Memory created with the same KEY.
21 *
22 * Description:
23 * Create 2 'containers' with the below flag value
24 *   Flag = clone, clone(CLONE_NEWIPC), or unshare(CLONE_NEWIPC)
25 * In Cont1, create Shared Memory segment with key 124426L
26 * In Cont2, try to access the MQ created in Cont1.
27 * PASS :
28 * 		If flag = None and the shmem seg is accessible in Cont2.
29 *		If flag = unshare/clone and the shmem seg is not accessible in Cont2.
30 * 		If shmem seg is not accessible in Cont2,
31 *		creates new shmem with same key to double check isloation in IPCNS.
32 *
33 * FAIL :
34 * 		If flag = none and the shmem seg is not accessible.
35 * 		If flag = unshare/clone and shmem seg is accessible in Cont2.
36 *		If the new shmem seg creation Fails.
37 ***************************************************************************/
38 
39 #define _GNU_SOURCE 1
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <unistd.h>
43 #include <string.h>
44 #include <sys/ipc.h>
45 #include <sys/shm.h>
46 #include <libclone.h>
47 #include "test.h"
48 #include "ipcns_helper.h"
49 
50 #define TESTKEY    124426L
51 #define UNSHARESTR "unshare"
52 #define CLONESTR   "clone"
53 #define NONESTR    "none"
54 
55 char *TCID = "shmem_2nstest";
56 int TST_TOTAL = 1;
57 int p2[2];
58 int p1[2];
59 
60 /*
61  * check_shmem1() does not read -- it writes to check_shmem2() when it's done.
62  */
check_shmem1(void * vtest)63 int check_shmem1(void *vtest)
64 {
65 	int id1;
66 
67 	(void) vtest;
68 
69 	close(p1[0]);
70 
71 	/* first create the key */
72 	id1 = shmget(TESTKEY, 100, IPC_CREAT);
73 	if (id1 == -1)
74 		tst_brkm(TFAIL | TERRNO, NULL, "shmget failed");
75 
76 	tst_resm(TINFO, "Cont1: Able to create shared mem segment");
77 	write(p1[1], "done", 5);
78 	tst_exit();
79 }
80 
81 /*
82  * check_shmem2() reads from check_shmem1() and writes to main() when it's done.
83  */
check_shmem2(void * vtest)84 int check_shmem2(void *vtest)
85 {
86 	char buf[3];
87 	int id2;
88 
89 	(void) vtest;
90 
91 	close(p1[1]);
92 	close(p2[0]);
93 
94 	read(p1[0], buf, 3);
95 	/* Trying to access shmem, if not existing create new shmem */
96 	id2 = shmget(TESTKEY, 100, 0);
97 	if (id2 == -1) {
98 		id2 = shmget(TESTKEY, 100, IPC_CREAT);
99 		if (id2 == -1)
100 			tst_resm(TFAIL | TERRNO, "shmget failed");
101 		else
102 			tst_resm(TINFO,
103 				 "Cont2: Able to allocate shmem seg with "
104 				 "the same key");
105 		write(p2[1], "notfnd", 7);
106 	} else
107 		write(p2[1], "exists", 7);
108 
109 	tst_exit();
110 }
111 
setup(void)112 static void setup(void)
113 {
114 	tst_require_root();
115 	check_newipc();
116 }
117 
main(int argc,char * argv[])118 int main(int argc, char *argv[])
119 {
120 	int ret, use_clone = T_NONE;
121 	char *tsttype = NONESTR;
122 	char buf[7];
123 	int id;
124 
125 	setup();
126 
127 	if (argc != 2) {
128 		tst_resm(TINFO, "Usage: %s <clone| unshare| none>", argv[0]);
129 		tst_resm(TINFO, " where clone, unshare, or fork specifies"
130 			 " unshare method.");
131 		tst_exit();
132 	}
133 
134 	/* Using PIPE's to sync between containers and Parent */
135 	if (pipe(p1) == -1)
136 		tst_brkm(TBROK | TERRNO, NULL, "pipe1 error");
137 	if (pipe(p2) == -1)
138 		tst_brkm(TBROK | TERRNO, NULL, "pipe2 error");
139 
140 	if (strcmp(argv[1], "clone") == 0) {
141 		use_clone = T_CLONE;
142 		tsttype = CLONESTR;
143 	} else if (strcmp(argv[1], "unshare") == 0) {
144 		use_clone = T_UNSHARE;
145 		tsttype = UNSHARESTR;
146 	}
147 
148 	tst_resm(TINFO, "Shared Memory namespace test : %s", tsttype);
149 
150 	/* Create 2 containers */
151 	ret =
152 	    do_clone_unshare_test(use_clone, CLONE_NEWIPC, check_shmem1, NULL);
153 	if (ret < 0)
154 		tst_brkm(TFAIL, NULL, "clone/unshare failed");
155 
156 	ret =
157 	    do_clone_unshare_test(use_clone, CLONE_NEWIPC, check_shmem2, NULL);
158 	if (ret < 0)
159 		tst_brkm(TFAIL, NULL, "clone/unshare failed");
160 
161 	close(p2[1]);
162 	read(p2[0], buf, 7);
163 
164 	if (strcmp(buf, "exists") == 0) {
165 		if (use_clone == T_NONE)
166 			tst_resm(TPASS,
167 				 "Plain cloned process able to access shmem "
168 				 "segment created");
169 		else
170 			tst_resm(TFAIL,
171 				 "%s : In namespace2 found the shmem segment "
172 				 "created in Namespace1", tsttype);
173 	} else {
174 		if (use_clone == T_NONE)
175 			tst_resm(TFAIL,
176 				 "Plain cloned process didn't find shmem seg");
177 		else
178 			tst_resm(TPASS,
179 				 "%s : In namespace2 unable to access the shmem seg "
180 				 "created in Namespace1", tsttype);
181 	}
182 	/* destroy the key */
183 
184 	id = shmget(TESTKEY, 100, 0);
185 	shmctl(id, IPC_RMID, NULL);
186 
187 	tst_exit();
188 }
189