Hi,
--- On Tue, 12/23/08, Andrew Vagin <ava...@parallels.com> wrote: > From: Andrew Vagin <ava...@parallels.com> > Subject: Re: [LTP] [PATCH] add new testcase for check inotify subsytem. > To: "CAI Qian" <caiq...@cclom.cn> > Cc: ltp-list@lists.sourceforge.net > Date: Tuesday, December 23, 2008, 7:56 PM > On Tue, Dec 23, 2008 at 02:57:16AM -0800, CAI Qian wrote: > > 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. > this test case will not execute automaticaly. See my > previous patch > [LTP] [PATCH] add options for block devices and turn on > related testcases > > It will execute if set option -b now. > I make setup a loop device for such testcases by the next > step. I look through the patch you mentioned, and now I see your points there. I have provided some comments there after a quick review. CAI Qian > > > > 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 ------------------------------------------------------------------------------ _______________________________________________ Ltp-list mailing list Ltp-list@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/ltp-list