Hi,
--- On Mon, 12/22/08, Andrew Vagin <ava...@gmail.com> wrote: > From: Andrew Vagin <ava...@gmail.com> > Subject: [LTP] [PATCH] add new testcase for check inotify subsytem. > To: subr...@linux.vnet.ibm.com > Cc: ltp-list@lists.sourceforge.net > Date: Monday, December 22, 2008, 3:14 PM > 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 > The problem here is that this test case requires too many human setup, so it should not in default run. It will cause a regression that the previous working command line is broken here. Please automate those in a script. For example, mount a loop device, and set some good default values. CAI Qian > 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 ------------------------------------------------------------------------------ _______________________________________________ Ltp-list mailing list Ltp-list@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/ltp-list