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: Serge Hallyn <serue (at) us.ibm.com> 17 * 18 * Check ipcns+sb longevity 19 * 20 * Mount mqueue fs 21 * unshare 22 * In unshared process: 23 * Create "/mq1" with mq_open() 24 * Mount mqueuefs 25 * Check that /mq1 exists 26 * Create /dev/mqueue/mq2 through vfs (create(2)) 27 * Umount /dev/mqueue 28 * Remount /dev/mqueue 29 * Check that both /mq1 and /mq2 exist 30 31 ***************************************************************************/ 32 33 #ifndef _GNU_SOURCE 34 #define _GNU_SOURCE 35 #endif 36 #include <sys/types.h> 37 #include <sys/stat.h> 38 #include <sys/wait.h> 39 #include <assert.h> 40 #include <stdio.h> 41 #include <stdlib.h> 42 #include <unistd.h> 43 #include <string.h> 44 #include <errno.h> 45 #include "mqns.h" 46 #include "mqns_helper.h" 47 48 char *TCID = "posixmq_namespace_03"; 49 int TST_TOTAL = 1; 50 51 int p1[2]; 52 int p2[2]; 53 54 #define FNAM1 DEV_MQUEUE2 SLASH_MQ1 55 #define FNAM2 DEV_MQUEUE2 SLASH_MQ2 56 57 int check_mqueue(void *vtest) 58 { 59 char buf[30]; 60 mqd_t mqd; 61 int rc; 62 struct stat statbuf; 63 64 (void) vtest; 65 66 close(p1[1]); 67 close(p2[0]); 68 69 if (read(p1[0], buf, 3) != 3) { /* go */ 70 perror("read failed"); 71 exit(1); 72 } 73 74 mqd = ltp_syscall(__NR_mq_open, NOSLASH_MQ1, O_RDWR | O_CREAT | O_EXCL, 75 0755, NULL); 76 if (mqd == -1) { 77 write(p2[1], "mqfail", 7); 78 exit(1); 79 } 80 81 mq_close(mqd); 82 83 rc = mount("mqueue", DEV_MQUEUE2, "mqueue", 0, NULL); 84 if (rc == -1) { 85 write(p2[1], "mount1", 7); 86 exit(1); 87 } 88 89 rc = stat(FNAM1, &statbuf); 90 if (rc == -1) { 91 write(p2[1], "stat1", 6); 92 exit(1); 93 } 94 95 rc = creat(FNAM2, 0755); 96 if (rc == -1) { 97 write(p2[1], "creat", 6); 98 exit(1); 99 } 100 101 close(rc); 102 103 rc = umount(DEV_MQUEUE2); 104 if (rc == -1) { 105 write(p2[1], "umount", 7); 106 exit(1); 107 } 108 109 rc = mount("mqueue", DEV_MQUEUE2, "mqueue", 0, NULL); 110 if (rc == -1) { 111 write(p2[1], "mount2", 7); 112 exit(1); 113 } 114 115 rc = stat(FNAM1, &statbuf); 116 if (rc == -1) { 117 write(p2[1], "stat2", 7); 118 exit(1); 119 } 120 121 rc = stat(FNAM2, &statbuf); 122 if (rc == -1) { 123 write(p2[1], "stat3", 7); 124 exit(1); 125 } 126 127 write(p2[1], "done", 5); 128 129 exit(0); 130 } 131 132 static void setup(void) 133 { 134 tst_require_root(); 135 check_mqns(); 136 } 137 138 int main(int argc, char *argv[]) 139 { 140 int r; 141 char buf[30]; 142 int use_clone = T_UNSHARE; 143 144 setup(); 145 146 if (argc == 2 && strcmp(argv[1], "-clone") == 0) { 147 tst_resm(TINFO, "Testing posix mq namespaces through clone(2)"); 148 use_clone = T_CLONE; 149 } else 150 tst_resm(TINFO, 151 "Testing posix mq namespaces through unshare(2)"); 152 153 if (pipe(p1) == -1 || pipe(p2) == -1) 154 tst_brkm(TBROK | TERRNO, NULL, "pipe failed"); 155 156 /* fire off the test */ 157 r = do_clone_unshare_test(use_clone, CLONE_NEWIPC, check_mqueue, NULL); 158 if (r < 0) { 159 tst_brkm(TBROK | TERRNO, NULL, "failed clone/unshare"); 160 } 161 162 tst_resm(TINFO, "Checking correct umount+remount of mqueuefs"); 163 164 mkdir(DEV_MQUEUE2, 0755); 165 166 close(p1[0]); 167 close(p2[1]); 168 write(p1[1], "go", 3); 169 170 read(p2[0], buf, 7); 171 r = TFAIL; 172 if (!strcmp(buf, "mqfail")) { 173 tst_resm(TFAIL, "child process could not create mqueue"); 174 goto fail; 175 } else if (!strcmp(buf, "mount1")) { 176 tst_resm(TFAIL, "child process could not mount mqueue"); 177 goto fail; 178 } else if (!strcmp(buf, "stat1x")) { 179 tst_resm(TFAIL, "mq created by child is not in mqueuefs"); 180 goto fail; 181 } else if (!strcmp(buf, "creat")) { 182 tst_resm(TFAIL, "child couldn't creat mq through mqueuefs"); 183 goto fail; 184 } else if (!strcmp(buf, "umount")) { 185 tst_resm(TFAIL, "child couldn't umount mqueuefs"); 186 goto fail; 187 } else if (!strcmp(buf, "mount2")) { 188 tst_resm(TFAIL, "child couldn't remount mqueuefs"); 189 goto fail; 190 } else if (!strcmp(buf, "stat2")) { 191 tst_resm(TFAIL, 192 "mq_open()d file gone after remount of mqueuefs"); 193 goto fail; 194 } else if (!strcmp(buf, "stat3")) { 195 tst_resm(TFAIL, 196 "creat(2)'d file gone after remount of mqueuefs"); 197 goto fail; 198 } 199 200 tst_resm(TPASS, "umount+remount of mqueuefs remounted the right fs"); 201 202 r = 0; 203 fail: 204 umount(DEV_MQUEUE2); 205 rmdir(DEV_MQUEUE2); 206 tst_exit(); 207 } 208