1 /*
2  * Copyright (c) 2013 Fujitsu Ltd.
3  * Author: DAN LI <li.dan@cn.fujitsu.com>
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it would be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12  *
13  * You should have received a copy of the GNU General Public License along
14  * with this program; if not, write the Free Software Foundation, Inc.,
15  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16  *
17  */
18 
19 /*
20  *  DESCRIPTION
21  *	Test for feature MS_BIND of mount.
22  *	"Perform a bind mount, making a file or a directory subtree visible
23  *	 at another point within a file system."
24  */
25 
26 #include <errno.h>
27 #include <sys/mount.h>
28 #include <sys/types.h>
29 #include <sys/stat.h>
30 #include <unistd.h>
31 #include <fcntl.h>
32 
33 #include "test.h"
34 #include "safe_macros.h"
35 
36 static void help(void);
37 static void setup(void);
38 static void cleanup(void);
39 
40 char *TCID = "mount05";
41 int TST_TOTAL = 1;
42 
43 #define DIR_MODE	(S_IRWXU | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP)
44 
45 static int dflag;
46 static char *fstype = "ext2";
47 static char *device;
48 static const char file_src[] = "mnt_src/tstfile";
49 static const char file_des[] = "mnt_des/tstfile";
50 static const char mntpoint_src[] = "mnt_src";
51 static const char mntpoint_des[] = "mnt_des";
52 
53 static option_t options[] = {
54 	{"T:", NULL, &fstype},
55 	{"D:", &dflag, &device},
56 	{NULL, NULL, NULL},
57 };
58 
main(int argc,char * argv[])59 int main(int argc, char *argv[])
60 {
61 	int lc;
62 
63 	tst_parse_opts(argc, argv, options, &help);
64 
65 	setup();
66 
67 	for (lc = 0; TEST_LOOPING(lc); lc++) {
68 
69 		tst_count = 0;
70 
71 		TEST(mount(mntpoint_src, mntpoint_des, fstype, MS_BIND, NULL));
72 
73 		if (TEST_RETURN != 0) {
74 			tst_resm(TFAIL | TTERRNO, "mount(2) failed");
75 		} else {
76 
77 			if (open(file_des, O_CREAT | O_EXCL, S_IRWXU) == -1 &&
78 			    errno == EEXIST)
79 				tst_resm(TPASS, "bind mount is ok");
80 			else
81 				tst_resm(TFAIL, "file %s is not available",
82 					 file_des);
83 
84 			TEST(tst_umount(mntpoint_des));
85 			if (TEST_RETURN != 0)
86 				tst_brkm(TBROK | TTERRNO, cleanup,
87 					 "umount(2) failed");
88 		}
89 	}
90 
91 	cleanup();
92 	tst_exit();
93 }
94 
setup(void)95 void setup(void)
96 {
97 	tst_require_root();
98 
99 	tst_sig(NOFORK, DEF_HANDLER, cleanup);
100 
101 	tst_tmpdir();
102 
103 	SAFE_MKDIR(cleanup, mntpoint_src, DIR_MODE);
104 	SAFE_MKDIR(cleanup, mntpoint_des, DIR_MODE);
105 
106 	if (dflag) {
107 		tst_mkfs(NULL, device, fstype, NULL, NULL);
108 
109 		SAFE_MOUNT(cleanup, device, mntpoint_src, fstype, 0, NULL);
110 	}
111 
112 	SAFE_FILE_PRINTF(cleanup, file_src, "TEST FILE");
113 
114 	TEST_PAUSE;
115 }
116 
cleanup(void)117 void cleanup(void)
118 {
119 	if (dflag)
120 		if (tst_umount(mntpoint_src) != 0)
121 			tst_brkm(TBROK | TTERRNO, NULL, "umount(2) failed");
122 
123 	tst_rmdir();
124 }
125 
help(void)126 void help(void)
127 {
128 	printf("-T type	  : specifies the type of filesystem to be mounted. "
129 	       "Default ext2.\n");
130 	printf("-D device : device used for mounting.\n");
131 }
132