• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) Wipro Technologies Ltd, 2002.  All Rights Reserved.
3  *  AUTHOR: Nirmala Devi Dhanasekar <nirmala.devi@wipro.com>
4  * Copyright (c) 2014 Cyril Hrubis <chrubis@suse.cz>
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms of version 2 of the GNU General Public License as
8  * published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it would be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  *
18  */
19 
20 /*
21 
22    DESCRIPTION
23 	Check for basic errors returned by mount(2) system call.
24 
25 	Verify that mount(2) returns -1 and sets errno to
26 	1) ENODEV if filesystem type not configured
27 	2) ENOTBLK if specialfile is not a block device
28 	3) EBUSY if specialfile is already mounted or
29 		it  cannot  be remounted read-only, because it still holds
30 		files open for writing.
31 	4) EINVAL if specialfile or device is invalid or
32 		 a remount was attempted, while source was not already
33 		 mounted on target.
34 	5) EFAULT if specialfile or device file points to invalid address space.
35 	6) ENAMETOOLONG if pathname was longer than MAXPATHLEN.
36 	7) ENOENT if pathname was empty or has a nonexistent component.
37 	8) ENOTDIR if not a directory.
38 */
39 
40 #include <errno.h>
41 #include <sys/mount.h>
42 #include <sys/types.h>
43 #include <sys/stat.h>
44 #include <sys/fcntl.h>
45 #include "test.h"
46 #include "safe_macros.h"
47 
48 static void setup(void);
49 static void cleanup(void);
50 
51 char *TCID = "mount02";
52 
53 #define DIR_MODE	(S_IRWXU | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP)
54 #define FILE_MODE	(S_IRWXU | S_IRWXG | S_IRWXO)
55 
56 static char path[PATH_MAX + 2];
57 static const char *long_path = path;
58 static const char *fs_type;
59 static const char *wrong_fs_type = "error";
60 static const char *mntpoint = "mntpoint";
61 static const char *device;
62 static const char *null = NULL;
63 static const char *fault = (void*)-1;
64 static const char *nonexistent = "nonexistent";
65 static const char *char_dev = "char_device";
66 static const char *file = "filename";
67 static int fd;
68 
69 static void do_umount(void);
70 static void close_umount(void);
71 static void do_mount(void);
72 static void mount_open(void);
73 
74 static struct test_case {
75 	const char **device;
76 	const char **mntpoint;
77 	const char **fs_type;
78 	unsigned long flag;
79 	int exp_errno;
80 	void (*setup)(void);
81 	void (*cleanup)(void);
82 } tc[] = {
83 	{&device, &mntpoint, &wrong_fs_type, 0, ENODEV, NULL, NULL},
84 	{&char_dev, &mntpoint, &fs_type, 0, ENOTBLK, NULL, NULL},
85 	{&device, &mntpoint, &fs_type, 0, EBUSY, do_mount, do_umount},
86 	{&device, &mntpoint, &fs_type, MS_REMOUNT | MS_RDONLY, EBUSY,
87 	 mount_open, close_umount},
88 	{&null, &mntpoint, &fs_type, 0, EINVAL, NULL, NULL},
89 	{&device, &mntpoint, &null, 0, EINVAL, NULL, NULL},
90 	{&device, &mntpoint, &fs_type, MS_REMOUNT, EINVAL, NULL, NULL},
91 	{&fault, &mntpoint, &fs_type, 0, EFAULT, NULL, NULL},
92 	{&device, &mntpoint, &fault, 0, EFAULT, NULL, NULL},
93 	{&device, &long_path, &fs_type, 0, ENAMETOOLONG, NULL, NULL},
94 	{&device, &nonexistent, &fs_type, 0, ENOENT, NULL, NULL},
95 	{&device, &file, &fs_type, 0, ENOTDIR, NULL, NULL},
96 };
97 
98 int TST_TOTAL = ARRAY_SIZE(tc);
99 
verify_mount(struct test_case * tc)100 static void verify_mount(struct test_case *tc)
101 {
102 	if (tc->setup)
103 		tc->setup();
104 
105 	TEST(mount(*tc->device, *tc->mntpoint, *tc->fs_type, tc->flag, NULL));
106 
107 	if (TEST_RETURN != -1) {
108 		tst_resm(TFAIL, "mount() succeded unexpectedly (ret=%li)",
109 		         TEST_RETURN);
110 		goto cleanup;
111 	}
112 
113 	if (TEST_ERRNO != tc->exp_errno) {
114 		tst_resm(TFAIL | TTERRNO,
115 		         "mount() was expected to fail with %s(%i)",
116 		         tst_strerrno(tc->exp_errno), tc->exp_errno);
117 		goto cleanup;
118 	}
119 
120 	tst_resm(TPASS | TTERRNO, "mount() failed expectedly");
121 
122 cleanup:
123 	if (tc->cleanup)
124 		tc->cleanup();
125 }
126 
main(int ac,char ** av)127 int main(int ac, char **av)
128 {
129 	int lc, i;
130 
131 	tst_parse_opts(ac, av, NULL, NULL);
132 
133 	setup();
134 
135 	for (lc = 0; TEST_LOOPING(lc); lc++) {
136 		tst_count = 0;
137 
138 		for (i = 0; i < TST_TOTAL; ++i)
139 			verify_mount(tc + i);
140 	}
141 
142 	cleanup();
143 	tst_exit();
144 }
145 
do_mount(void)146 static void do_mount(void)
147 {
148 	if (mount(device, mntpoint, fs_type, 0, NULL))
149 		tst_brkm(TBROK | TERRNO, cleanup, "Failed to mount(mntpoint)");
150 }
151 
mount_open(void)152 static void mount_open(void)
153 {
154 	do_mount();
155 
156 	fd = SAFE_OPEN(cleanup, "mntpoint/file", O_CREAT | O_RDWR, S_IRWXU);
157 }
158 
close_umount(void)159 static void close_umount(void)
160 {
161 	SAFE_CLOSE(cleanup, fd);
162 	do_umount();
163 }
164 
do_umount(void)165 static void do_umount(void)
166 {
167 	if (tst_umount(mntpoint))
168 		tst_brkm(TBROK | TERRNO, cleanup, "Failed to umount(mntpoint)");
169 }
170 
setup(void)171 static void setup(void)
172 {
173 	dev_t dev;
174 
175 	tst_sig(FORK, DEF_HANDLER, cleanup);
176 
177 	tst_require_root();
178 
179 	tst_tmpdir();
180 
181 	SAFE_TOUCH(cleanup, file, FILE_MODE, NULL);
182 
183 	fs_type = tst_dev_fs_type();
184 	device = tst_acquire_device(cleanup);
185 
186 	if (!device)
187 		tst_brkm(TCONF, cleanup, "Failed to obtain block device");
188 
189 	tst_mkfs(cleanup, device, fs_type, NULL, NULL);
190 
191 	SAFE_MKDIR(cleanup, mntpoint, DIR_MODE);
192 
193 	memset(path, 'a', PATH_MAX + 1);
194 
195 	dev = makedev(1, 3);
196 	if (mknod(char_dev, S_IFCHR | FILE_MODE, dev)) {
197 		tst_brkm(TBROK | TERRNO, cleanup,
198 			 "failed to mknod(char_dev, S_IFCHR | FILE_MODE, %lu)",
199 			 dev);
200 	}
201 
202 	TEST_PAUSE;
203 }
204 
cleanup(void)205 static void cleanup(void)
206 {
207 	if (device)
208 		tst_release_device(device);
209 
210 	tst_rmdir();
211 }
212