robbiew | 1d89ad5 | 2006-01-31 15:12:47 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) Wipro Technologies Ltd, 2002. All Rights Reserved. |
Cyril Hrubis | 0a1c828 | 2014-06-30 13:42:10 +0200 | [diff] [blame] | 3 | * AUTHOR: Nirmala Devi Dhanasekar <nirmala.devi@wipro.com> |
| 4 | * Copyright (c) 2014 Cyril Hrubis <chrubis@suse.cz> |
robbiew | 1d89ad5 | 2006-01-31 15:12:47 +0000 | [diff] [blame] | 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 |
Wanlong Gao | fed9641 | 2012-10-24 10:10:29 +0800 | [diff] [blame] | 15 | * with this program; if not, write the Free Software Foundation, Inc., |
| 16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
robbiew | 1d89ad5 | 2006-01-31 15:12:47 +0000 | [diff] [blame] | 17 | * |
| 18 | */ |
DAN LI | 61fbe0c | 2013-04-26 15:50:54 +0800 | [diff] [blame] | 19 | |
| 20 | /* |
DAN LI | 61fbe0c | 2013-04-26 15:50:54 +0800 | [diff] [blame] | 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. |
DAN LI | 61fbe0c | 2013-04-26 15:50:54 +0800 | [diff] [blame] | 38 | */ |
robbiew | 1d89ad5 | 2006-01-31 15:12:47 +0000 | [diff] [blame] | 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" |
Cyril Hrubis | 0a1c828 | 2014-06-30 13:42:10 +0200 | [diff] [blame] | 46 | #include "safe_macros.h" |
robbiew | 1d89ad5 | 2006-01-31 15:12:47 +0000 | [diff] [blame] | 47 | |
robbiew | 1d89ad5 | 2006-01-31 15:12:47 +0000 | [diff] [blame] | 48 | static void setup(void); |
| 49 | static void cleanup(void); |
| 50 | |
Cyril Hrubis | fdce7d5 | 2013-04-04 18:35:48 +0200 | [diff] [blame] | 51 | char *TCID = "mount02"; |
robbiew | 1d89ad5 | 2006-01-31 15:12:47 +0000 | [diff] [blame] | 52 | |
DAN LI | 61fbe0c | 2013-04-26 15:50:54 +0800 | [diff] [blame] | 53 | #define DIR_MODE (S_IRWXU | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP) |
| 54 | #define FILE_MODE (S_IRWXU | S_IRWXG | S_IRWXO) |
robbiew | 1d89ad5 | 2006-01-31 15:12:47 +0000 | [diff] [blame] | 55 | |
Cyril Hrubis | 0a1c828 | 2014-06-30 13:42:10 +0200 | [diff] [blame] | 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"; |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 67 | static int fd; |
Cyril Hrubis | 0a1c828 | 2014-06-30 13:42:10 +0200 | [diff] [blame] | 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); |
robbiew | 1d89ad5 | 2006-01-31 15:12:47 +0000 | [diff] [blame] | 99 | |
Cyril Hrubis | 0a1c828 | 2014-06-30 13:42:10 +0200 | [diff] [blame] | 100 | static void verify_mount(struct test_case *tc) |
| 101 | { |
| 102 | if (tc->setup) |
| 103 | tc->setup(); |
Garrett Cooper | 2ddcc1b | 2010-12-13 20:47:00 -0800 | [diff] [blame] | 104 | |
Cyril Hrubis | 0a1c828 | 2014-06-30 13:42:10 +0200 | [diff] [blame] | 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 | } |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 126 | |
| 127 | int main(int ac, char **av) |
robbiew | 1d89ad5 | 2006-01-31 15:12:47 +0000 | [diff] [blame] | 128 | { |
Cyril Hrubis | 89af32a | 2012-10-24 16:39:11 +0200 | [diff] [blame] | 129 | int lc, i; |
Cyril Hrubis | 0b9589f | 2014-05-27 17:40:33 +0200 | [diff] [blame] | 130 | const char *msg; |
robbiew | 1d89ad5 | 2006-01-31 15:12:47 +0000 | [diff] [blame] | 131 | |
Cyril Hrubis | 0a1c828 | 2014-06-30 13:42:10 +0200 | [diff] [blame] | 132 | msg = parse_opts(ac, av, NULL, NULL); |
DAN LI | 61fbe0c | 2013-04-26 15:50:54 +0800 | [diff] [blame] | 133 | if (msg != NULL) |
robbiew | 1d89ad5 | 2006-01-31 15:12:47 +0000 | [diff] [blame] | 134 | tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); |
robbiew | 1d89ad5 | 2006-01-31 15:12:47 +0000 | [diff] [blame] | 135 | |
robbiew | 1d89ad5 | 2006-01-31 15:12:47 +0000 | [diff] [blame] | 136 | setup(); |
| 137 | |
robbiew | 1d89ad5 | 2006-01-31 15:12:47 +0000 | [diff] [blame] | 138 | for (lc = 0; TEST_LOOPING(lc); lc++) { |
Caspar Zhang | d59a659 | 2013-03-07 14:59:12 +0800 | [diff] [blame] | 139 | tst_count = 0; |
robbiew | 1d89ad5 | 2006-01-31 15:12:47 +0000 | [diff] [blame] | 140 | |
Cyril Hrubis | 0a1c828 | 2014-06-30 13:42:10 +0200 | [diff] [blame] | 141 | for (i = 0; i < TST_TOTAL; ++i) |
| 142 | verify_mount(tc + i); |
Garrett Cooper | 2c28215 | 2010-12-16 00:55:50 -0800 | [diff] [blame] | 143 | } |
robbiew | 1d89ad5 | 2006-01-31 15:12:47 +0000 | [diff] [blame] | 144 | |
robbiew | 1d89ad5 | 2006-01-31 15:12:47 +0000 | [diff] [blame] | 145 | cleanup(); |
Garrett Cooper | 2ddcc1b | 2010-12-13 20:47:00 -0800 | [diff] [blame] | 146 | tst_exit(); |
Garrett Cooper | 2c28215 | 2010-12-16 00:55:50 -0800 | [diff] [blame] | 147 | } |
robbiew | 1d89ad5 | 2006-01-31 15:12:47 +0000 | [diff] [blame] | 148 | |
Cyril Hrubis | 0a1c828 | 2014-06-30 13:42:10 +0200 | [diff] [blame] | 149 | static void do_mount(void) |
robbiew | 1d89ad5 | 2006-01-31 15:12:47 +0000 | [diff] [blame] | 150 | { |
Cyril Hrubis | 0a1c828 | 2014-06-30 13:42:10 +0200 | [diff] [blame] | 151 | if (mount(device, mntpoint, fs_type, 0, NULL)) |
| 152 | tst_brkm(TBROK | TERRNO, cleanup, "Failed to mount(mntpoint)"); |
robbiew | 1d89ad5 | 2006-01-31 15:12:47 +0000 | [diff] [blame] | 153 | } |
| 154 | |
Cyril Hrubis | 0a1c828 | 2014-06-30 13:42:10 +0200 | [diff] [blame] | 155 | static void mount_open(void) |
robbiew | 1d89ad5 | 2006-01-31 15:12:47 +0000 | [diff] [blame] | 156 | { |
Cyril Hrubis | 0a1c828 | 2014-06-30 13:42:10 +0200 | [diff] [blame] | 157 | do_mount(); |
| 158 | |
| 159 | fd = SAFE_OPEN(cleanup, "mntpoint/file", O_CREAT | O_RDWR, S_IRWXU); |
| 160 | } |
| 161 | |
| 162 | static void close_umount(void) |
| 163 | { |
| 164 | SAFE_CLOSE(cleanup, fd); |
| 165 | do_umount(); |
| 166 | } |
| 167 | |
| 168 | static void do_umount(void) |
| 169 | { |
Cyril Hrubis | c60a230 | 2015-01-29 16:28:24 +0100 | [diff] [blame] | 170 | if (tst_umount(mntpoint)) |
Cyril Hrubis | 0a1c828 | 2014-06-30 13:42:10 +0200 | [diff] [blame] | 171 | tst_brkm(TBROK | TERRNO, cleanup, "Failed to umount(mntpoint)"); |
robbiew | 1d89ad5 | 2006-01-31 15:12:47 +0000 | [diff] [blame] | 172 | } |
robbiew | 1d89ad5 | 2006-01-31 15:12:47 +0000 | [diff] [blame] | 173 | |
DAN LI | 61fbe0c | 2013-04-26 15:50:54 +0800 | [diff] [blame] | 174 | static void setup(void) |
robbiew | 1d89ad5 | 2006-01-31 15:12:47 +0000 | [diff] [blame] | 175 | { |
robbiew | 1d89ad5 | 2006-01-31 15:12:47 +0000 | [diff] [blame] | 176 | tst_sig(FORK, DEF_HANDLER, cleanup); |
| 177 | |
Garrett Cooper | 5374050 | 2010-12-16 00:04:01 -0800 | [diff] [blame] | 178 | tst_require_root(NULL); |
robbiew | 1d89ad5 | 2006-01-31 15:12:47 +0000 | [diff] [blame] | 179 | |
robbiew | 1d89ad5 | 2006-01-31 15:12:47 +0000 | [diff] [blame] | 180 | tst_tmpdir(); |
| 181 | |
Cyril Hrubis | 0a1c828 | 2014-06-30 13:42:10 +0200 | [diff] [blame] | 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); |
| 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 | } |
robbiew | 1d89ad5 | 2006-01-31 15:12:47 +0000 | [diff] [blame] | 200 | |
robbiew | 1d89ad5 | 2006-01-31 15:12:47 +0000 | [diff] [blame] | 201 | TEST_PAUSE; |
Garrett Cooper | 2c28215 | 2010-12-16 00:55:50 -0800 | [diff] [blame] | 202 | } |
robbiew | 1d89ad5 | 2006-01-31 15:12:47 +0000 | [diff] [blame] | 203 | |
DAN LI | 61fbe0c | 2013-04-26 15:50:54 +0800 | [diff] [blame] | 204 | static void cleanup(void) |
robbiew | 1d89ad5 | 2006-01-31 15:12:47 +0000 | [diff] [blame] | 205 | { |
Cyril Hrubis | 0a1c828 | 2014-06-30 13:42:10 +0200 | [diff] [blame] | 206 | if (device) |
| 207 | tst_release_device(NULL, device); |
| 208 | |
| 209 | tst_rmdir(); |
Chris Dearman | ec6edca | 2012-10-17 19:54:01 -0700 | [diff] [blame] | 210 | } |