blob: bb68920d2b1aeb424fafca27a6bf8e511d21be89 [file] [log] [blame]
subrata_modakd0a9af02008-12-29 11:28:49 +00001/*
2 * Copyright (c) 2008 Parallels. All Rights Reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of version 2 of the GNU General Public License as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it would be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * Further, this software is distributed without any warranty that it is
13 * free of the rightful claim of any third person regarding infringement
14 * or the like. Any license provided herein, whether implied or
15 * otherwise, applies only to this software file. Patent licenses, if
16 * any, provided herein do not apply to combinations of this program with
17 * other software, or any other product whatsoever.
18 *
19 * You should have received a copy of the GNU General Public License along
Wanlong Gaofed96412012-10-24 10:10:29 +080020 * with this program; if not, write the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
subrata_modakd0a9af02008-12-29 11:28:49 +000022 *
23 * Started by Andrew Vagin <avagin@gmail.com>
24 *
subrata_modakd0a9af02008-12-29 11:28:49 +000025 * DESCRIPTION
26 * Check that inotify get IN_UNMOUNT event and
27 * don't block the umount command.
28 *
29 * ALGORITHM
30 * Execute sequence file's operation and check return events
31 *
32 */
subrata_modak91960512009-01-05 08:28:40 +000033#include "config.h"
subrata_modakd0a9af02008-12-29 11:28:49 +000034
35#include <stdio.h>
36#include <sys/mount.h>
37#include <sys/stat.h>
38#include <sys/types.h>
39#include <sys/fcntl.h>
40#include <errno.h>
41#include <string.h>
42#include <sys/syscall.h>
43#include <signal.h>
44#include "test.h"
Garrett Cooper53740502010-12-16 00:04:01 -080045#include "linux_syscall_numbers.h"
Garrett Cooper3bf3cb12012-05-20 10:51:55 -070046#include "inotify.h"
subrata_modakd0a9af02008-12-29 11:28:49 +000047
Cyril Hrubisedea6b42013-07-09 17:28:06 +020048char *TCID = "inotify03";
49int TST_TOTAL = 3;
50
Garrett Cooper53740502010-12-16 00:04:01 -080051#if defined(HAVE_SYS_INOTIFY_H)
subrata_modakd0a9af02008-12-29 11:28:49 +000052#include <sys/inotify.h>
53
54#define EVENT_MAX 1024
55/* size of the event structure, not counting name */
DAN LI4a7d9752013-07-16 11:09:10 +080056#define EVENT_SIZE (sizeof(struct inotify_event))
subrata_modakd0a9af02008-12-29 11:28:49 +000057/* reasonable guess as to size of 1024 events */
58#define EVENT_BUF_LEN (EVENT_MAX * (EVENT_SIZE + 16))
59
Cyril Hrubisedea6b42013-07-09 17:28:06 +020060static void setup(void);
61static void cleanup(void);
subrata_modakd0a9af02008-12-29 11:28:49 +000062
63#define BUF_SIZE 1024
Cyril Hrubis26aa0a82013-08-08 14:58:42 +020064static char fname[BUF_SIZE];
65static int fd, fd_notify;
66static int wd;
subrata_modakd0a9af02008-12-29 11:28:49 +000067
Cyril Hrubis26aa0a82013-08-08 14:58:42 +020068static int event_set[EVENT_MAX];
subrata_modakd0a9af02008-12-29 11:28:49 +000069
Cyril Hrubis26aa0a82013-08-08 14:58:42 +020070static char event_buf[EVENT_BUF_LEN];
subrata_modakd0a9af02008-12-29 11:28:49 +000071
DAN LI4a7d9752013-07-16 11:09:10 +080072#define DIR_MODE (S_IRWXU | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP)
subrata_modakd0a9af02008-12-29 11:28:49 +000073
Cyril Hrubis26aa0a82013-08-08 14:58:42 +020074static char *mntpoint = "mntpoint";
DAN LI4a7d9752013-07-16 11:09:10 +080075static int mount_flag;
Cyril Hrubisf8bf8652014-06-19 16:57:53 +020076static const char *device;
77static const char *fs_type;
subrata_modakd0a9af02008-12-29 11:28:49 +000078
DAN LI4a7d9752013-07-16 11:09:10 +080079int main(int argc, char *argv[])
subrata_modak56207ce2009-03-23 13:35:39 +000080{
Cyril Hrubis0b9589f2014-05-27 17:40:33 +020081 const char *msg;
subrata_modakd0a9af02008-12-29 11:28:49 +000082 int ret;
83 int len, i, test_num;
84
Cyril Hrubisf8bf8652014-06-19 16:57:53 +020085 msg = parse_opts(argc, argv, NULL, NULL);
DAN LI4a7d9752013-07-16 11:09:10 +080086 if (msg != NULL)
Garrett Cooper60fa8012010-11-22 13:50:58 -080087 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
subrata_modakd0a9af02008-12-29 11:28:49 +000088
subrata_modakd0a9af02008-12-29 11:28:49 +000089 setup();
90
Caspar Zhangd59a6592013-03-07 14:59:12 +080091 tst_count = 0;
subrata_modakd0a9af02008-12-29 11:28:49 +000092
Caspar Zhangd59a6592013-03-07 14:59:12 +080093 event_set[tst_count] = IN_UNMOUNT;
94 tst_count++;
95 event_set[tst_count] = IN_IGNORED;
96 tst_count++;
subrata_modakd0a9af02008-12-29 11:28:49 +000097
subrata_modak56207ce2009-03-23 13:35:39 +000098 /*check exit code from inotify_rm_watch */
Caspar Zhangd59a6592013-03-07 14:59:12 +080099 tst_count++;
subrata_modakd0a9af02008-12-29 11:28:49 +0000100
Caspar Zhangd59a6592013-03-07 14:59:12 +0800101 if (TST_TOTAL != tst_count) {
subrata_modak56207ce2009-03-23 13:35:39 +0000102 tst_brkm(TBROK, cleanup,
Caspar Zhangd59a6592013-03-07 14:59:12 +0800103 "TST_TOTAL and tst_count are not equal");
subrata_modak56207ce2009-03-23 13:35:39 +0000104 }
Caspar Zhangd59a6592013-03-07 14:59:12 +0800105 tst_count = 0;
subrata_modakd0a9af02008-12-29 11:28:49 +0000106
107 tst_resm(TINFO, "umount %s", device);
Cyril Hrubisc60a2302015-01-29 16:28:24 +0100108 TEST(tst_umount(mntpoint));
subrata_modakd0a9af02008-12-29 11:28:49 +0000109 if (TEST_RETURN != 0) {
subrata_modakd0a9af02008-12-29 11:28:49 +0000110 tst_brkm(TBROK, cleanup, "umount(2) Failed "
subrata_modak56207ce2009-03-23 13:35:39 +0000111 "while unmounting errno = %d : %s",
112 TEST_ERRNO, strerror(TEST_ERRNO));
subrata_modakd0a9af02008-12-29 11:28:49 +0000113 }
114 mount_flag = 0;
115
116 len = read(fd_notify, event_buf, EVENT_BUF_LEN);
117 if (len < 0) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800118 tst_brkm(TBROK | TERRNO, cleanup,
119 "read(%d, buf, %zu) failed", fd_notify, EVENT_BUF_LEN);
subrata_modakd0a9af02008-12-29 11:28:49 +0000120 }
121
122 /* check events */
123 test_num = 0;
124 i = 0;
125 while (i < len) {
126 struct inotify_event *event;
subrata_modak56207ce2009-03-23 13:35:39 +0000127 event = (struct inotify_event *)&event_buf[i];
subrata_modakd0a9af02008-12-29 11:28:49 +0000128 if (test_num >= (TST_TOTAL - 1)) {
subrata_modak4babec72008-12-29 11:30:14 +0000129 tst_resm(TFAIL,
subrata_modak56207ce2009-03-23 13:35:39 +0000130 "get unnecessary event: wd=%d mask=%x "
131 "cookie=%u len=%u",
132 event->wd, event->mask,
133 event->cookie, event->len);
134 } else if (event_set[test_num] == event->mask) {
subrata_modakd0a9af02008-12-29 11:28:49 +0000135 tst_resm(TPASS, "get event: wd=%d mask=%x"
subrata_modak56207ce2009-03-23 13:35:39 +0000136 " cookie=%u len=%u",
137 event->wd, event->mask,
138 event->cookie, event->len);
subrata_modakd0a9af02008-12-29 11:28:49 +0000139
140 } else {
subrata_modak56207ce2009-03-23 13:35:39 +0000141 tst_resm(TFAIL, "get event: wd=%d mask=%x "
142 "(expected %x) cookie=%u len=%u",
143 event->wd, event->mask,
144 event_set[test_num],
145 event->cookie, event->len);
subrata_modakd0a9af02008-12-29 11:28:49 +0000146 }
147 test_num++;
148 i += EVENT_SIZE + event->len;
149 }
subrata_modak56207ce2009-03-23 13:35:39 +0000150 for (; test_num < TST_TOTAL - 1; test_num++) {
subrata_modakd0a9af02008-12-29 11:28:49 +0000151 tst_resm(TFAIL, "don't get event: mask=%x ",
subrata_modak56207ce2009-03-23 13:35:39 +0000152 event_set[test_num]);
subrata_modakd0a9af02008-12-29 11:28:49 +0000153
154 }
155 ret = myinotify_rm_watch(fd_notify, wd);
156 if (ret != -1 || errno != EINVAL)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800157 tst_resm(TFAIL | TERRNO,
158 "inotify_rm_watch (%d, %d) didn't return EINVAL",
159 fd_notify, wd);
subrata_modakd0a9af02008-12-29 11:28:49 +0000160 else
Garrett Cooper045b2222010-11-22 15:34:12 -0800161 tst_resm(TPASS, "inotify_rm_watch (%d, %d) returned EINVAL",
Wanlong Gao354ebb42012-12-07 10:10:04 +0800162 fd_notify, wd);
subrata_modakd0a9af02008-12-29 11:28:49 +0000163
subrata_modakd0a9af02008-12-29 11:28:49 +0000164 cleanup();
Garrett Cooperddc4c0d2010-11-22 15:05:35 -0800165 tst_exit();
Garrett Cooper2c282152010-12-16 00:55:50 -0800166}
subrata_modakd0a9af02008-12-29 11:28:49 +0000167
Cyril Hrubisedea6b42013-07-09 17:28:06 +0200168static void setup(void)
subrata_modakd0a9af02008-12-29 11:28:49 +0000169{
170 int ret;
Garrett Cooper2c282152010-12-16 00:55:50 -0800171
subrata_modakd0a9af02008-12-29 11:28:49 +0000172 tst_sig(NOFORK, DEF_HANDLER, cleanup);
173
subrata_modakd0a9af02008-12-29 11:28:49 +0000174 TEST_PAUSE;
175
Cyril Hrubisf8bf8652014-06-19 16:57:53 +0200176 fs_type = tst_dev_fs_type();
177
subrata_modakd0a9af02008-12-29 11:28:49 +0000178 tst_tmpdir();
179
Cyril Hrubisf8bf8652014-06-19 16:57:53 +0200180 device = tst_acquire_device(cleanup);
181 if (!device)
182 tst_brkm(TCONF, cleanup, "Failed to obtain block device");
183
184 tst_mkfs(cleanup, device, fs_type, NULL);
185
subrata_modakd0a9af02008-12-29 11:28:49 +0000186 if (mkdir(mntpoint, DIR_MODE) < 0) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800187 tst_brkm(TBROK | TERRNO, cleanup, "mkdir(%s, %#o) failed",
188 mntpoint, DIR_MODE);
subrata_modakd0a9af02008-12-29 11:28:49 +0000189 }
190
191 /* Call mount(2) */
Cyril Hrubisf8bf8652014-06-19 16:57:53 +0200192 tst_resm(TINFO, "mount %s to %s fs_type=%s", device, mntpoint, fs_type);
193 TEST(mount(device, mntpoint, fs_type, 0, NULL));
subrata_modakd0a9af02008-12-29 11:28:49 +0000194
195 /* check return code */
196 if (TEST_RETURN != 0) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800197 tst_brkm(TBROK | TTERRNO, cleanup, "mount(2) failed");
subrata_modakd0a9af02008-12-29 11:28:49 +0000198 }
199 mount_flag = 1;
200
subrata_modak56207ce2009-03-23 13:35:39 +0000201 sprintf(fname, "%s/tfile_%d", mntpoint, getpid());
202 fd = open(fname, O_RDWR | O_CREAT, 0700);
subrata_modakd0a9af02008-12-29 11:28:49 +0000203 if (fd == -1) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800204 tst_brkm(TBROK | TERRNO, cleanup,
205 "open(%s, O_RDWR|O_CREAT,0700) failed", fname);
subrata_modakd0a9af02008-12-29 11:28:49 +0000206 }
207
208 ret = write(fd, fname, 1);
209 if (ret == -1) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800210 tst_brkm(TBROK | TERRNO, cleanup,
211 "write(%d, %s, 1) failed", fd, fname);
subrata_modakd0a9af02008-12-29 11:28:49 +0000212 }
213
214 /* close the file we have open */
DAN LI4a7d9752013-07-16 11:09:10 +0800215 if (close(fd) == -1)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800216 tst_brkm(TBROK | TERRNO, cleanup, "close(%s) failed", fname);
subrata_modakd0a9af02008-12-29 11:28:49 +0000217
218 fd_notify = myinotify_init();
219
220 if (fd_notify < 0) {
DAN LI4a7d9752013-07-16 11:09:10 +0800221 if (errno == ENOSYS)
Garrett Cooperddc4c0d2010-11-22 15:05:35 -0800222 tst_brkm(TCONF, cleanup,
subrata_modak56207ce2009-03-23 13:35:39 +0000223 "inotify is not configured in this kernel.");
DAN LI4a7d9752013-07-16 11:09:10 +0800224 else
Wanlong Gao354ebb42012-12-07 10:10:04 +0800225 tst_brkm(TBROK | TERRNO, cleanup,
226 "inotify_init failed");
subrata_modakd0a9af02008-12-29 11:28:49 +0000227 }
228
subrata_modak56207ce2009-03-23 13:35:39 +0000229 wd = myinotify_add_watch(fd_notify, fname, IN_ALL_EVENTS);
DAN LI4a7d9752013-07-16 11:09:10 +0800230 if (wd < 0)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800231 tst_brkm(TBROK | TERRNO, cleanup,
Garrett Cooperddc4c0d2010-11-22 15:05:35 -0800232 "inotify_add_watch (%d, %s, IN_ALL_EVENTS) failed.",
233 fd_notify, fname);
Garrett Cooper2c282152010-12-16 00:55:50 -0800234}
subrata_modakd0a9af02008-12-29 11:28:49 +0000235
Cyril Hrubisedea6b42013-07-09 17:28:06 +0200236static void cleanup(void)
subrata_modakd0a9af02008-12-29 11:28:49 +0000237{
Cyril Hrubisf8bf8652014-06-19 16:57:53 +0200238 if (fd_notify > 0 && close(fd_notify) == -1)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800239 tst_resm(TWARN | TERRNO, "close(%d) failed", fd_notify);
subrata_modakd0a9af02008-12-29 11:28:49 +0000240
241 if (mount_flag) {
Cyril Hrubisc60a2302015-01-29 16:28:24 +0100242 TEST(tst_umount(mntpoint));
DAN LI4a7d9752013-07-16 11:09:10 +0800243 if (TEST_RETURN != 0)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800244 tst_resm(TWARN | TTERRNO, "umount(%s) failed",
245 mntpoint);
subrata_modakd0a9af02008-12-29 11:28:49 +0000246 }
247
Cyril Hrubisf8bf8652014-06-19 16:57:53 +0200248 tst_release_device(NULL, device);
249
subrata_modakd0a9af02008-12-29 11:28:49 +0000250 tst_rmdir();
Garrett Cooper2c282152010-12-16 00:55:50 -0800251}
subrata_modakd0a9af02008-12-29 11:28:49 +0000252
subrata_modakd0a9af02008-12-29 11:28:49 +0000253#else
254
Cyril Hrubisedea6b42013-07-09 17:28:06 +0200255int main(void)
subrata_modakd0a9af02008-12-29 11:28:49 +0000256{
Garrett Cooper53740502010-12-16 00:04:01 -0800257 tst_brkm(TCONF, NULL, "system doesn't have required inotify support");
subrata_modakd0a9af02008-12-29 11:28:49 +0000258}
259
Markos Chandrasf4539c62012-01-03 09:41:10 +0000260#endif