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