--- On Sat, 12/27/08, Andrew Vagin <ava...@gmail.com> wrote:
> From: Andrew Vagin <ava...@gmail.com>
> Subject: [PATCH] add new testcase for check inotify subsytem.
> To: caiq...@cclom.cn
> Cc: subr...@linux.vnet.ibm.com, ltp-list@lists.sourceforge.net, "Andrew
> Vagin" <ava...@gmail.com>
> Date: Saturday, December 27, 2008, 8:36 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
>
> 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
Acked-by: CAI Qian <caiq...@cclom.cn>
------------------------------------------------------------------------------
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list