1 /*
2 * Copyright (c) Wipro Technologies Ltd, 2002. All Rights Reserved.
3 * Copyright (c) 2014 Cyril Hrubis <chrubis@suse.cz>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16 *
17 * AUTHOR : Nirmala Devi Dhanasekar <nirmala.devi@wipro.com>
18 *
19 * DESCRIPTION
20 * Check for basic errors returned by umount(2) system call.
21 *
22 * Verify that umount(2) returns -1 and sets errno to
23 *
24 * 1) EBUSY if it cannot be umounted, because dir is still busy.
25 * 2) EFAULT if specialfile or device file points to invalid address space.
26 * 3) ENOENT if pathname was empty or has a nonexistent component.
27 * 4) EINVAL if specialfile or device is invalid or not a mount point.
28 * 5) ENAMETOOLONG if pathname was longer than MAXPATHLEN.
29 *****************************************************************************/
30
31 #include <errno.h>
32 #include <sys/mount.h>
33 #include <sys/types.h>
34 #include <sys/stat.h>
35 #include <sys/fcntl.h>
36 #include <pwd.h>
37
38 #include "test.h"
39 #include "safe_macros.h"
40
41 static void setup(void);
42 static void cleanup(void);
43
44 char *TCID = "umount02";
45
46 #define DIR_MODE S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH
47 #define FILE_MODE S_IRWXU | S_IRWXG | S_IRWXO
48 #define MNTPOINT "mntpoint"
49
50 static char long_path[PATH_MAX + 2];
51 static int mount_flag;
52 static int fd;
53
54 static const char *device;
55
56 static struct test_case_t {
57 char *err_desc;
58 char *mntpoint;
59 int exp_errno;
60 char *exp_retval;
61 } testcases[] = {
62 {"Already mounted/busy", MNTPOINT, EBUSY, "EBUSY"},
63 {"Invalid address space", NULL, EFAULT, "EFAULT"},
64 {"Directory not found", "nonexistent", ENOENT, "ENOENT"},
65 {"Invalid device", "./", EINVAL, "EINVAL"},
66 {"Pathname too long", long_path, ENAMETOOLONG, "ENAMETOOLONG"}
67 };
68
69 int TST_TOTAL = ARRAY_SIZE(testcases);
70
main(int ac,char ** av)71 int main(int ac, char **av)
72 {
73 int lc, i;
74
75 tst_parse_opts(ac, av, NULL, NULL);
76
77 setup();
78
79 for (lc = 0; TEST_LOOPING(lc); lc++) {
80 tst_count = 0;
81
82 for (i = 0; i < TST_TOTAL; ++i) {
83 TEST(umount(testcases[i].mntpoint));
84
85 if ((TEST_RETURN == -1) &&
86 (TEST_ERRNO == testcases[i].exp_errno)) {
87 tst_resm(TPASS, "umount(2) expected failure; "
88 "Got errno - %s : %s",
89 testcases[i].exp_retval,
90 testcases[i].err_desc);
91 } else {
92 tst_resm(TFAIL, "umount(2) failed to produce "
93 "expected error; %d, errno:%s got %d",
94 testcases[i].exp_errno,
95 testcases[i].exp_retval, TEST_ERRNO);
96 }
97 }
98 }
99
100 cleanup();
101 tst_exit();
102 }
103
setup(void)104 static void setup(void)
105 {
106 const char *fs_type;
107
108 tst_sig(FORK, DEF_HANDLER, cleanup);
109
110 tst_require_root();
111
112 tst_tmpdir();
113
114 fs_type = tst_dev_fs_type();
115 device = tst_acquire_device(cleanup);
116
117 if (!device)
118 tst_brkm(TCONF, cleanup, "Failed to obtain block device");
119
120 tst_mkfs(cleanup, device, fs_type, NULL, NULL);
121
122 memset(long_path, 'a', PATH_MAX + 1);
123
124 SAFE_MKDIR(cleanup, MNTPOINT, DIR_MODE);
125
126 if (mount(device, MNTPOINT, fs_type, 0, NULL))
127 tst_brkm(TBROK | TERRNO, cleanup, "mount() failed");
128 mount_flag = 1;
129
130 fd = SAFE_OPEN(cleanup, MNTPOINT "/file", O_CREAT | O_RDWR);
131
132 TEST_PAUSE;
133 }
134
cleanup(void)135 static void cleanup(void)
136 {
137 if (fd > 0 && close(fd))
138 tst_resm(TWARN | TERRNO, "Failed to close file");
139
140 if (mount_flag && tst_umount(MNTPOINT))
141 tst_resm(TWARN | TERRNO, "umount() failed");
142
143 if (device)
144 tst_release_device(device);
145
146 tst_rmdir();
147 }
148