blob: cffcfdfc11cc1dce7dc7852b6c54dddfd193afe1 [file] [log] [blame]
robbiew1d89ad52006-01-31 15:12:47 +00001/*
2 * Copyright (c) Wipro Technologies Ltd, 2002. All Rights Reserved.
Cyril Hrubis0a1c8282014-06-30 13:42:10 +02003 * AUTHOR: Nirmala Devi Dhanasekar <nirmala.devi@wipro.com>
4 * Copyright (c) 2014 Cyril Hrubis <chrubis@suse.cz>
robbiew1d89ad52006-01-31 15:12:47 +00005 *
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
Wanlong Gaofed96412012-10-24 10:10:29 +080015 * with this program; if not, write the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
robbiew1d89ad52006-01-31 15:12:47 +000017 *
18 */
DAN LI61fbe0c2013-04-26 15:50:54 +080019
20/*
DAN LI61fbe0c2013-04-26 15:50:54 +080021
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.
DAN LI61fbe0c2013-04-26 15:50:54 +080038*/
robbiew1d89ad52006-01-31 15:12:47 +000039
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"
Cyril Hrubis0a1c8282014-06-30 13:42:10 +020046#include "safe_macros.h"
robbiew1d89ad52006-01-31 15:12:47 +000047
robbiew1d89ad52006-01-31 15:12:47 +000048static void setup(void);
49static void cleanup(void);
50
Cyril Hrubisfdce7d52013-04-04 18:35:48 +020051char *TCID = "mount02";
robbiew1d89ad52006-01-31 15:12:47 +000052
DAN LI61fbe0c2013-04-26 15:50:54 +080053#define DIR_MODE (S_IRWXU | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP)
54#define FILE_MODE (S_IRWXU | S_IRWXG | S_IRWXO)
robbiew1d89ad52006-01-31 15:12:47 +000055
Cyril Hrubis0a1c8282014-06-30 13:42:10 +020056static char path[PATH_MAX + 2];
57static const char *long_path = path;
58static const char *fs_type;
59static const char *wrong_fs_type = "error";
60static const char *mntpoint = "mntpoint";
61static const char *device;
62static const char *null = NULL;
63static const char *fault = (void*)-1;
64static const char *nonexistent = "nonexistent";
65static const char *char_dev = "char_device";
66static const char *file = "filename";
subrata_modak56207ce2009-03-23 13:35:39 +000067static int fd;
Cyril Hrubis0a1c8282014-06-30 13:42:10 +020068
69static void do_umount(void);
70static void close_umount(void);
71static void do_mount(void);
72static void mount_open(void);
73
74static 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
98int TST_TOTAL = ARRAY_SIZE(tc);
robbiew1d89ad52006-01-31 15:12:47 +000099
Cyril Hrubis0a1c8282014-06-30 13:42:10 +0200100static void verify_mount(struct test_case *tc)
101{
102 if (tc->setup)
103 tc->setup();
Garrett Cooper2ddcc1b2010-12-13 20:47:00 -0800104
Cyril Hrubis0a1c8282014-06-30 13:42:10 +0200105 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
122cleanup:
123 if (tc->cleanup)
124 tc->cleanup();
125}
subrata_modak56207ce2009-03-23 13:35:39 +0000126
127int main(int ac, char **av)
robbiew1d89ad52006-01-31 15:12:47 +0000128{
Cyril Hrubis89af32a2012-10-24 16:39:11 +0200129 int lc, i;
Cyril Hrubis0b9589f2014-05-27 17:40:33 +0200130 const char *msg;
robbiew1d89ad52006-01-31 15:12:47 +0000131
Cyril Hrubis0a1c8282014-06-30 13:42:10 +0200132 msg = parse_opts(ac, av, NULL, NULL);
DAN LI61fbe0c2013-04-26 15:50:54 +0800133 if (msg != NULL)
robbiew1d89ad52006-01-31 15:12:47 +0000134 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
robbiew1d89ad52006-01-31 15:12:47 +0000135
robbiew1d89ad52006-01-31 15:12:47 +0000136 setup();
137
robbiew1d89ad52006-01-31 15:12:47 +0000138 for (lc = 0; TEST_LOOPING(lc); lc++) {
Caspar Zhangd59a6592013-03-07 14:59:12 +0800139 tst_count = 0;
robbiew1d89ad52006-01-31 15:12:47 +0000140
Cyril Hrubis0a1c8282014-06-30 13:42:10 +0200141 for (i = 0; i < TST_TOTAL; ++i)
142 verify_mount(tc + i);
Garrett Cooper2c282152010-12-16 00:55:50 -0800143 }
robbiew1d89ad52006-01-31 15:12:47 +0000144
robbiew1d89ad52006-01-31 15:12:47 +0000145 cleanup();
Garrett Cooper2ddcc1b2010-12-13 20:47:00 -0800146 tst_exit();
Garrett Cooper2c282152010-12-16 00:55:50 -0800147}
robbiew1d89ad52006-01-31 15:12:47 +0000148
Cyril Hrubis0a1c8282014-06-30 13:42:10 +0200149static void do_mount(void)
robbiew1d89ad52006-01-31 15:12:47 +0000150{
Cyril Hrubis0a1c8282014-06-30 13:42:10 +0200151 if (mount(device, mntpoint, fs_type, 0, NULL))
152 tst_brkm(TBROK | TERRNO, cleanup, "Failed to mount(mntpoint)");
robbiew1d89ad52006-01-31 15:12:47 +0000153}
154
Cyril Hrubis0a1c8282014-06-30 13:42:10 +0200155static void mount_open(void)
robbiew1d89ad52006-01-31 15:12:47 +0000156{
Cyril Hrubis0a1c8282014-06-30 13:42:10 +0200157 do_mount();
158
159 fd = SAFE_OPEN(cleanup, "mntpoint/file", O_CREAT | O_RDWR, S_IRWXU);
160}
161
162static void close_umount(void)
163{
164 SAFE_CLOSE(cleanup, fd);
165 do_umount();
166}
167
168static void do_umount(void)
169{
Cyril Hrubisc60a2302015-01-29 16:28:24 +0100170 if (tst_umount(mntpoint))
Cyril Hrubis0a1c8282014-06-30 13:42:10 +0200171 tst_brkm(TBROK | TERRNO, cleanup, "Failed to umount(mntpoint)");
robbiew1d89ad52006-01-31 15:12:47 +0000172}
robbiew1d89ad52006-01-31 15:12:47 +0000173
DAN LI61fbe0c2013-04-26 15:50:54 +0800174static void setup(void)
robbiew1d89ad52006-01-31 15:12:47 +0000175{
robbiew1d89ad52006-01-31 15:12:47 +0000176 tst_sig(FORK, DEF_HANDLER, cleanup);
177
Garrett Cooper53740502010-12-16 00:04:01 -0800178 tst_require_root(NULL);
robbiew1d89ad52006-01-31 15:12:47 +0000179
robbiew1d89ad52006-01-31 15:12:47 +0000180 tst_tmpdir();
181
Cyril Hrubis0a1c8282014-06-30 13:42:10 +0200182 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);
191
192 SAFE_MKDIR(cleanup, mntpoint, DIR_MODE);
193
194 memset(path, 'a', PATH_MAX + 1);
195
196 if (mknod(char_dev, S_IFCHR | FILE_MODE, 0)) {
197 tst_brkm(TBROK | TERRNO, cleanup,
198 "failed to mknod(char_dev, S_IFCHR | FILE_MODE, 0)");
199 }
robbiew1d89ad52006-01-31 15:12:47 +0000200
robbiew1d89ad52006-01-31 15:12:47 +0000201 TEST_PAUSE;
Garrett Cooper2c282152010-12-16 00:55:50 -0800202}
robbiew1d89ad52006-01-31 15:12:47 +0000203
DAN LI61fbe0c2013-04-26 15:50:54 +0800204static void cleanup(void)
robbiew1d89ad52006-01-31 15:12:47 +0000205{
Cyril Hrubis0a1c8282014-06-30 13:42:10 +0200206 if (device)
207 tst_release_device(NULL, device);
208
209 tst_rmdir();
Chris Dearmanec6edca2012-10-17 19:54:01 -0700210}