All of lore.kernel.org
 help / color / mirror / Atom feed
* [LTP] [PATCH v4 0/3] syscalls/fanotify: FAN_REPORT_FID and Directory Modification Events
@ 2019-06-17 10:34 Matthew Bobrowski
  2019-06-17 10:35 ` [LTP] [PATCH v4 1/3] syscalls/fanotify13: new test to verify FAN_REPORT_FID functionality Matthew Bobrowski
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Matthew Bobrowski @ 2019-06-17 10:34 UTC (permalink / raw)
  To: ltp

This patch series contains the changes needed to validate the new
FAN_REPORT_FID flag and directory modification event functionality
within the fanotify API.

Changes since version 3:
        * Added missing _GNU_SOURCE feature macro from
          syscalls/fanotify05.
	* Moved fanotify_get_fid() in fanotify.h outside #ifndef
	  FAN_REPORT_FID to accommodate for the situation where LTP is
	  built on a system that has newer (5.1 >) kernel headers
	  installed.

Thanks for your help Amir and Jan.

Matthew Bobrowski (3):
  syscalls/fanotify13: new test to verify FAN_REPORT_FID functionality
  syscalls/fanotify14: new test to validate FAN_REPORT_FID interface
    return values
  syscalls/fanotify15: verify fid for dirent events

 configure.ac                                  |   1 +
 runtest/syscalls                              |   3 +
 testcases/kernel/syscalls/fanotify/.gitignore |   3 +
 testcases/kernel/syscalls/fanotify/fanotify.h |  81 ++++-
 .../kernel/syscalls/fanotify/fanotify05.c     |   1 +
 .../kernel/syscalls/fanotify/fanotify13.c     | 313 ++++++++++++++++++
 .../kernel/syscalls/fanotify/fanotify14.c     | 171 ++++++++++
 .../kernel/syscalls/fanotify/fanotify15.c     | 245 ++++++++++++++
 8 files changed, 815 insertions(+), 3 deletions(-)
 create mode 100644 testcases/kernel/syscalls/fanotify/fanotify13.c
 create mode 100644 testcases/kernel/syscalls/fanotify/fanotify14.c
 create mode 100644 testcases/kernel/syscalls/fanotify/fanotify15.c

-- 
2.21.0


-- 
Matthew Bobrowski

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [LTP] [PATCH v4 1/3] syscalls/fanotify13: new test to verify FAN_REPORT_FID functionality
  2019-06-17 10:34 [LTP] [PATCH v4 0/3] syscalls/fanotify: FAN_REPORT_FID and Directory Modification Events Matthew Bobrowski
@ 2019-06-17 10:35 ` Matthew Bobrowski
  2019-06-18 21:23   ` Amir Goldstein
  2019-06-17 10:35 ` [LTP] [PATCH v4 2/3] syscalls/fanotify14: new test to validate FAN_REPORT_FID interface return values Matthew Bobrowski
  2019-06-17 10:35 ` [LTP] [PATCH v4 3/3] syscalls/fanotify15: verify fid for dirent events Matthew Bobrowski
  2 siblings, 1 reply; 7+ messages in thread
From: Matthew Bobrowski @ 2019-06-17 10:35 UTC (permalink / raw)
  To: ltp

A newly defined test file to validate the fanotify FAN_REPORT_FID
functionality. A new line entry for this test file has been added within
runtest/syscalls.

Additionally, defined a helper function that can be used to obtain
__kernel_fsid_t and file_handle objects. This helper will be used by
test files related to verifying FAN_REPORT_FID. The name_to_handle_at()
function is conditionally added to accommodate for builds on older
distributions.

Added _GNU_SOURCE feature test macro to syscalls/fanotify05 in order to
resolve build warnings.

Signed-off-by: Matthew Bobrowski <mbobrowski@mbobrowski.org>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
---
 configure.ac                                  |   1 +
 runtest/syscalls                              |   1 +
 testcases/kernel/syscalls/fanotify/.gitignore |   1 +
 testcases/kernel/syscalls/fanotify/fanotify.h |  56 +++-
 .../kernel/syscalls/fanotify/fanotify05.c     |   1 +
 .../kernel/syscalls/fanotify/fanotify13.c     | 313 ++++++++++++++++++
 6 files changed, 370 insertions(+), 3 deletions(-)
 create mode 100644 testcases/kernel/syscalls/fanotify/fanotify13.c

diff --git a/configure.ac b/configure.ac
index 5ecc92781..9538b2322 100644
--- a/configure.ac
+++ b/configure.ac
@@ -70,6 +70,7 @@ AC_CHECK_FUNCS([ \
     kcmp \
     mkdirat \
     mknodat \
+    name_to_handle_at \
     openat \
     preadv \
     preadv2 \
diff --git a/runtest/syscalls b/runtest/syscalls
index a1106fb84..e682f5087 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -534,6 +534,7 @@ fanotify09 fanotify09
 fanotify10 fanotify10
 fanotify11 fanotify11
 fanotify12 fanotify12
+fanotify13 fanotify13
 
 ioperm01 ioperm01
 ioperm02 ioperm02
diff --git a/testcases/kernel/syscalls/fanotify/.gitignore b/testcases/kernel/syscalls/fanotify/.gitignore
index 4256b8cd3..16bdd99e5 100644
--- a/testcases/kernel/syscalls/fanotify/.gitignore
+++ b/testcases/kernel/syscalls/fanotify/.gitignore
@@ -10,4 +10,5 @@
 /fanotify10
 /fanotify11
 /fanotify12
+/fanotify13
 /fanotify_child
diff --git a/testcases/kernel/syscalls/fanotify/fanotify.h b/testcases/kernel/syscalls/fanotify/fanotify.h
index 14654b7c7..a5ac14acb 100644
--- a/testcases/kernel/syscalls/fanotify/fanotify.h
+++ b/testcases/kernel/syscalls/fanotify/fanotify.h
@@ -29,6 +29,11 @@
 #define	__FANOTIFY_H__
 
 #include "config.h"
+#include <sys/statfs.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <fcntl.h>
 
 #if defined(HAVE_SYS_FANOTIFY_H)
 
@@ -57,9 +62,6 @@ static long fanotify_mark(int fd, unsigned int flags, uint64_t mask,
 #ifndef FAN_REPORT_TID
 #define FAN_REPORT_TID		0x00000100
 #endif
-#ifndef FAN_REPORT_FID
-#define FAN_REPORT_FID		0x00000200
-#endif
 
 #ifndef FAN_MARK_INODE
 #define FAN_MARK_INODE		0
@@ -89,6 +91,54 @@ struct fanotify_mark_type {
 	const char * name;
 };
 
+#ifndef FAN_REPORT_FID
+#define FAN_REPORT_FID		0x00000200
+
+struct fanotify_event_info_header {
+	uint8_t info_type;
+	uint8_t pad;
+	uint16_t len;
+};
+
+struct fanotify_event_info_fid {
+	struct fanotify_event_info_header hdr;
+	__kernel_fsid_t fsid;
+	unsigned char handle[0];
+};
+
+#endif
+
+/*
+ * Helper function used to obtain __kernel_fsid_t and file_handle objects
+ * for a given path. Used by test files correlated to FAN_REPORT_FID
+ * functionality.
+ */
+static inline void fanotify_get_fid(const char *path, __kernel_fsid_t *fsid,
+			struct file_handle *handle)
+{
+	int mount_id;
+	struct statfs stats;
+
+	if (statfs(path, &stats) == -1)
+		tst_brk(TBROK | TERRNO,
+			"statfs(%s, ...) failed", path);
+	memcpy(fsid, &stats.f_fsid, sizeof(stats.f_fsid));
+
+#ifdef HAVE_NAME_TO_HANDLE_AT
+	if (name_to_handle_at(AT_FDCWD, path, handle, &mount_id, 0) == -1) {
+		if (errno == EOPNOTSUPP) {
+			tst_brk(TCONF,
+				"filesystem %s does not support file handles",
+				tst_device->fs_type);
+		}
+		tst_brk(TBROK | TERRNO,
+			"name_to_handle_at(AT_FDCWD, %s, ...) failed", path);
+	}
+#else
+	tst_brk(TCONF, "name_to_handle_at() is not implmented");
+#endif /* HAVE_NAME_TO_HANDLE_AT */
+}
+
 #define INIT_FANOTIFY_MARK_TYPE(t) \
 	{ FAN_MARK_ ## t, "FAN_MARK_" #t }
 
diff --git a/testcases/kernel/syscalls/fanotify/fanotify05.c b/testcases/kernel/syscalls/fanotify/fanotify05.c
index de72e346a..112295709 100644
--- a/testcases/kernel/syscalls/fanotify/fanotify05.c
+++ b/testcases/kernel/syscalls/fanotify/fanotify05.c
@@ -11,6 +11,7 @@
  *     Generate enough events without reading them and check that overflow
  *     event is generated.
  */
+#define _GNU_SOURCE
 #include "config.h"
 
 #include <stdio.h>
diff --git a/testcases/kernel/syscalls/fanotify/fanotify13.c b/testcases/kernel/syscalls/fanotify/fanotify13.c
new file mode 100644
index 000000000..820f1390c
--- /dev/null
+++ b/testcases/kernel/syscalls/fanotify/fanotify13.c
@@ -0,0 +1,313 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018 Matthew Bobrowski. All Rights Reserved.
+ *
+ * Started by Matthew Bobrowski <mbobrowski@mbobrowski.org>
+ *
+ * DESCRIPTION
+ *	Validate that the values returned within an event when
+ *	FAN_REPORT_FID is specified matches those that are obtained via
+ *	explicit invocation to system calls statfs(2) and
+ *	name_to_handle_at(2).
+ */
+#define _GNU_SOURCE
+#include "config.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/statfs.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+#include "tst_test.h"
+#include "fanotify.h"
+
+#if defined(HAVE_SYS_FANOTIFY_H)
+#include <sys/fanotify.h>
+
+#define PATH_LEN 128
+#define BUF_SIZE 256
+#define DIR_ONE "dir_one"
+#define FILE_ONE "file_one"
+#define FILE_TWO "file_two"
+#define MOUNT_PATH "mntpoint"
+#define EVENT_MAX ARRAY_SIZE(objects)
+#define DIR_PATH_ONE MOUNT_PATH"/"DIR_ONE
+#define FILE_PATH_ONE MOUNT_PATH"/"FILE_ONE
+#define FILE_PATH_TWO MOUNT_PATH"/"FILE_TWO
+
+struct event_t {
+	unsigned long long expected_mask;
+	__kernel_fsid_t fsid;
+	struct file_handle handle;
+	char buf[MAX_HANDLE_SZ];
+};
+
+static struct object_t {
+	const char *path;
+	int is_dir;
+} objects[] = {
+	{FILE_PATH_ONE, 0},
+	{FILE_PATH_TWO, 0},
+	{DIR_PATH_ONE, 1}
+};
+
+static struct test_case_t {
+	struct fanotify_mark_type mark;
+	unsigned long long mask;
+} test_cases[] = {
+	{
+		INIT_FANOTIFY_MARK_TYPE(INODE),
+		FAN_OPEN | FAN_CLOSE_NOWRITE
+	},
+	{
+		INIT_FANOTIFY_MARK_TYPE(INODE),
+		FAN_OPEN | FAN_CLOSE_NOWRITE | FAN_ONDIR
+	},
+	{
+		INIT_FANOTIFY_MARK_TYPE(MOUNT),
+		FAN_OPEN | FAN_CLOSE_NOWRITE
+	},
+	{
+		INIT_FANOTIFY_MARK_TYPE(MOUNT),
+		FAN_OPEN | FAN_CLOSE_NOWRITE | FAN_ONDIR
+	},
+	{
+		INIT_FANOTIFY_MARK_TYPE(FILESYSTEM),
+		FAN_OPEN | FAN_CLOSE_NOWRITE
+	},
+	{
+		INIT_FANOTIFY_MARK_TYPE(FILESYSTEM),
+		FAN_OPEN | FAN_CLOSE_NOWRITE | FAN_ONDIR
+	}
+};
+
+static int fanotify_fd;
+static char events_buf[BUF_SIZE];
+static struct event_t event_set[EVENT_MAX];
+
+static void create_objects(void)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(objects); i++) {
+		if (objects[i].is_dir)
+			SAFE_MKDIR(objects[i].path, 0755);
+		else
+			SAFE_FILE_PRINTF(objects[i].path, "0");
+	}
+}
+
+static void get_object_stats(void)
+{
+	unsigned int i;
+	for (i = 0; i < ARRAY_SIZE(objects); i++) {
+		event_set[i].handle.handle_bytes = MAX_HANDLE_SZ;
+		fanotify_get_fid(objects[i].path, &event_set[i].fsid,
+				&event_set[i].handle);
+	}
+}
+
+static void do_setup(void)
+{
+	int fd;
+
+	/* Check for kernel fanotify support */
+	fd = SAFE_FANOTIFY_INIT(FAN_CLASS_NOTIF, O_RDONLY);
+	SAFE_CLOSE(fd);
+
+	/* Create file and directory objects for testing */
+	create_objects();
+
+	/* Get the filesystem fsid and file handle for each created object */
+	get_object_stats();
+}
+
+
+static int setup_marks(unsigned int fd, struct test_case_t *tc)
+{
+	unsigned int i;
+	struct fanotify_mark_type *mark = &tc->mark;
+
+	for (i = 0; i < ARRAY_SIZE(objects); i++) {
+		if (fanotify_mark(fd, FAN_MARK_ADD | mark->flag, tc->mask,
+					AT_FDCWD, objects[i].path) == -1) {
+			if (errno == EINVAL &&
+				mark->flag & FAN_MARK_FILESYSTEM) {
+				tst_res(TCONF,
+					"FAN_MARK_FILESYSTEM not supported by "
+					"kernel");
+				return 1;
+			} else if (errno == ENODEV &&
+					!event_set[i].fsid.val[0] &&
+					!event_set[i].fsid.val[1]) {
+				tst_res(TCONF,
+					"FAN_REPORT_FID not supported on "
+					"filesystem type %s",
+					tst_device->fs_type);
+				return 1;
+			}
+			tst_brk(TBROK | TERRNO,
+				"fanotify_mark(%d, FAN_MARK_ADD, FAN_OPEN, "
+				"AT_FDCWD, %s) failed",
+				fanotify_fd, objects[i].path);
+		}
+
+		/* Setup the expected mask for each generated event */
+		event_set[i].expected_mask = tc->mask;
+		if (!objects[i].is_dir)
+			event_set[i].expected_mask &= ~FAN_ONDIR;
+	}
+	return 0;
+}
+
+static void do_test(unsigned int number)
+{
+	unsigned int i;
+	int len, fds[ARRAY_SIZE(objects)];
+
+	struct file_handle *event_file_handle;
+	struct fanotify_event_metadata *metadata;
+	struct fanotify_event_info_fid *event_fid;
+	struct test_case_t *tc = &test_cases[number];
+	struct fanotify_mark_type *mark = &tc->mark;
+
+	tst_res(TINFO,
+		"Test #%d: FAN_REPORT_FID with mark flag: %s",
+		number, mark->name);
+
+	fanotify_fd = fanotify_init(FAN_CLASS_NOTIF | FAN_REPORT_FID, O_RDONLY);
+	if (fanotify_fd == -1) {
+		if (errno == EINVAL) {
+			tst_res(TCONF,
+				"FAN_REPORT_FID not supported by kernel");
+			return;
+		}
+		tst_brk(TBROK | TERRNO,
+			"fanotify_init(FAN_CLASS_NOTIF | FAN_REPORT_FID, "
+			"O_RDONLY) failed");
+	}
+
+	/* Place marks on a set of objects and setup the expected masks
+	 * for each event that is expected to be generated
+	 */
+	if (setup_marks(fanotify_fd, tc) != 0)
+		return;
+
+	/* Generate sequence of FAN_OPEN events on objects */
+	for (i = 0; i < ARRAY_SIZE(objects); i++)
+		fds[i] = SAFE_OPEN(objects[i].path, O_RDONLY);
+
+	/* Generate sequence of FAN_CLOSE_NOWRITE events on objects. Each
+	 * FAN_CLOSE_NOWRITE event is expected to be merged with its
+	 * respective FAN_OPEN event that was performed on the same object
+	 */
+	for (i = 0; i < ARRAY_SIZE(objects); i++) {
+		if (fds[i] > 0)
+			SAFE_CLOSE(fds[i]);
+	}
+
+	/* Read events from event queue */
+	len = SAFE_READ(0, fanotify_fd, events_buf, BUF_SIZE);
+
+	/* Iterate over event queue */
+	for (i = 0, metadata = (struct fanotify_event_metadata *) events_buf;
+		FAN_EVENT_OK(metadata, len);
+		metadata = FAN_EVENT_NEXT(metadata, len), i++) {
+		event_fid = (struct fanotify_event_info_fid *) (metadata + 1);
+		event_file_handle = (struct file_handle *) event_fid->handle;
+
+		/* File descriptor is redundant with FAN_REPORT_FID */
+		if (metadata->fd != FAN_NOFD)
+			tst_res(TFAIL,
+				"Unexpectedly received file descriptor %d in "
+				"event. Expected to get FAN_NOFD(%d)",
+				metadata->fd, FAN_NOFD);
+
+		/* Ensure that the correct mask has been reported in event */
+		if (metadata->mask != event_set[i].expected_mask)
+			tst_res(TFAIL,
+				"Unexpected mask received: %llx (expected: "
+				"%llx) in event",
+				metadata->mask,
+				event_set[i].expected_mask);
+
+		/* Verify handle_bytes returned in event */
+		if (event_file_handle->handle_bytes
+				!= event_set[i].handle.handle_bytes) {
+			tst_res(TFAIL,
+				"handle_bytes (%x) returned in event does not "
+				"equal to handle_bytes (%x) returned in "
+				"name_to_handle_at(2)",
+				event_file_handle->handle_bytes,
+				event_set[i].handle.handle_bytes);
+			continue;
+		}
+
+		/* Verify handle_type returned in event */
+		if (event_file_handle->handle_type !=
+				event_set[i].handle.handle_type) {
+			tst_res(TFAIL,
+				"handle_type (%x) returned in event does not "
+				"equal to handle_type (%x) returned in "
+				"name_to_handle_at(2)",
+				event_file_handle->handle_type,
+				event_set[i].handle.handle_type);
+			continue;
+		}
+
+		/* Verify file identifier f_handle returned in event */
+		if (memcmp(event_file_handle->f_handle,
+				event_set[i].handle.f_handle,
+				event_set[i].handle.handle_bytes) != 0) {
+			tst_res(TFAIL,
+				"event_file_handle->f_handle does not match "
+				"event_set[i].handle.f_handle returned in "
+				"name_to_handle_at(2)");
+			continue;
+		}
+
+		/* Verify filesystem ID fsid  returned in event */
+		if (memcmp(&event_fid->fsid, &event_set[i].fsid,
+				sizeof(event_set[i].fsid)) != 0) {
+			tst_res(TFAIL,
+				"event_fid.fsid != stat.f_fsid that was "
+				"obtained via statfs(2)");
+			continue;
+		}
+
+		tst_res(TPASS,
+			"got event: mask=%llx, pid=%d, fid=%x.%x.%lx values "
+			"returned in event match those returned in statfs(2) "
+			"and name_to_handle_at(2)",
+			metadata->mask,
+			getpid(),
+			event_fid->fsid.val[0],
+			event_fid->fsid.val[1],
+			*(unsigned long *) event_file_handle->f_handle);
+	}
+}
+
+static void do_cleanup(void)
+{
+	if (fanotify_fd > 0)
+		SAFE_CLOSE(fanotify_fd);
+}
+
+static struct tst_test test = {
+	.setup = do_setup,
+	.test = do_test,
+	.tcnt = ARRAY_SIZE(test_cases),
+	.cleanup = do_cleanup,
+	.needs_root = 1,
+	.needs_tmpdir = 1,
+	.mount_device = 1,
+	.mntpoint = MOUNT_PATH,
+	.all_filesystems = 1
+};
+
+#else
+	TST_TEST_CONF("System does not have required fanotify support");
+#endif
-- 
2.21.0


-- 
Matthew Bobrowski

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [LTP] [PATCH v4 2/3] syscalls/fanotify14: new test to validate FAN_REPORT_FID interface return values
  2019-06-17 10:34 [LTP] [PATCH v4 0/3] syscalls/fanotify: FAN_REPORT_FID and Directory Modification Events Matthew Bobrowski
  2019-06-17 10:35 ` [LTP] [PATCH v4 1/3] syscalls/fanotify13: new test to verify FAN_REPORT_FID functionality Matthew Bobrowski
@ 2019-06-17 10:35 ` Matthew Bobrowski
  2019-06-17 10:35 ` [LTP] [PATCH v4 3/3] syscalls/fanotify15: verify fid for dirent events Matthew Bobrowski
  2 siblings, 0 replies; 7+ messages in thread
From: Matthew Bobrowski @ 2019-06-17 10:35 UTC (permalink / raw)
  To: ltp

A newly defined test file has been introduced to validate that the
fanotify interface returns the correct error values upon specifying
invalid flags and masks in conjunction with FAN_REPORT_FID. A new line
entry within runtest/syscalls for this new test file.

Signed-off-by: Matthew Bobrowski <mbobrowski@mbobrowski.org>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
---
 runtest/syscalls                              |   1 +
 testcases/kernel/syscalls/fanotify/.gitignore |   1 +
 testcases/kernel/syscalls/fanotify/fanotify.h |  25 +++
 .../kernel/syscalls/fanotify/fanotify14.c     | 171 ++++++++++++++++++
 4 files changed, 198 insertions(+)
 create mode 100644 testcases/kernel/syscalls/fanotify/fanotify14.c

diff --git a/runtest/syscalls b/runtest/syscalls
index e682f5087..56f84824a 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -535,6 +535,7 @@ fanotify10 fanotify10
 fanotify11 fanotify11
 fanotify12 fanotify12
 fanotify13 fanotify13
+fanotify14 fanotify14
 
 ioperm01 ioperm01
 ioperm02 ioperm02
diff --git a/testcases/kernel/syscalls/fanotify/.gitignore b/testcases/kernel/syscalls/fanotify/.gitignore
index 16bdd99e5..bf389c96a 100644
--- a/testcases/kernel/syscalls/fanotify/.gitignore
+++ b/testcases/kernel/syscalls/fanotify/.gitignore
@@ -11,4 +11,5 @@
 /fanotify11
 /fanotify12
 /fanotify13
+/fanotify14
 /fanotify_child
diff --git a/testcases/kernel/syscalls/fanotify/fanotify.h b/testcases/kernel/syscalls/fanotify/fanotify.h
index a5ac14acb..f9803c1cc 100644
--- a/testcases/kernel/syscalls/fanotify/fanotify.h
+++ b/testcases/kernel/syscalls/fanotify/fanotify.h
@@ -69,6 +69,31 @@ static long fanotify_mark(int fd, unsigned int flags, uint64_t mask,
 #ifndef FAN_MARK_FILESYSTEM
 #define FAN_MARK_FILESYSTEM	0x00000100
 #endif
+/* New dirent event masks */
+#ifndef FAN_ATTRIB
+#define FAN_ATTRIB		0x00000004
+#endif
+#ifndef FAN_MOVED_FROM
+#define FAN_MOVED_FROM		0x00000040
+#endif
+#ifndef FAN_MOVED_TO
+#define FAN_MOVED_TO		0x00000080
+#endif
+#ifndef FAN_CREATE
+#define FAN_CREATE		0x00000100
+#endif
+#ifndef FAN_DELETE
+#define FAN_DELETE		0x00000200
+#endif
+#ifndef FAN_DELETE_SELF
+#define FAN_DELETE_SELF		0x00000400
+#endif
+#ifndef FAN_MOVE_SELF
+#define FAN_MOVE_SELF		0x00000800
+#endif
+#ifndef FAN_MOVE
+#define FAN_MOVE		(FAN_MOVED_FROM | FAN_MOVED_TO)
+#endif
 #ifndef FAN_OPEN_EXEC
 #define FAN_OPEN_EXEC		0x00001000
 #endif
diff --git a/testcases/kernel/syscalls/fanotify/fanotify14.c b/testcases/kernel/syscalls/fanotify/fanotify14.c
new file mode 100644
index 000000000..2e1878ac0
--- /dev/null
+++ b/testcases/kernel/syscalls/fanotify/fanotify14.c
@@ -0,0 +1,171 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018 Matthew Bobrowski. All Rights Reserved.
+ *
+ * Started by Matthew Bobrowski <mbobrowski@mbobrowski.org>
+ *
+ * DESCRIPTION
+ *	This test file has been designed to ensure that the fanotify
+ *	system calls fanotify_init(2) and fanotify_mark(2) return the
+ *	correct error code to the calling process when an invalid flag or
+ *	mask value has been specified in conjunction with FAN_REPORT_FID.
+ */
+#define _GNU_SOURCE
+#include "tst_test.h"
+#include "fanotify.h"
+
+#include <errno.h>
+
+#if defined(HAVE_SYS_FANOTIFY_H)
+#include <sys/fanotify.h>
+
+#define MNTPOINT "mntpoint"
+#define FILE1 MNTPOINT"/file1"
+
+/* List of inode events that are only available when notification group is
+ * set to report fid
+ */
+#define INODE_EVENTS (FAN_ATTRIB | FAN_CREATE | FAN_DELETE | FAN_MOVE | \
+		      FAN_DELETE_SELF | FAN_MOVE_SELF)
+
+static int fanotify_fd;
+
+/* Each test case has been designed in a manner whereby the values defined
+ * within should result in the interface to return an error to the calling
+ * process.
+ */
+static struct test_case_t {
+	unsigned int init_flags;
+	unsigned int mark_flags;
+	unsigned long long mask;
+} test_cases[] = {
+	{
+		FAN_CLASS_CONTENT | FAN_REPORT_FID, 0, 0
+	},
+	{
+		FAN_CLASS_PRE_CONTENT | FAN_REPORT_FID, 0, 0
+	},
+	{
+		FAN_CLASS_NOTIF, 0, INODE_EVENTS
+	},
+	{
+		FAN_CLASS_NOTIF | FAN_REPORT_FID, FAN_MARK_MOUNT, INODE_EVENTS
+	}
+};
+
+static void do_setup(void)
+{
+	int fd;
+
+	/* Check for kernel fanotify support */
+	fd = SAFE_FANOTIFY_INIT(FAN_CLASS_NOTIF, O_RDONLY);
+	SAFE_CLOSE(fd);
+
+	/* Create temporary test file to place marks on */
+	SAFE_FILE_PRINTF(FILE1, "0");
+}
+
+static void do_test(unsigned int number)
+{
+	int ret;
+	struct test_case_t *tc = &test_cases[number];
+
+	fanotify_fd = fanotify_init(tc->init_flags, O_RDONLY);
+
+	if (fanotify_fd < 0) {
+		/* EINVAL is to be returned to the calling process when
+		 * an invalid notification class is specified in
+		 * conjunction with FAN_REPORT_FID
+		 */
+		if (errno == EINVAL) {
+			tst_res(TPASS,
+				"fanotify_fd=%d, fanotify_init(%x, O_RDONLY) "
+				"failed with error EINVAL as expected",
+				fanotify_fd,
+				tc->init_flags);
+			return;
+		}
+		tst_brk(TBROK | TERRNO,
+			"fanotify_fd=%d, fanotify_init(%x, O_RDONLY) failed",
+			fanotify_fd,
+			tc->init_flags);
+	}
+
+	/* A test case with a mask set to zero indicate that they've been
+	 * specifically designed to test and fail on the fanotify_init()
+	 * system call.
+	 */
+	if (tc->mask == 0) {
+		tst_res(TFAIL,
+			"fanotify_fd=%d fanotify_init(%x, O_RDONLY) "
+			"unexpectedly succeeded when tests with mask 0 are"
+			"expected to fail when calling fanotify_init()",
+			fanotify_fd,
+			tc->init_flags);
+		return;
+	}
+
+	ret = fanotify_mark(fanotify_fd, FAN_MARK_ADD | tc->mark_flags,
+				tc->mask, AT_FDCWD, FILE1);
+
+	if (ret < 0) {
+		/* EINVAL is to be returned to the calling process when
+		 * attempting to use INODE_EVENTS without FAN_REPORT_FID
+		 * specified on the notification group, or using
+		 * INODE_EVENTS with mark type FAN_MARK_MOUNT.
+		 */
+		if (errno == EINVAL) {
+			tst_res(TPASS,
+				"ret=%d, fanotify_mark(%d, FAN_MARK_ADD | %x, "
+				"%llx, AT_FDCWD, %s) failed with error EINVAL "
+				"as expected",
+				ret,
+				fanotify_fd,
+				tc->mark_flags,
+				tc->mask,
+				FILE1);
+			return;
+		}
+		tst_brk(TBROK | TERRNO,
+			"ret=%d, fanotify_mark(%d, FAN_MARK_ADD | %x, %llx, "
+			"AT_FDCWD, %s) failed",
+			ret,
+			fanotify_fd,
+			tc->mark_flags,
+			tc->mask,
+			FILE1);
+	}
+
+	tst_res(TFAIL,
+		"fanotify_fd=%d, ret=%d, fanotify_init(%x, O_RDONLY) and "
+		"fanotify_mark(%d, FAN_MARK_ADD | %x, %llx, AT_FDCWD, %s) did "
+		"not return any errors as expected",
+		fanotify_fd,
+		ret,
+		tc->init_flags,
+		fanotify_fd,
+		tc->mark_flags,
+		tc->mask,
+		FILE1);
+}
+
+static void do_cleanup(void)
+{
+	if (fanotify_fd > 0)
+		SAFE_CLOSE(fanotify_fd);
+}
+
+static struct tst_test test = {
+	.needs_root = 1,
+	.setup = do_setup,
+	.test = do_test,
+	.tcnt = ARRAY_SIZE(test_cases),
+	.cleanup = do_cleanup,
+	.mount_device = 1,
+	.mntpoint = MNTPOINT,
+	.all_filesystems = 1
+};
+
+#else
+	TST_TEST_CONF("System does not have required fanotify support")
+#endif
-- 
2.21.0


-- 
Matthew Bobrowski

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [LTP] [PATCH v4 3/3] syscalls/fanotify15: verify fid for dirent events
  2019-06-17 10:34 [LTP] [PATCH v4 0/3] syscalls/fanotify: FAN_REPORT_FID and Directory Modification Events Matthew Bobrowski
  2019-06-17 10:35 ` [LTP] [PATCH v4 1/3] syscalls/fanotify13: new test to verify FAN_REPORT_FID functionality Matthew Bobrowski
  2019-06-17 10:35 ` [LTP] [PATCH v4 2/3] syscalls/fanotify14: new test to validate FAN_REPORT_FID interface return values Matthew Bobrowski
@ 2019-06-17 10:35 ` Matthew Bobrowski
  2 siblings, 0 replies; 7+ messages in thread
From: Matthew Bobrowski @ 2019-06-17 10:35 UTC (permalink / raw)
  To: ltp

A new test file that provides coverage for new dirent events has been
added. A new line entry within the runtest/syscalls file has been also
added to support the testing of these new dirent events.

Signed-off-by: Matthew Bobrowski <mbobrowski@mbobrowski.org>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
---
 runtest/syscalls                              |   1 +
 testcases/kernel/syscalls/fanotify/.gitignore |   1 +
 .../kernel/syscalls/fanotify/fanotify15.c     | 245 ++++++++++++++++++
 3 files changed, 247 insertions(+)
 create mode 100644 testcases/kernel/syscalls/fanotify/fanotify15.c

diff --git a/runtest/syscalls b/runtest/syscalls
index 56f84824a..25cb29dab 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -536,6 +536,7 @@ fanotify11 fanotify11
 fanotify12 fanotify12
 fanotify13 fanotify13
 fanotify14 fanotify14
+fanotify15 fanotify15
 
 ioperm01 ioperm01
 ioperm02 ioperm02
diff --git a/testcases/kernel/syscalls/fanotify/.gitignore b/testcases/kernel/syscalls/fanotify/.gitignore
index bf389c96a..68e4cc7aa 100644
--- a/testcases/kernel/syscalls/fanotify/.gitignore
+++ b/testcases/kernel/syscalls/fanotify/.gitignore
@@ -12,4 +12,5 @@
 /fanotify12
 /fanotify13
 /fanotify14
+/fanotify15
 /fanotify_child
diff --git a/testcases/kernel/syscalls/fanotify/fanotify15.c b/testcases/kernel/syscalls/fanotify/fanotify15.c
new file mode 100644
index 000000000..02f3b34ab
--- /dev/null
+++ b/testcases/kernel/syscalls/fanotify/fanotify15.c
@@ -0,0 +1,245 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2019 CTERA Networks. All Rights Reserved.
+ *
+ * Started by Amir Goldstein <amir73il@gmail.com>
+ * Modified by Matthew Bobrowski <mbobrowski@mbobrowski.org>
+ *
+ * DESCRIPTION
+ *	Test file that has been purposely designed to verify
+ *	FAN_REPORT_FID functionality while using newly defined dirent
+ *	events.
+ */
+#define _GNU_SOURCE
+#include "config.h"
+
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/statfs.h>
+#include <sys/types.h>
+
+#include "tst_test.h"
+#include "fanotify.h"
+
+#if defined(HAVE_SYS_FANOTIFY_H)
+#include <sys/fanotify.h>
+
+#define BUF_SIZE 256
+#define EVENT_MAX 256
+
+#define MOUNT_POINT "mntpoint"
+#define TEST_DIR MOUNT_POINT"/test_dir"
+#define DIR1 TEST_DIR"/dir1"
+#define DIR2 TEST_DIR"/dir2"
+#define FILE1 TEST_DIR"/file1"
+#define FILE2 TEST_DIR"/file2"
+
+struct event_t {
+	unsigned long long mask;
+	__kernel_fsid_t fsid;
+	struct file_handle handle;
+	char buf[MAX_HANDLE_SZ];
+};
+
+static int fanotify_fd;
+static char events_buf[BUF_SIZE];
+static struct event_t event_set[EVENT_MAX];
+
+static void do_setup(void)
+{
+	int fd;
+
+	/* Check kernel for fanotify support */
+	fd = SAFE_FANOTIFY_INIT(FAN_CLASS_NOTIF, O_RDONLY);
+	SAFE_CLOSE(fd);
+
+	fanotify_fd = fanotify_init(FAN_REPORT_FID, O_RDONLY);
+	if (fanotify_fd == -1) {
+		if (errno == EINVAL)
+			tst_brk(TCONF,
+				"FAN_REPORT_FID not supported in kernel");
+		tst_brk(TBROK | TERRNO,
+			"fanotify_init(FAN_REPORT_FID, O_RDONLY) failed");
+	}
+
+	SAFE_MKDIR(TEST_DIR, 0755);
+}
+
+static void do_test(void)
+{
+	int i, fd, len, count = 0;
+
+	struct file_handle *event_file_handle;
+	struct fanotify_event_metadata *metadata;
+	struct fanotify_event_info_fid *event_fid;
+
+	if (fanotify_mark(fanotify_fd, FAN_MARK_ADD | FAN_MARK_FILESYSTEM,
+				FAN_CREATE | FAN_DELETE | FAN_ATTRIB |
+				FAN_MOVED_FROM | FAN_MOVED_TO |
+				FAN_DELETE_SELF | FAN_ONDIR,
+				AT_FDCWD, TEST_DIR) == -1) {
+		if (errno == ENODEV)
+			tst_brk(TCONF,
+				"FAN_REPORT_FID not supported on %s "
+				"filesystem", tst_device->fs_type);
+		tst_brk(TBROK | TERRNO,
+			"fanotify_mark(%d, FAN_MARK_ADD, FAN_CREATE | "
+			"FAN_DELETE | FAN_MOVED_FROM | FAN_MOVED_TO | "
+			"FAN_DELETE_SELF | FAN_ONDIR, AT_FDCWD, %s) failed",
+			fanotify_fd, TEST_DIR);
+	}
+
+	/* Generate a sequence of events */
+	event_set[count].mask = FAN_CREATE | FAN_MOVED_FROM | FAN_MOVED_TO | \
+				FAN_DELETE;
+	event_set[count].handle.handle_bytes = MAX_HANDLE_SZ;
+	fanotify_get_fid(TEST_DIR, &event_set[count].fsid,
+			 &event_set[count].handle);
+	count++;
+
+	fd = SAFE_CREAT(FILE1, 0644);
+	SAFE_CLOSE(fd);
+
+	SAFE_RENAME(FILE1, FILE2);
+
+	event_set[count].mask = FAN_ATTRIB | FAN_DELETE_SELF;
+	event_set[count].handle.handle_bytes = MAX_HANDLE_SZ;
+	fanotify_get_fid(FILE2, &event_set[count].fsid,
+			 &event_set[count].handle);
+	count++;
+
+	SAFE_UNLINK(FILE2);
+
+	/* Generate a sequence of events on a directory. Subsequent events
+	 * are merged, so it's required that we set FAN_ONDIR once in
+	 * order to acknowledge that changes related to a subdirectory
+	 * took place. Events on subdirectories are not merged with events
+	 * on non-subdirectories.
+	 */
+	event_set[count].mask = FAN_ONDIR | FAN_CREATE | FAN_MOVED_FROM | \
+				FAN_MOVED_TO | FAN_DELETE;
+	event_set[count].handle.handle_bytes = MAX_HANDLE_SZ;
+	fanotify_get_fid(TEST_DIR, &event_set[count].fsid,
+			 &event_set[count].handle);
+	count++;
+
+	SAFE_MKDIR(DIR1, 0755);
+
+	SAFE_RENAME(DIR1, DIR2);
+
+	event_set[count].mask = FAN_ONDIR | FAN_DELETE_SELF;
+	event_set[count].handle.handle_bytes = MAX_HANDLE_SZ;
+	fanotify_get_fid(DIR2, &event_set[count].fsid,
+			 &event_set[count].handle);
+	count++;
+
+	SAFE_RMDIR(DIR2);
+
+	/* Read events from the event queue */
+	len = SAFE_READ(0, fanotify_fd, events_buf, BUF_SIZE);
+
+	/* Process each event in buffer */
+	for (i = 0, metadata = (struct fanotify_event_metadata *) events_buf;
+		FAN_EVENT_OK(metadata, len);
+		metadata = FAN_EVENT_NEXT(metadata,len), i++) {
+		event_fid = (struct fanotify_event_info_fid *) (metadata + 1);
+		event_file_handle = (struct file_handle *) event_fid->handle;
+
+		if (i >= count) {
+			tst_res(TFAIL,
+				"got unnecessary event: mask=%llx "
+				"pid=%u fd=%d",
+				(unsigned long long) metadata->mask,
+				metadata->pid,
+				metadata->fd);
+			metadata->mask = 0;
+		} else if (metadata->fd != FAN_NOFD) {
+			tst_res(TFAIL,
+				"Received unexpected file descriptor %d in "
+				"event. Expected to get FAN_NOFD(%d)",
+				metadata->fd, FAN_NOFD);
+		} else if (metadata->mask != event_set[i].mask) {
+			tst_res(TFAIL,
+				"Got event: mask=%llx (expected %llx) "
+				"pid=%u fd=%d",
+				(unsigned long long) metadata->mask,
+				event_set[i].mask,
+				(unsigned) metadata->pid,
+				metadata->fd);
+		} else if (metadata->pid != getpid()) {
+			tst_res(TFAIL,
+				"Got event: mask=%llx pid=%u "
+				"(expected %u) fd=%d",
+				(unsigned long long) metadata->mask,
+				(unsigned) metadata->pid,
+				(unsigned) getpid(),
+				metadata->fd);
+		} else if (event_file_handle->handle_bytes !=
+				event_set[i].handle.handle_bytes) {
+			tst_res(TFAIL,
+				"Got event: handle_bytes (%x) returned in "
+				"event does not equal handle_bytes (%x) "
+				"retunred in name_to_handle_at(2)",
+				event_file_handle->handle_bytes,
+				event_set[i].handle.handle_bytes);
+		} else if (event_file_handle->handle_type !=
+				event_set[i].handle.handle_type) {
+			tst_res(TFAIL,
+				"handle_type (%x) returned in event does not "
+				"equal to handle_type (%x) returned in "
+				"name_to_handle_at(2)",
+				event_file_handle->handle_type,
+				event_set[i].handle.handle_type);
+		} else if (memcmp(event_file_handle->f_handle,
+					event_set[i].handle.f_handle,
+					event_set[i].handle.handle_bytes)
+					!= 0) {
+			tst_res(TFAIL,
+				"event_file_handle->f_handle does not match "
+				"handle.f_handle returned in "
+				"name_to_handle_at(2)");
+		} else if (memcmp(&event_fid->fsid, &event_set[i].fsid,
+					sizeof(event_set[i].fsid)) != 0) {
+			tst_res(TFAIL,
+				"event_fid->fsid != stats.f_fsid that was "
+				"obtained via statfs(2)");
+		} else {
+			tst_res(TPASS,
+				"Got event: mask=%llx, pid=%u, "
+				"fid=%x.%x.%lx values",
+				metadata->mask,
+				getpid(),
+				event_fid->fsid.val[0],
+				event_fid->fsid.val[1],
+				*(unsigned long *)
+				event_file_handle->f_handle);
+		}
+	}
+
+	for (; i < count; i++)
+		tst_res(TFAIL,
+			"Didn't receive event: mask=%llx",
+			event_set[i].mask);
+}
+
+static void do_cleanup(void)
+{
+	if (fanotify_fd > 0)
+		SAFE_CLOSE(fanotify_fd);
+}
+
+static struct tst_test test = {
+	.needs_root = 1,
+	.needs_tmpdir = 1,
+	.mount_device = 1,
+	.mntpoint = MOUNT_POINT,
+	.all_filesystems = 1,
+	.setup = do_setup,
+	.test_all = do_test,
+	.cleanup = do_cleanup
+};
+
+#else
+	TST_TEST_CONF("System does not have required fanotify support");
+#endif
-- 
2.21.0


-- 
Matthew Bobrowski

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [LTP] [PATCH v4 1/3] syscalls/fanotify13: new test to verify FAN_REPORT_FID functionality
  2019-06-17 10:35 ` [LTP] [PATCH v4 1/3] syscalls/fanotify13: new test to verify FAN_REPORT_FID functionality Matthew Bobrowski
@ 2019-06-18 21:23   ` Amir Goldstein
  2019-06-19  2:35     ` Matthew Bobrowski
  0 siblings, 1 reply; 7+ messages in thread
From: Amir Goldstein @ 2019-06-18 21:23 UTC (permalink / raw)
  To: ltp

> +static void do_test(unsigned int number)
> +{
> +       unsigned int i;
> +       int len, fds[ARRAY_SIZE(objects)];
> +
> +       struct file_handle *event_file_handle;
> +       struct fanotify_event_metadata *metadata;
> +       struct fanotify_event_info_fid *event_fid;
> +       struct test_case_t *tc = &test_cases[number];
> +       struct fanotify_mark_type *mark = &tc->mark;
> +
> +       tst_res(TINFO,
> +               "Test #%d: FAN_REPORT_FID with mark flag: %s",
> +               number, mark->name);
> +
> +       fanotify_fd = fanotify_init(FAN_CLASS_NOTIF | FAN_REPORT_FID, O_RDONLY);
> +       if (fanotify_fd == -1) {
> +               if (errno == EINVAL) {
> +                       tst_res(TCONF,
> +                               "FAN_REPORT_FID not supported by kernel");
> +                       return;
> +               }
> +               tst_brk(TBROK | TERRNO,
> +                       "fanotify_init(FAN_CLASS_NOTIF | FAN_REPORT_FID, "
> +                       "O_RDONLY) failed");
> +       }
> +
> +       /* Place marks on a set of objects and setup the expected masks
> +        * for each event that is expected to be generated
> +        */
> +       if (setup_marks(fanotify_fd, tc) != 0)
> +               return;
> +

Sorry, just notices a test bug.
fanotify_fd needs to be closed before returning from this function,
because next test case is going to overwrite fanotify_fd.
do_cleanup() is called only at end of entire test or on tst_brk().

This needs to be fixed for fanotify14 and fanotify15 as well.

Also, please see my fanotify_dentry branch on github for an extra
patch to fanotify13 to cover a bug reported by syzbot:

https://lore.kernel.org/linux-fsdevel/CAOQ4uxhsnOXXVCuOT4p4c_koBMFfprWwdtCPGNGhzprFaJZwRA@mail.gmail.com/T/#t

Please include this extra patch in your next series posting.

Thanks,
Amir.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [LTP] [PATCH v4 1/3] syscalls/fanotify13: new test to verify FAN_REPORT_FID functionality
  2019-06-18 21:23   ` Amir Goldstein
@ 2019-06-19  2:35     ` Matthew Bobrowski
  2019-06-19  5:53       ` Amir Goldstein
  0 siblings, 1 reply; 7+ messages in thread
From: Matthew Bobrowski @ 2019-06-19  2:35 UTC (permalink / raw)
  To: ltp

On Wed, Jun 19, 2019 at 12:23:34AM +0300, Amir Goldstein wrote:
> > +static void do_test(unsigned int number)
> > +{
> > +       unsigned int i;
> > +       int len, fds[ARRAY_SIZE(objects)];
> > +
> > +       struct file_handle *event_file_handle;
> > +       struct fanotify_event_metadata *metadata;
> > +       struct fanotify_event_info_fid *event_fid;
> > +       struct test_case_t *tc = &test_cases[number];
> > +       struct fanotify_mark_type *mark = &tc->mark;
> > +
> > +       tst_res(TINFO,
> > +               "Test #%d: FAN_REPORT_FID with mark flag: %s",
> > +               number, mark->name);
> > +
> > +       fanotify_fd = fanotify_init(FAN_CLASS_NOTIF | FAN_REPORT_FID, O_RDONLY);
> > +       if (fanotify_fd == -1) {
> > +               if (errno == EINVAL) {
> > +                       tst_res(TCONF,
> > +                               "FAN_REPORT_FID not supported by kernel");
> > +                       return;
> > +               }
> > +               tst_brk(TBROK | TERRNO,
> > +                       "fanotify_init(FAN_CLASS_NOTIF | FAN_REPORT_FID, "
> > +                       "O_RDONLY) failed");
> > +       }
> > +
> > +       /* Place marks on a set of objects and setup the expected masks
> > +        * for each event that is expected to be generated
> > +        */
> > +       if (setup_marks(fanotify_fd, tc) != 0)
> > +               return;
> > +
> 
> Sorry, just notices a test bug.
> fanotify_fd needs to be closed before returning from this function,
> because next test case is going to overwrite fanotify_fd.
> do_cleanup() is called only at end of entire test or on tst_brk().
> 
> This needs to be fixed for fanotify14 and fanotify15 as well.

Ah, yes. Thank you Amir and good spotting. I've also updated
TST_TEST_CONF() to TST_TEST_TCONF(). The branch containing these updates
can be found here:
	- https://github.com/matthewbobrowski/ltp/commits/fanotify_dirent	

Please check.
 
> Also, please see my fanotify_dentry branch on github for an extra
> patch to fanotify13 to cover a bug reported by syzbot:
> 
> https://lore.kernel.org/linux-fsdevel/CAOQ4uxhsnOXXVCuOT4p4c_koBMFfprWwdtCPGNGhzprFaJZwRA@mail.gmail.com/T/#t
> 
> Please include this extra patch in your next series posting.

No problem. Applied on top of my fanotify_dirent branch (above).

-- 
Matthew Bobrowski

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [LTP] [PATCH v4 1/3] syscalls/fanotify13: new test to verify FAN_REPORT_FID functionality
  2019-06-19  2:35     ` Matthew Bobrowski
@ 2019-06-19  5:53       ` Amir Goldstein
  0 siblings, 0 replies; 7+ messages in thread
From: Amir Goldstein @ 2019-06-19  5:53 UTC (permalink / raw)
  To: ltp

On Wed, Jun 19, 2019 at 5:35 AM Matthew Bobrowski
<mbobrowski@mbobrowski.org> wrote:
>
> On Wed, Jun 19, 2019 at 12:23:34AM +0300, Amir Goldstein wrote:
> > > +static void do_test(unsigned int number)
> > > +{
> > > +       unsigned int i;
> > > +       int len, fds[ARRAY_SIZE(objects)];
> > > +
> > > +       struct file_handle *event_file_handle;
> > > +       struct fanotify_event_metadata *metadata;
> > > +       struct fanotify_event_info_fid *event_fid;
> > > +       struct test_case_t *tc = &test_cases[number];
> > > +       struct fanotify_mark_type *mark = &tc->mark;
> > > +
> > > +       tst_res(TINFO,
> > > +               "Test #%d: FAN_REPORT_FID with mark flag: %s",
> > > +               number, mark->name);
> > > +
> > > +       fanotify_fd = fanotify_init(FAN_CLASS_NOTIF | FAN_REPORT_FID, O_RDONLY);
> > > +       if (fanotify_fd == -1) {
> > > +               if (errno == EINVAL) {
> > > +                       tst_res(TCONF,
> > > +                               "FAN_REPORT_FID not supported by kernel");
> > > +                       return;
> > > +               }
> > > +               tst_brk(TBROK | TERRNO,
> > > +                       "fanotify_init(FAN_CLASS_NOTIF | FAN_REPORT_FID, "
> > > +                       "O_RDONLY) failed");
> > > +       }
> > > +
> > > +       /* Place marks on a set of objects and setup the expected masks
> > > +        * for each event that is expected to be generated
> > > +        */
> > > +       if (setup_marks(fanotify_fd, tc) != 0)
> > > +               return;
> > > +
> >
> > Sorry, just notices a test bug.
> > fanotify_fd needs to be closed before returning from this function,
> > because next test case is going to overwrite fanotify_fd.
> > do_cleanup() is called only at end of entire test or on tst_brk().
> >
> > This needs to be fixed for fanotify14 and fanotify15 as well.
>
> Ah, yes. Thank you Amir and good spotting. I've also updated
> TST_TEST_CONF() to TST_TEST_TCONF(). The branch containing these updates
> can be found here:
>         - https://github.com/matthewbobrowski/ltp/commits/fanotify_dirent
>
> Please check.

There were still problems with unbalanced close.
I fixes them up and pushed to my branch.

Most ltp tests are written like this:
do_test()
...
do_setup()
do_cleanup()

and for a good reason so it is easy to pair up full test resource setup
with full test resource cleanup.
This includes resources that are allocated not per test case and not
per test loop
(e.g. ./fanotify13 -i 2)

I reordered the tests code to match this pattern.
Please hold off with posting v5, because I want to see that after we fix
the fsid cache bug, the new test will pass.

Thanks,
Amir.

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2019-06-19  5:53 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-06-17 10:34 [LTP] [PATCH v4 0/3] syscalls/fanotify: FAN_REPORT_FID and Directory Modification Events Matthew Bobrowski
2019-06-17 10:35 ` [LTP] [PATCH v4 1/3] syscalls/fanotify13: new test to verify FAN_REPORT_FID functionality Matthew Bobrowski
2019-06-18 21:23   ` Amir Goldstein
2019-06-19  2:35     ` Matthew Bobrowski
2019-06-19  5:53       ` Amir Goldstein
2019-06-17 10:35 ` [LTP] [PATCH v4 2/3] syscalls/fanotify14: new test to validate FAN_REPORT_FID interface return values Matthew Bobrowski
2019-06-17 10:35 ` [LTP] [PATCH v4 3/3] syscalls/fanotify15: verify fid for dirent events Matthew Bobrowski

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.