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 "safe_macros.h" 49#include "ipcns_helper.h" 50 51#define TESTKEY 124426L 52#define UNSHARESTR "unshare" 53#define CLONESTR "clone" 54#define NONESTR "none" 55 56char *TCID = "shmem_2nstest"; 57int TST_TOTAL = 1; 58int p2[2]; 59int p1[2]; 60 61/* 62 * check_shmem1() does not read -- it writes to check_shmem2() when it's done. 63 */ 64int check_shmem1(void *vtest) 65{ 66 int id1; 67 68 (void) vtest; 69 70 close(p1[0]); 71 72 /* first create the key */ 73 id1 = shmget(TESTKEY, 100, IPC_CREAT); 74 if (id1 == -1) 75 tst_brkm(TFAIL | TERRNO, NULL, "shmget failed"); 76 77 tst_resm(TINFO, "Cont1: Able to create shared mem segment"); 78 write(p1[1], "done", 5); 79 tst_exit(); 80} 81 82/* 83 * check_shmem2() reads from check_shmem1() and writes to main() when it's done. 84 */ 85int check_shmem2(void *vtest) 86{ 87 char buf[3]; 88 int id2; 89 90 (void) vtest; 91 92 close(p1[1]); 93 close(p2[0]); 94 95 read(p1[0], buf, 3); 96 /* Trying to access shmem, if not existing create new shmem */ 97 id2 = shmget(TESTKEY, 100, 0); 98 if (id2 == -1) { 99 id2 = shmget(TESTKEY, 100, IPC_CREAT); 100 if (id2 == -1) 101 tst_resm(TFAIL | TERRNO, "shmget failed"); 102 else 103 tst_resm(TINFO, 104 "Cont2: Able to allocate shmem seg with " 105 "the same key"); 106 write(p2[1], "notfnd", 7); 107 } else 108 write(p2[1], "exists", 7); 109 110 tst_exit(); 111} 112 113static void setup(void) 114{ 115 tst_require_root(); 116 check_newipc(); 117} 118 119int main(int argc, char *argv[]) 120{ 121 int ret, use_clone = T_NONE; 122 char *tsttype = NONESTR; 123 char buf[7]; 124 int id; 125 126 setup(); 127 128 if (argc != 2) { 129 tst_resm(TINFO, "Usage: %s <clone| unshare| none>", argv[0]); 130 tst_resm(TINFO, " where clone, unshare, or fork specifies" 131 " unshare method."); 132 tst_exit(); 133 } 134 135 /* Using PIPE's to sync between containers and Parent */ 136 SAFE_PIPE(NULL, p1); 137 SAFE_PIPE(NULL, p2); 138 139 if (strcmp(argv[1], "clone") == 0) { 140 use_clone = T_CLONE; 141 tsttype = CLONESTR; 142 } else if (strcmp(argv[1], "unshare") == 0) { 143 use_clone = T_UNSHARE; 144 tsttype = UNSHARESTR; 145 } 146 147 tst_resm(TINFO, "Shared Memory namespace test : %s", tsttype); 148 149 /* Create 2 containers */ 150 ret = 151 do_clone_unshare_test(use_clone, CLONE_NEWIPC, check_shmem1, NULL); 152 if (ret < 0) 153 tst_brkm(TFAIL, NULL, "clone/unshare failed"); 154 155 ret = 156 do_clone_unshare_test(use_clone, CLONE_NEWIPC, check_shmem2, NULL); 157 if (ret < 0) 158 tst_brkm(TFAIL, NULL, "clone/unshare failed"); 159 160 close(p2[1]); 161 read(p2[0], buf, 7); 162 163 if (strcmp(buf, "exists") == 0) { 164 if (use_clone == T_NONE) 165 tst_resm(TPASS, 166 "Plain cloned process able to access shmem " 167 "segment created"); 168 else 169 tst_resm(TFAIL, 170 "%s : In namespace2 found the shmem segment " 171 "created in Namespace1", tsttype); 172 } else { 173 if (use_clone == T_NONE) 174 tst_resm(TFAIL, 175 "Plain cloned process didn't find shmem seg"); 176 else 177 tst_resm(TPASS, 178 "%s : In namespace2 unable to access the shmem seg " 179 "created in Namespace1", tsttype); 180 } 181 /* destroy the key */ 182 183 id = shmget(TESTKEY, 100, 0); 184 shmctl(id, IPC_RMID, NULL); 185 186 tst_exit(); 187} 188