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

Reply via email to