• Home
  • 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/sysmacros.h>
45 #include <fcntl.h>
46 #include "test.h"
47 #include "safe_macros.h"
48 
49 static void setup(void);
50 static void cleanup(void);
51 
52 char *TCID = "mount02";
53 
54 #define DIR_MODE	(S_IRWXU | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP)
55 #define FILE_MODE	(S_IRWXU | S_IRWXG | S_IRWXO)
56 
57 static char path[PATH_MAX + 2];
58 static const char *long_path = path;
59 static const char *fs_type;
60 static const char *wrong_fs_type = "error";
61 static const char *mntpoint = "mntpoint";
62 static const char *device;
63 static const char *null = NULL;
64 static const char *fault = (void*)-1;
65 static const char *nonexistent = "nonexistent";
66 static const char *char_dev = "char_device";
67 static const char *file = "filename";
68 static int fd;
69 
70 static void do_umount(void);
71 static void close_umount(void);
72 static void do_mount(void);
73 static void mount_open(void);
74 
75 static struct test_case {
76 	const char **device;
77 	const char **mntpoint;
78 	const char **fs_type;
79 	unsigned long flag;
80 	int exp_errno;
81 	void (*setup)(void);
82 	void (*cleanup)(void);
83 } tc[] = {
84 	{&device, &mntpoint, &wrong_fs_type, 0, ENODEV, NULL, NULL},
85 	{&char_dev, &mntpoint, &fs_type, 0, ENOTBLK, NULL, NULL},
86 	{&device, &mntpoint, &fs_type, 0, EBUSY, do_mount, do_umount},
87 	{&device, &mntpoint, &fs_type, MS_REMOUNT | MS_RDONLY, EBUSY,
88 	 mount_open, close_umount},
89 	{&null, &mntpoint, &fs_type, 0, EINVAL, NULL, NULL},
90 	{&device, &mntpoint, &null, 0, EINVAL, NULL, NULL},
91 	{&device, &mntpoint, &fs_type, MS_REMOUNT, EINVAL, NULL, NULL},
92 	{&fault, &mntpoint, &fs_type, 0, EFAULT, NULL, NULL},
93 	{&device, &mntpoint, &fault, 0, EFAULT, NULL, NULL},
94 	{&device, &long_path, &fs_type, 0, ENAMETOOLONG, NULL, NULL},
95 	{&device, &nonexistent, &fs_type, 0, ENOENT, NULL, NULL},
96 	{&device, &file, &fs_type, 0, ENOTDIR, NULL, NULL},
97 };
98 
99 int TST_TOTAL = ARRAY_SIZE(tc);
100 
verify_mount(struct test_case * tc)101 static void verify_mount(struct test_case *tc)
102 {
103 	if (tc->setup)
104 		tc->setup();
105 
106 	TEST(mount(*tc->device, *tc->mntpoint, *tc->fs_type, tc->flag, NULL));
107 
108 	if (TEST_RETURN != -1) {
109 		tst_resm(TFAIL, "mount() succeded unexpectedly (ret=%li)",
110 		         TEST_RETURN);
111 		goto cleanup;
112 	}
113 
114 	if (TEST_ERRNO != tc->exp_errno) {
115 		tst_resm(TFAIL | TTERRNO,
116 		         "mount() was expected to fail with %s(%i)",
117 		         tst_strerrno(tc->exp_errno), tc->exp_errno);
118 		goto cleanup;
119 	}
120 
121 	tst_resm(TPASS | TTERRNO, "mount() failed expectedly");
122 
123 cleanup:
124 	if (tc->cleanup)
125 		tc->cleanup();
126 }
127 
main(int ac,char ** av)128 int main(int ac, char **av)
129 {
130 	int lc, i;
131 
132 	tst_parse_opts(ac, av, NULL, NULL);
133 
134 	setup();
135 
136 	for (lc = 0; TEST_LOOPING(lc); lc++) {
137 		tst_count = 0;
138 
139 		for (i = 0; i < TST_TOTAL; ++i)
140 			verify_mount(tc + i);
141 	}
142 
143 	cleanup();
144 	tst_exit();
145 }
146 
do_mount(void)147 static void do_mount(void)
148 {
149 	if (mount(device, mntpoint, fs_type, 0, NULL))
150 		tst_brkm(TBROK | TERRNO, cleanup, "Failed to mount(mntpoint)");
151 }
152 
mount_open(void)153 static void mount_open(void)
154 {
155 	do_mount();
156 
157 	fd = SAFE_OPEN(cleanup, "mntpoint/file", O_CREAT | O_RDWR, S_IRWXU);
158 }
159 
close_umount(void)160 static void close_umount(void)
161 {
162 	SAFE_CLOSE(cleanup, fd);
163 	do_umount();
164 }
165 
do_umount(void)166 static void do_umount(void)
167 {
168 	if (tst_umount(mntpoint))
169 		tst_brkm(TBROK | TERRNO, cleanup, "Failed to umount(mntpoint)");
170 }
171 
setup(void)172 static void setup(void)
173 {
174 	dev_t dev;
175 
176 	tst_sig(FORK, DEF_HANDLER, cleanup);
177 
178 	tst_require_root();
179 
180 	tst_tmpdir();
181 
182 	SAFE_TOUCH(cleanup, file, FILE_MODE, NULL);
183 
184 	fs_type = tst_dev_fs_type();
185 	device = tst_acquire_device(cleanup);
186 
187 	if (!device)
188 		tst_brkm(TCONF, cleanup, "Failed to obtain block device");
189 
190 	tst_mkfs(cleanup, device, fs_type, NULL, NULL);
191 
192 	SAFE_MKDIR(cleanup, mntpoint, DIR_MODE);
193 
194 	memset(path, 'a', PATH_MAX + 1);
195 
196 	dev = makedev(1, 3);
197 	if (mknod(char_dev, S_IFCHR | FILE_MODE, dev)) {
198 		tst_brkm(TBROK | TERRNO, cleanup,
199 			 "failed to mknod(char_dev, S_IFCHR | FILE_MODE, %lu)",
200 			 dev);
201 	}
202 
203 	TEST_PAUSE;
204 }
205 
cleanup(void)206 static void cleanup(void)
207 {
208 	if (device)
209 		tst_release_device(device);
210 
211 	tst_rmdir();
212 }
213