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* In Parent Process , create mesgq with key 154326L 19* Now create container by passing 1 of the flag values.. 20* Flag = clone, clone(CLONE_NEWIPC), or unshare(CLONE_NEWIPC) 21* In cloned process, try to access the created mesgq 22* Test PASS: If the mesgq is readable when flag is None. 23* Test FAIL: If the mesgq is readable when flag is Unshare or Clone. 24***************************************************************************/ 25 26#define _GNU_SOURCE 1 27#include <stdio.h> 28#include <stdlib.h> 29#include <unistd.h> 30#include <string.h> 31#include <sys/ipc.h> 32#include <sys/msg.h> 33#include <libclone.h> 34#include "test.h" 35#include "ipcns_helper.h" 36 37#define KEY_VAL 154326L 38#define UNSHARESTR "unshare" 39#define CLONESTR "clone" 40#define NONESTR "none" 41 42char *TCID = "mesgq_nstest"; 43int TST_TOTAL = 1; 44int p1[2]; 45int p2[2]; 46struct msg_buf { 47 long int mtype; /* type of received/sent message */ 48 char mtext[80]; /* text of the message */ 49} msg; 50 51void mesgq_read(int id) 52{ 53 int READMAX = 80; 54 int n; 55 /* read msg type 5 on the Q; msgtype, flags are last 2 params.. */ 56 57 n = msgrcv(id, &msg, READMAX, 5, 0); 58 if (n == -1) 59 perror("msgrcv"), tst_exit(); 60 61 tst_resm(TINFO, "Mesg read of %d bytes; Type %ld: Msg: %.*s", 62 n, msg.mtype, n, msg.mtext); 63} 64 65int check_mesgq(void *vtest) 66{ 67 char buf[3]; 68 int id; 69 70 (void) vtest; 71 72 close(p1[1]); 73 close(p2[0]); 74 75 read(p1[0], buf, 3); 76 id = msgget(KEY_VAL, 0); 77 if (id == -1) 78 write(p2[1], "notfnd", 7); 79 else { 80 write(p2[1], "exists", 7); 81 mesgq_read(id); 82 } 83 tst_exit(); 84} 85 86static void setup(void) 87{ 88 tst_require_root(); 89 check_newipc(); 90} 91 92int main(int argc, char *argv[]) 93{ 94 int ret, use_clone = T_NONE, id, n; 95 char *tsttype = NONESTR; 96 char buf[7]; 97 98 setup(); 99 100 if (argc != 2) { 101 tst_resm(TFAIL, "Usage: %s <clone|unshare|none>", argv[0]); 102 tst_brkm(TFAIL, NULL, " where clone, unshare, or fork specifies" 103 " unshare method."); 104 } 105 106 /* Using PIPE's to sync between container and Parent */ 107 if (pipe(p1) == -1) { 108 perror("pipe"); 109 exit(EXIT_FAILURE); 110 } 111 if (pipe(p2) == -1) { 112 perror("pipe"); 113 exit(EXIT_FAILURE); 114 } 115 116 tsttype = NONESTR; 117 118 if (strcmp(argv[1], "clone") == 0) { 119 use_clone = T_CLONE; 120 tsttype = CLONESTR; 121 } else if (strcmp(argv[1], "unshare") == 0) { 122 use_clone = T_UNSHARE; 123 tsttype = UNSHARESTR; 124 } 125 126 id = msgget(KEY_VAL, IPC_CREAT | IPC_EXCL | 0600); 127 if (id == -1) { 128 perror("msgget"); 129 /* Retry without attempting to create the MQ */ 130 id = msgget(KEY_VAL, 0); 131 if (id == -1) 132 perror("msgget failure"), exit(1); 133 } 134 135 msg.mtype = 5; 136 strcpy(msg.mtext, "Message of type 5!"); 137 n = msgsnd(id, &msg, strlen(msg.mtext), 0); 138 if (n == -1) 139 perror("msgsnd"), tst_exit(); 140 141 tst_resm(TINFO, "mesgq namespaces test : %s", tsttype); 142 /* fire off the test */ 143 ret = do_clone_unshare_test(use_clone, CLONE_NEWIPC, check_mesgq, NULL); 144 if (ret < 0) { 145 tst_brkm(TFAIL, NULL, "%s failed", tsttype); 146 } 147 148 close(p1[0]); 149 close(p2[1]); 150 write(p1[1], "go", 3); 151 152 read(p2[0], buf, 7); 153 if (strcmp(buf, "exists") == 0) { 154 if (use_clone == T_NONE) 155 tst_resm(TPASS, "Plain cloned process found mesgq " 156 "inside container"); 157 else 158 tst_resm(TFAIL, 159 "%s: Container init process found mesgq", 160 tsttype); 161 } else { 162 if (use_clone == T_NONE) 163 tst_resm(TFAIL, 164 "Plain cloned process didn't find mesgq"); 165 else 166 tst_resm(TPASS, "%s: Container didn't find mesgq", 167 tsttype); 168 } 169 170 /* Delete the mesgQ */ 171 id = msgget(KEY_VAL, 0); 172 msgctl(id, IPC_RMID, NULL); 173 174 tst_exit(); 175} 176