Home | History | Annotate | Download | only in mqns
      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