[LTP] [PATCH 4/4] syscalls/fanotify09: Add test cases for merge of ignore mask

Jan Kara jack@suse.cz
Mon Jun 20 17:20:32 CEST 2022


On Mon 20-06-22 16:27:37, Amir Goldstein wrote:
> 1. Verify that an ignore mask that does not survive modify event,
>    does survive a modify event on child, if parent is not watching
>    events on children.
> 
> 2. Verify that an ignore mask on parent does not ignore close events
>    sent to mount mark, if parent is not watching events on children.
> 
> The behavior of these corner cases of ignore mask on parent dir have
> always been undefined, so do not run the test for kernel < v5.19.
> 
> Signed-off-by: Amir Goldstein <amir73il@gmail.com>

Hum, I was looking into the testcase. What does generate a modify event
there and checks that ignore mask does not survive it?

								Honza

> ---
>  .../kernel/syscalls/fanotify/fanotify09.c     | 72 +++++++++++++++++--
>  1 file changed, 68 insertions(+), 4 deletions(-)
> 
> diff --git a/testcases/kernel/syscalls/fanotify/fanotify09.c b/testcases/kernel/syscalls/fanotify/fanotify09.c
> index 070ad9933..0eb83e2f8 100644
> --- a/testcases/kernel/syscalls/fanotify/fanotify09.c
> +++ b/testcases/kernel/syscalls/fanotify/fanotify09.c
> @@ -27,6 +27,11 @@
>   * Test case #5 is a regression test for commit:
>   *
>   *      7372e79c9eb9 fanotify: fix logic of reporting name info with watched parent
> + *
> + * Test cases #6-#7 are regression tests for commit:
> + * (from v5.19, unlikely to be backported thus not in .tags):
> + *
> + *      e730558adffb fanotify: consistent behavior for parent not watching children
>   */
>  
>  #define _GNU_SOURCE
> @@ -73,6 +78,7 @@ static struct tcase {
>  	const char *tname;
>  	struct fanotify_mark_type mark;
>  	unsigned int ondir;
> +	unsigned int ignore;
>  	unsigned int report_name;
>  	const char *close_nowrite;
>  	int nevents;
> @@ -83,6 +89,7 @@ static struct tcase {
>  		INIT_FANOTIFY_MARK_TYPE(MOUNT),
>  		0,
>  		0,
> +		0,
>  		DIR_NAME,
>  		1, 0,
>  	},
> @@ -91,6 +98,7 @@ static struct tcase {
>  		INIT_FANOTIFY_MARK_TYPE(MOUNT),
>  		FAN_ONDIR,
>  		0,
> +		0,
>  		DIR_NAME,
>  		2, 0,
>  	},
> @@ -99,6 +107,7 @@ static struct tcase {
>  		INIT_FANOTIFY_MARK_TYPE(MOUNT),
>  		FAN_ONDIR,
>  		0,
> +		0,
>  		".",
>  		2, 0
>  	},
> @@ -107,6 +116,7 @@ static struct tcase {
>  		INIT_FANOTIFY_MARK_TYPE(INODE),
>  		FAN_ONDIR,
>  		0,
> +		0,
>  		DIR_NAME,
>  		2, 0,
>  	},
> @@ -115,6 +125,7 @@ static struct tcase {
>  		INIT_FANOTIFY_MARK_TYPE(MOUNT),
>  		0,
>  		0,
> +		0,
>  		FILE2_NAME,
>  		2, FAN_CLOSE_NOWRITE,
>  	},
> @@ -122,10 +133,29 @@ static struct tcase {
>  		"Events on non-dir child with both parent and mount marks and filename info",
>  		INIT_FANOTIFY_MARK_TYPE(MOUNT),
>  		0,
> +		0,
>  		FAN_REPORT_DFID_NAME,
>  		FILE2_NAME,
>  		2, FAN_CLOSE_NOWRITE,
>  	},
> +	{
> +		"Events on non-dir child with ignore mask on parent",
> +		INIT_FANOTIFY_MARK_TYPE(MOUNT),
> +		0,
> +		FAN_MARK_IGNORED_MASK,
> +		0,
> +		DIR_NAME,
> +		1, 0,
> +	},
> +	{
> +		"Events on non-dir children with surviving ignore mask on parent",
> +		INIT_FANOTIFY_MARK_TYPE(MOUNT),
> +		0,
> +		FAN_MARK_IGNORED_MASK | FAN_MARK_IGNORED_SURV_MODIFY,
> +		0,
> +		FILE2_NAME,
> +		2, FAN_CLOSE_NOWRITE,
> +	},
>  };
>  
>  static void create_fanotify_groups(struct tcase *tc)
> @@ -140,13 +170,14 @@ static void create_fanotify_groups(struct tcase *tc)
>  		 */
>  		unsigned int report_name = tc->report_name;
>  		unsigned int mask_flags = tc->ondir | FAN_EVENT_ON_CHILD;
> -		unsigned int parent_mask;
> +		unsigned int parent_mask, ignore = 0;
>  
>  		/*
>  		 * The non-first groups do not request events on children and
> -		 * subdirs.
> +		 * subdirs and may set an ignore mask on parent dir.
>  		 */
>  		if (i > 0) {
> +			ignore = tc->ignore;
>  			report_name = 0;
>  			mask_flags = 0;
>  		}
> @@ -168,10 +199,15 @@ static void create_fanotify_groups(struct tcase *tc)
>  		 * but only the first group requests events on child.
>  		 * The one mark with FAN_EVENT_ON_CHILD is needed for
>  		 * setting the DCACHE_FSNOTIFY_PARENT_WATCHED dentry flag.
> +		 *
> +		 * The inode mark on non-first group is either with FAN_MODIFY
> +		 * in mask or FAN_CLOSE_NOWRITE in ignore mask. In either case,
> +		 * it is not expected to get the modify event on a child, nor
> +		 * the close event on dir.
>  		 */
>  		parent_mask = FAN_MODIFY | tc->ondir | mask_flags;
> -		SAFE_FANOTIFY_MARK(fd_notify[i], FAN_MARK_ADD,
> -				    parent_mask,
> +		SAFE_FANOTIFY_MARK(fd_notify[i], FAN_MARK_ADD | ignore,
> +				    ignore ? FAN_CLOSE_NOWRITE : parent_mask,
>  				    AT_FDCWD, ".");
>  	}
>  }
> @@ -186,6 +222,21 @@ static void cleanup_fanotify_groups(void)
>  	}
>  }
>  
> +static void check_ignore_mask(int fd)
> +{
> +	unsigned int ignored_mask, mflags;
> +	char procfdinfo[100];
> +
> +	sprintf(procfdinfo, "/proc/%d/fdinfo/%d", (int)getpid(), fd);
> +	if (FILE_LINES_SCANF(procfdinfo, "fanotify ino:%*x sdev:%*x mflags: %x mask:0 ignored_mask:%x",
> +				&mflags, &ignored_mask) || !ignored_mask) {
> +		tst_res(TFAIL, "The ignore mask did not survive");
> +	} else {
> +		tst_res(TPASS, "Found mark with ignore mask (ignored_mask=%x, mflags=%x) in %s",
> +				ignored_mask, mflags, procfdinfo);
> +	}
> +}
> +
>  static void event_res(int ttype, int group,
>  		      struct fanotify_event_metadata *event,
>  		      const char *filename)
> @@ -274,6 +325,12 @@ static void test_fanotify(unsigned int n)
>  		return;
>  	}
>  
> +	if (tc->ignore && tst_kvercmp(5, 19, 0) < 0) {
> +		tst_res(TCONF, "ignored mask on parent dir has undefined "
> +				"behavior on kernel < 5.19");
> +		return;
> +	}
> +
>  	create_fanotify_groups(tc);
>  
>  	/*
> @@ -326,6 +383,13 @@ static void test_fanotify(unsigned int n)
>  	 * got the FAN_CLOSE_NOWRITE event only on a non-directory.
>  	 */
>  	for (i = 1; i < NUM_GROUPS; i++) {
> +		/*
> +		 * Verify that ignore mask survived the modify event on child,
> +		 * which was not supposed to be sent to this group.
> +		 */
> +		if (tc->ignore)
> +			check_ignore_mask(fd_notify[i]);
> +
>  		ret = read(fd_notify[i], event_buf, EVENT_BUF_LEN);
>  		if (ret > 0) {
>  			event = (struct fanotify_event_metadata *)event_buf;
> -- 
> 2.25.1
> 
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR


More information about the ltp mailing list