this testcase checked event IN_UNMOUNT
IN_UNMOUNT File system containing watched object was unmounted and
check filesystem that it can't be unmounted if exist opened inotify
descriptor.

example of execution:

Running tests.......
inotify03    0  INFO  :  mount /dev/loop0 to mnt_694 fstype=ext3
inotify03    0  INFO  :  umount /dev/loop0
<<<test_start>>>
tag=inotify03 stime=1229332020
cmdline="inotify03 -D /dev/loop0 -T ext3"
contacts=""
analysis=exit
initiation_status="ok"
<<<test_output>>>
incrementing stop
inotify03    1  PASS  :  get event: wd=1 mask=2000 cookie=0 len=0
inotify03    2  PASS  :  get event: wd=1 mask=8000 cookie=0 len=0
inotify03    3  PASS  :  inotify_rm_watch (5, 1) return -1 errno=22 : Invalid 
argument
<<<execution_status>>>
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=0
<<<test_end>>>

kernel: Linux avagin 2.6.25-rc6 #1 SMP Tue Jul 8 13:42:51 MSD 2008 i686 
Intel(R) Celeron(R) CPU 2.53GHz GenuineIntel GNU/Linux
---
 runtest/syscalls                              |    1 +
 testcases/kernel/syscalls/inotify/inotify03.c |  378 +++++++++++++++++++++++++
 2 files changed, 379 insertions(+), 0 deletions(-)
 create mode 100644 testcases/kernel/syscalls/inotify/inotify03.c

diff --git a/runtest/syscalls b/runtest/syscalls
index 67c79c3..2b35f9a 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -411,6 +411,7 @@ ioctl03      ioctl03
 
 inotify01 inotify01
 inotify02 inotify02
+inotify03 inotify03 -D DEVICE -T DEVICE_FS_TYPE
 
 ioperm01 ioperm01
 ioperm02 ioperm02
diff --git a/testcases/kernel/syscalls/inotify/inotify03.c 
b/testcases/kernel/syscalls/inotify/inotify03.c
new file mode 100644
index 0000000..2761b88
--- /dev/null
+++ b/testcases/kernel/syscalls/inotify/inotify03.c
@@ -0,0 +1,378 @@
+/*
+ * Copyright (c) 2008 Parallels.  All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like.  Any license provided herein, whether implied or
+ * otherwise, applies only to this software file.  Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Started by Andrew Vagin <ava...@gmail.com>
+ *
+ */
+/*
+ * NAME
+ *     inotify03
+ *
+ * DESCRIPTION
+ *     Check that inotify get IN_UNMOUNT event and
+ *     don't block the umount command.
+ *
+ * ALGORITHM
+ *     Execute sequence file's operation and check return events
+ *
+ */
+
+#include <stdio.h>
+#include <sys/mount.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/syscall.h>
+#include <signal.h>
+#include "test.h"
+#include "usctest.h"
+
+#if defined(HAS_SYS_INOTIFY) && defined(__NR_inotify_init)
+#include <sys/inotify.h>
+
+#define EVENT_MAX 1024
+/* size of the event structure, not counting name */
+#define EVENT_SIZE (sizeof (struct inotify_event))
+/* reasonable guess as to size of 1024 events */
+#define EVENT_BUF_LEN          (EVENT_MAX * (EVENT_SIZE + 16))
+
+void help(void);
+void setup();
+void cleanup();
+
+char *TCID="inotify03";                /* Test program identifier.     */
+int TST_TOTAL = 3;             /* Total number of test cases. */
+extern int Tst_count;          /* Test Case counter for tst_* routines */
+
+#define BUF_SIZE 1024
+char fname[BUF_SIZE];
+char buf[BUF_SIZE];
+int fd, fd_notify;
+int wd;
+
+int event_set[EVENT_MAX];
+
+char event_buf[EVENT_BUF_LEN];
+
+static long myinotify_init()
+{
+       return syscall(__NR_inotify_init);
+}
+
+static long myinotify_add_watch(int fd, const char *pathname, int mask)
+{
+       return syscall(__NR_inotify_add_watch, fd, pathname, mask);
+}
+
+static long myinotify_rm_watch(int fd, int wd)
+{
+       return syscall(__NR_inotify_rm_watch, fd, wd);
+}
+
+#define DEFAULT_FSTYPE "ext2"
+#define DIR_MODE       S_IRWXU | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP
+
+static char *Fstype;
+static char mntpoint[20];
+static int mount_flag = 0;
+static char *fstype;
+static char *device;
+static int Tflag = 0;
+static int Dflag = 0;
+
+static option_t options[] = {          /* options supported by mount01 test */
+       { "T:", &Tflag, &fstype },      /* -T type of filesystem        */
+       { "D:", &Dflag, &device },      /* -D device used for mounting  */
+       { NULL, NULL, NULL }
+};
+
+int main(int ac, char **av){
+       char *msg;              /* message returned from parse_opts */
+       int ret;
+       int len, i, test_num;
+
+       /* parse standard options */
+       msg = parse_opts(ac, av, (option_t *) options, &help);
+       if ( msg != (char *) NULL )
+               tst_brkm(TBROK, cleanup, "OPTION PARSING ERROR - %s", msg);
+
+       /* Check for mandatory option of the testcase */
+       if (!Dflag) {
+               tst_brkm(TBROK, NULL, "You must specifiy the device used for "
+                       " mounting with -D option, Run '%s  -h' for option "
+                       " information.", TCID);
+               tst_exit();
+       }
+
+       if (Tflag) {
+               Fstype = (char *) malloc(strlen(fstype)+1);
+               if(Fstype == NULL) {
+                       tst_brkm(TBROK, NULL, "malloc - failed to alloc %d"
+                               "errno %d", strlen(fstype), errno);
+               }
+               strncpy(Fstype, fstype, strlen(fstype)+1);
+       } else {
+               Fstype = (char *) malloc(strlen(DEFAULT_FSTYPE)+1);
+               if(Fstype == NULL) {
+                       tst_brkm(TBROK, NULL, "malloc - failed to alloc %d"
+                               "errno %d", strlen(DEFAULT_FSTYPE), errno);
+               }
+               strncpy(Fstype, DEFAULT_FSTYPE, strlen(DEFAULT_FSTYPE)+1);
+       }
+
+       /* perform global setup for test */
+       setup();
+
+       Tst_count = 0;
+
+       event_set[Tst_count] = IN_UNMOUNT;
+       Tst_count++;
+       event_set[Tst_count] = IN_IGNORED;
+       Tst_count++;
+
+       /*check exit code from inotify_rm_watch*/
+       Tst_count++;
+
+       if (TST_TOTAL != Tst_count) {
+            tst_brkm(TBROK, cleanup,
+                    "TST_TOTAL and Tst_count are not equal");
+        }
+        Tst_count = 0;
+
+       tst_resm(TINFO, "umount %s", device);
+       TEST(umount(mntpoint));
+       if (TEST_RETURN != 0) {
+               TEST_ERROR_LOG(TEST_ERRNO);
+               tst_brkm(TBROK, cleanup, "umount(2) Failed "
+                       "while unmounting errno = %d : %s",
+                       TEST_ERRNO, strerror(TEST_ERRNO));
+       }
+       mount_flag = 0;
+
+       len = read(fd_notify, event_buf, EVENT_BUF_LEN);
+       if (len < 0) {
+               tst_brkm(TBROK, cleanup,
+                       "read(%d, buf, %d) Failed, errno=%d : %s",
+                       fd_notify, EVENT_BUF_LEN, errno,
+                       strerror(errno));
+       }
+
+       /* check events */
+       test_num = 0;
+       i = 0;
+       while (i < len) {
+               struct inotify_event *event;
+               event = (struct inotify_event *) &event_buf[i];
+               if (test_num >= (TST_TOTAL - 1)) {
+                       tst_resm(TINFO,
+                               "get unnecessary event: wd=%d mask=%x "
+                               "cookie=%u len=%u",
+                               event->wd, event->mask,
+                               event->cookie, event->len);
+               } else if (event_set[test_num] == event->mask){
+                       tst_resm(TPASS, "get event: wd=%d mask=%x"
+                               " cookie=%u len=%u",
+                               event->wd, event->mask,
+                               event->cookie, event->len);
+
+               } else {
+                       tst_resm( TFAIL, "get event: wd=%d mask=%x "
+                               "(expected %x) cookie=%u len=%u",
+                               event->wd, event->mask,
+                               event_set[test_num],
+                               event->cookie, event->len);
+               }
+               test_num++;
+               i += EVENT_SIZE + event->len;
+       }
+       for (; test_num<TST_TOTAL - 1; test_num++){
+               tst_resm(TFAIL, "don't get event: mask=%x ",
+                               event_set[test_num]);
+
+       }
+       ret = myinotify_rm_watch(fd_notify, wd);
+       if (ret != -1 || errno != EINVAL)
+               tst_resm(TFAIL, "inotify_rm_watch (%d, %d) return %d "
+                       "errno=%d : %s (instead of %d)",
+                       fd_notify, wd, ret, errno, EINVAL, strerror(errno));
+       else
+               tst_resm(TPASS, "inotify_rm_watch (%d, %d) return %d "
+                       "errno=%d : %s",
+                       fd_notify, wd, ret, errno, strerror(errno));
+
+       /* cleanup and exit */
+       cleanup();
+
+       return 0;
+}      /* End main */
+
+/*
+ * setup() - performs all ONE TIME setup for this test.
+ */
+void setup()
+{
+       int ret;
+       /* capture signals */
+       tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+       /* Pause if that option was specified */
+       TEST_PAUSE;
+
+       /* make a temp directory and cd to it */
+       tst_tmpdir();
+
+       (void)sprintf(mntpoint, "mnt_%d", getpid());
+
+       if (mkdir(mntpoint, DIR_MODE) < 0) {
+               tst_brkm(TBROK, cleanup, "mkdir(%s, %#o) failed; "
+                       "errno = %d: %s", mntpoint, DIR_MODE, errno,
+                       strerror(errno));
+       }
+
+       /* Call mount(2) */
+       tst_resm(TINFO, "mount %s to %s fstype=%s", device, mntpoint, Fstype);
+       TEST(mount(device, mntpoint, Fstype, 0, NULL));
+
+       /* check return code */
+       if (TEST_RETURN != 0) {
+               TEST_ERROR_LOG(TEST_ERRNO);
+               tst_brkm(TBROK, cleanup, "mount(2) Failed errno = %d : %s",
+                       TEST_ERRNO, strerror(TEST_ERRNO));
+       }
+       mount_flag = 1;
+
+       sprintf(fname,"%s/tfile_%d", mntpoint, getpid());
+       fd = open(fname,O_RDWR|O_CREAT,0700);
+       if (fd == -1) {
+               tst_brkm(TBROK, cleanup,
+                       "open(%s, O_RDWR|O_CREAT,0700) Failed, errno=%d : %s",
+                       fname, errno, strerror(errno));
+       }
+
+       ret = write(fd, fname, 1);
+       if (ret == -1) {
+               tst_brkm(TBROK, cleanup,
+                               "write(%d, %s, 1) Failed, errno=%d : %s",
+                               fd, fname, errno, strerror(errno));
+       }
+
+       /* close the file we have open */
+       if (close(fd) == -1) {
+               tst_brkm(TBROK, cleanup,
+                               "close(%s) Failed, errno=%d : %s",
+                               fname, errno, strerror(errno));
+       }
+
+       fd_notify = myinotify_init();
+
+       if (fd_notify < 0) {
+               if( errno == ENOSYS ){
+                       tst_resm(TCONF, "inotify is not configured in this 
kernel.");
+                       tst_resm(TCONF, "Test will not run.");
+                       cleanup();
+                       tst_exit();
+               }else{
+                       tst_brkm(TBROK, cleanup,
+                               "inotify_init () Failed, errno=%d : %s",
+                               errno, strerror(errno));
+               }
+       }
+
+       wd = myinotify_add_watch (fd_notify, fname, IN_ALL_EVENTS);
+       if (wd < 0) {
+               tst_brkm(TBROK, cleanup,
+                               "inotify_add_watch (%d, %s, IN_ALL_EVENTS)"
+                               "Failed, errno=%d : %s",
+                               fd_notify, fname, errno, strerror(errno));
+       };
+
+}      /* End setup() */
+
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ *             completion or premature exit.
+ */
+void cleanup()
+{
+       free(Fstype);
+       if (close(fd_notify) == -1) {
+               tst_resm(TWARN, "close(%d) Failed, errno=%d : %s",
+                               fd_notify, errno, strerror(errno));
+       }
+
+       if (mount_flag) {
+               TEST(umount(mntpoint));
+               if (TEST_RETURN != 0) {
+                       TEST_ERROR_LOG(TEST_ERRNO);
+                       tst_resm(TWARN, "umount(2) Failed "
+                               "while unmounting errno = %d : %s",
+                               TEST_ERRNO, strerror(TEST_ERRNO));
+               }
+       }
+
+       /*
+        * print timing stats if that option was specified.
+        * print errno log if that option was specified.
+        */
+       TEST_CLEANUP;
+
+       /* Remove tmp dir and all files in it */
+       tst_rmdir();
+
+       /* exit with return code appropriate for results */
+       tst_exit();
+}      /* End cleanup() */
+
+/*
+ * issue a help message
+ */
+void help()
+{
+       printf("-T type : specifies the type of filesystem to be mounted."
+               " Default ext2. \n");
+       printf("-D device : device used for mounting \n");
+}
+
+#else
+
+char *TCID="inotify03";        /* Test program identifier.     */
+int TST_TOTAL = 0;             /* Total number of test cases. */
+
+int
+main()
+{
+#ifndef __NR_inotify_init
+       tst_resm(TWARN, "This test needs a kernel that has inotify syscall.");
+       tst_resm(TWARN, "Inotify syscall can be found at kernel 2.6.13 or 
higher.");
+       return 0;
+#endif
+#ifndef HAS_SYS_INOTIFY
+       tst_resm(TBROK, "can't find header sys/inotify.h");
+       return 1;
+#endif
+       return 0;
+}
+
+#endif
-- 
1.5.6.4


------------------------------------------------------------------------------
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list

Reply via email to