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

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

Changes since version 1:
	* Added new line entries into runtest/syscalls to support newly defined
	  fanotify tests.
	
	* Defined new generic helper function within fanotify.h to remove code
	  duplication that was previsouly found across tests.

	* Added '.all_filesystems = 1' flag within tests fanotify14 and
	  fanotify15.

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

 runtest/syscalls                                |   3 +
 testcases/kernel/syscalls/fanotify/.gitignore   |   3 +
 testcases/kernel/syscalls/fanotify/fanotify.h   |  77 +++++-
 testcases/kernel/syscalls/fanotify/fanotify13.c | 313 ++++++++++++++++++++++++
 testcases/kernel/syscalls/fanotify/fanotify14.c | 171 +++++++++++++
 testcases/kernel/syscalls/fanotify/fanotify15.c | 245 +++++++++++++++++++
 6 files changed, 809 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

-- 
1.8.3.1


-- 
Matthew Bobrowski

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

* [LTP] [PATCH v2 1/3] syscalls/fanotify13: new test to verify FAN_REPORT_FID functionality
  2019-04-20 12:49 [LTP] [PATCH v2 0/3] FAN_REPORT_FID and Directory Modification Events Matthew Bobrowski
@ 2019-04-20 12:49 ` Matthew Bobrowski
  2019-04-26 15:27   ` Cyril Hrubis
  2019-04-20 12:50 ` [LTP] [PATCH v2 2/3] syscalls/fanotify14: new test to validate FAN_REPORT_FID interface return values Matthew Bobrowski
  2019-04-20 12:50 ` [LTP] [PATCH v2 3/3] syscalls/fanotify15: verify fid for dirent events Matthew Bobrowski
  2 siblings, 1 reply; 9+ messages in thread
From: Matthew Bobrowski @ 2019-04-20 12:49 UTC (permalink / raw)
  To: ltp

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
tests related to FAN_REPORT_FID.

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   |  52 +++-
 testcases/kernel/syscalls/fanotify/fanotify13.c | 313 ++++++++++++++++++++++++
 4 files changed, 364 insertions(+), 3 deletions(-)
 create mode 100644 testcases/kernel/syscalls/fanotify/fanotify13.c

diff --git a/runtest/syscalls b/runtest/syscalls
index 2b8ca71..dfdc6cb 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -537,6 +537,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 4256b8c..16bdd99 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 14654b7..e9b23cc 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,50 @@ 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];
+};
+
+/*
+ * 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));
+
+	if (name_to_handle_at(AT_FDCWD, path, handle, &mount_id, 0) == -1) {
+		if (errno == EOPNOTSUPP) {
+			tst_res(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);
+	}
+}
+
+#endif
+
 #define INIT_FANOTIFY_MARK_TYPE(t) \
 	{ FAN_MARK_ ## t, "FAN_MARK_" #t }
 
diff --git a/testcases/kernel/syscalls/fanotify/fanotify13.c b/testcases/kernel/syscalls/fanotify/fanotify13.c
new file mode 100644
index 0000000..820f139
--- /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
-- 
1.8.3.1


-- 
Matthew Bobrowski

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

* [LTP] [PATCH v2 2/3] syscalls/fanotify14: new test to validate FAN_REPORT_FID interface return values
  2019-04-20 12:49 [LTP] [PATCH v2 0/3] FAN_REPORT_FID and Directory Modification Events Matthew Bobrowski
  2019-04-20 12:49 ` [LTP] [PATCH v2 1/3] syscalls/fanotify13: new test to verify FAN_REPORT_FID functionality Matthew Bobrowski
@ 2019-04-20 12:50 ` Matthew Bobrowski
  2019-04-20 12:50 ` [LTP] [PATCH v2 3/3] syscalls/fanotify15: verify fid for dirent events Matthew Bobrowski
  2 siblings, 0 replies; 9+ messages in thread
From: Matthew Bobrowski @ 2019-04-20 12:50 UTC (permalink / raw)
  To: ltp

New 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 ++++
 testcases/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 dfdc6cb..5c62895 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -538,6 +538,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 16bdd99..bf389c9 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 e9b23cc..7c88fa8 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 0000000..735d6ac
--- /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.
+ */
+
+#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
-- 
1.8.3.1


-- 
Matthew Bobrowski

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

* [LTP] [PATCH v2 3/3] syscalls/fanotify15: verify fid for dirent events
  2019-04-20 12:49 [LTP] [PATCH v2 0/3] FAN_REPORT_FID and Directory Modification Events Matthew Bobrowski
  2019-04-20 12:49 ` [LTP] [PATCH v2 1/3] syscalls/fanotify13: new test to verify FAN_REPORT_FID functionality Matthew Bobrowski
  2019-04-20 12:50 ` [LTP] [PATCH v2 2/3] syscalls/fanotify14: new test to validate FAN_REPORT_FID interface return values Matthew Bobrowski
@ 2019-04-20 12:50 ` Matthew Bobrowski
  2 siblings, 0 replies; 9+ messages in thread
From: Matthew Bobrowski @ 2019-04-20 12:50 UTC (permalink / raw)
  To: ltp

New test file that provides coverage for new dirent events. A new line
entry within the runtest/syscalls file has been added to support 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/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 5c62895..2f9f147 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -539,6 +539,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 bf389c9..68e4cc7 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 0000000..02f3b34
--- /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
-- 
1.8.3.1


-- 
Matthew Bobrowski

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

* [LTP] [PATCH v2 1/3] syscalls/fanotify13: new test to verify FAN_REPORT_FID functionality
  2019-04-20 12:49 ` [LTP] [PATCH v2 1/3] syscalls/fanotify13: new test to verify FAN_REPORT_FID functionality Matthew Bobrowski
@ 2019-04-26 15:27   ` Cyril Hrubis
  2019-04-27  4:53     ` Matthew Bobrowski
  0 siblings, 1 reply; 9+ messages in thread
From: Cyril Hrubis @ 2019-04-26 15:27 UTC (permalink / raw)
  To: ltp

Hi!
I've tried these tests on buildservice to check that there are no
problems on slightly older distributions and found two.

The first one is that we do define fallback definitions in fanotify.h
but then ifdef the whole test code in #if defined(HAVE_SYS_FANOTIFY_H)
so that it's efectively disabled on older distros even with fallback
definitions in place. Also it's TST_TEST_TCONF() but that is just easy
to fix typo. I guess that we can remove the ifdef and sys/fanotify.h
include from the test sources since we conditionally include the
sys/fanotify.h in the local fanotify.h already.

The second one is that we fail to compile on older distributions because
of missing name_to_handle_at() so we need configure check for that
syscall and fallback definition in lapi/ header, or at least configure
check and ifdef in the fanotify_get_fid() function. Which should be as
easy as adding a name_to_handle_at line to AC_CHECK_FUNCS() in the
configure.ac and using the macro from config.h.

> diff --git a/runtest/syscalls b/runtest/syscalls
> index 2b8ca71..dfdc6cb 100644
> --- a/runtest/syscalls
> +++ b/runtest/syscalls
> @@ -537,6 +537,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 4256b8c..16bdd99 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 14654b7..e9b23cc 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,50 @@ 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];
> +};
> +
> +/*
> + * 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));
> +
> +	if (name_to_handle_at(AT_FDCWD, path, handle, &mount_id, 0) == -1) {
> +		if (errno == EOPNOTSUPP) {
> +			tst_res(TCONF,
> +				"filesystem %s does not support file handles",
> +				tst_device->fs_type);

Btw, here the tst_res() does not make much sense sice the code will
continue and we will exit the test with the tst_brk() below. Shouldn't
we use tst_brk() here as well?

> +		}
> +		tst_brk(TBROK | TERRNO,
> +			"name_to_handle_at(AT_FDCWD, %s, ...) failed", path);
> +	}
> +}
> +
> +#endif
> +
>  #define INIT_FANOTIFY_MARK_TYPE(t) \
>  	{ FAN_MARK_ ## t, "FAN_MARK_" #t }

-- 
Cyril Hrubis
chrubis@suse.cz

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

* [LTP] [PATCH v2 1/3] syscalls/fanotify13: new test to verify FAN_REPORT_FID functionality
  2019-04-26 15:27   ` Cyril Hrubis
@ 2019-04-27  4:53     ` Matthew Bobrowski
  2019-05-07  7:40       ` Matthew Bobrowski
  2019-05-15 14:50       ` Amir Goldstein
  0 siblings, 2 replies; 9+ messages in thread
From: Matthew Bobrowski @ 2019-04-27  4:53 UTC (permalink / raw)
  To: ltp

On Fri, Apr 26, 2019 at 05:27:48PM +0200, Cyril Hrubis wrote:
> Hi!
> I've tried these tests on buildservice to check that there are no
> problems on slightly older distributions and found two.
> 
> The first one is that we do define fallback definitions in fanotify.h
> but then ifdef the whole test code in #if defined(HAVE_SYS_FANOTIFY_H)
> so that it's efectively disabled on older distros even with fallback
> definitions in place. Also it's TST_TEST_TCONF() but that is just easy
> to fix typo. I guess that we can remove the ifdef and sys/fanotify.h
> include from the test sources since we conditionally include the
> sys/fanotify.h in the local fanotify.h already.

OK. In that case I can write a patch that is to be applied prior to this series
which essentially just removes this specific preprocessor conditional directive
from all the source files. Would you like me to do this?
 
> The second one is that we fail to compile on older distributions because
> of missing name_to_handle_at() so we need configure check for that
> syscall and fallback definition in lapi/ header, or at least configure
> check and ifdef in the fanotify_get_fid() function. Which should be as
> easy as adding a name_to_handle_at line to AC_CHECK_FUNCS() in the
> configure.ac and using the macro from config.h.

Sure. I've gone ahead an updated it to accommodate for this. Prior to
submitting through another patches series, changes can be found here:
https://github.com/matthewbobrowski/ltp/commit/54264db0e574d2f90e716a510fcb1da11ee174dc.

I think we can do better and also provide a fallback definition though,
thoughts? Don't believe that it would take much effort. 
 
> > diff --git a/runtest/syscalls b/runtest/syscalls
> > index 2b8ca71..dfdc6cb 100644
> > --- a/runtest/syscalls
> > +++ b/runtest/syscalls
> > @@ -537,6 +537,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 4256b8c..16bdd99 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 14654b7..e9b23cc 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,50 @@ 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];
> > +};
> > +
> > +/*
> > + * 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));
> > +
> > +	if (name_to_handle_at(AT_FDCWD, path, handle, &mount_id, 0) == -1) {
> > +		if (errno == EOPNOTSUPP) {
> > +			tst_res(TCONF,
> > +				"filesystem %s does not support file handles",
> > +				tst_device->fs_type);
> 
> Btw, here the tst_res() does not make much sense sice the code will
> continue and we will exit the test with the tst_brk() below. Shouldn't
> we use tst_brk() here as well?

Yes, we should be using tst_brk(...) instead. Thanks for picking this up.
 
> > +		}
> > +		tst_brk(TBROK | TERRNO,
> > +			"name_to_handle_at(AT_FDCWD, %s, ...) failed", path);
> > +	}
> > +}
> > +
> > +#endif
> > +
> >  #define INIT_FANOTIFY_MARK_TYPE(t) \
> >  	{ FAN_MARK_ ## t, "FAN_MARK_" #t }

-- 
Matthew Bobrowski

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

* [LTP] [PATCH v2 1/3] syscalls/fanotify13: new test to verify FAN_REPORT_FID functionality
  2019-04-27  4:53     ` Matthew Bobrowski
@ 2019-05-07  7:40       ` Matthew Bobrowski
  2019-05-15 14:50       ` Amir Goldstein
  1 sibling, 0 replies; 9+ messages in thread
From: Matthew Bobrowski @ 2019-05-07  7:40 UTC (permalink / raw)
  To: ltp

Hi Cyril,

Any feedback on the below?

On Sat, Apr 27, 2019 at 02:53:44PM +1000, Matthew Bobrowski wrote:
> On Fri, Apr 26, 2019 at 05:27:48PM +0200, Cyril Hrubis wrote:
> > Hi!
> > I've tried these tests on buildservice to check that there are no
> > problems on slightly older distributions and found two.
> > 
> > The first one is that we do define fallback definitions in fanotify.h
> > but then ifdef the whole test code in #if defined(HAVE_SYS_FANOTIFY_H)
> > so that it's efectively disabled on older distros even with fallback
> > definitions in place. Also it's TST_TEST_TCONF() but that is just easy
> > to fix typo. I guess that we can remove the ifdef and sys/fanotify.h
> > include from the test sources since we conditionally include the
> > sys/fanotify.h in the local fanotify.h already.
> 
> OK. In that case I can write a patch that is to be applied prior to this series
> which essentially just removes this specific preprocessor conditional directive
> from all the source files. Would you like me to do this?
>  
> > The second one is that we fail to compile on older distributions because
> > of missing name_to_handle_at() so we need configure check for that
> > syscall and fallback definition in lapi/ header, or at least configure
> > check and ifdef in the fanotify_get_fid() function. Which should be as
> > easy as adding a name_to_handle_at line to AC_CHECK_FUNCS() in the
> > configure.ac and using the macro from config.h.
> 
> Sure. I've gone ahead an updated it to accommodate for this. Prior to
> submitting through another patches series, changes can be found here:
> https://github.com/matthewbobrowski/ltp/commit/54264db0e574d2f90e716a510fcb1da11ee174dc.
> 
> I think we can do better and also provide a fallback definition though,
> thoughts? Don't believe that it would take much effort. 
>  
> > > diff --git a/runtest/syscalls b/runtest/syscalls
> > > index 2b8ca71..dfdc6cb 100644
> > > --- a/runtest/syscalls
> > > +++ b/runtest/syscalls
> > > @@ -537,6 +537,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 4256b8c..16bdd99 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 14654b7..e9b23cc 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,50 @@ 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];
> > > +};
> > > +
> > > +/*
> > > + * 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));
> > > +
> > > +	if (name_to_handle_at(AT_FDCWD, path, handle, &mount_id, 0) == -1) {
> > > +		if (errno == EOPNOTSUPP) {
> > > +			tst_res(TCONF,
> > > +				"filesystem %s does not support file handles",
> > > +				tst_device->fs_type);
> > 
> > Btw, here the tst_res() does not make much sense sice the code will
> > continue and we will exit the test with the tst_brk() below. Shouldn't
> > we use tst_brk() here as well?
> 
> Yes, we should be using tst_brk(...) instead. Thanks for picking this up.
>  
> > > +		}
> > > +		tst_brk(TBROK | TERRNO,
> > > +			"name_to_handle_at(AT_FDCWD, %s, ...) failed", path);
> > > +	}
> > > +}
> > > +
> > > +#endif
> > > +
> > >  #define INIT_FANOTIFY_MARK_TYPE(t) \
> > >  	{ FAN_MARK_ ## t, "FAN_MARK_" #t }

-- 
Matthew Bobrowski

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

* [LTP] [PATCH v2 1/3] syscalls/fanotify13: new test to verify FAN_REPORT_FID functionality
  2019-04-27  4:53     ` Matthew Bobrowski
  2019-05-07  7:40       ` Matthew Bobrowski
@ 2019-05-15 14:50       ` Amir Goldstein
  2019-05-19  4:39         ` Matthew Bobrowski
  1 sibling, 1 reply; 9+ messages in thread
From: Amir Goldstein @ 2019-05-15 14:50 UTC (permalink / raw)
  To: ltp

On Sat, Apr 27, 2019 at 7:53 AM Matthew Bobrowski
<mbobrowski@mbobrowski.org> wrote:
>
> On Fri, Apr 26, 2019 at 05:27:48PM +0200, Cyril Hrubis wrote:
> > Hi!
> > I've tried these tests on buildservice to check that there are no
> > problems on slightly older distributions and found two.
> >
> > The first one is that we do define fallback definitions in fanotify.h
> > but then ifdef the whole test code in #if defined(HAVE_SYS_FANOTIFY_H)
> > so that it's efectively disabled on older distros even with fallback
> > definitions in place. Also it's TST_TEST_TCONF() but that is just easy
> > to fix typo. I guess that we can remove the ifdef and sys/fanotify.h
> > include from the test sources since we conditionally include the
> > sys/fanotify.h in the local fanotify.h already.
>
> OK. In that case I can write a patch that is to be applied prior to this series
> which essentially just removes this specific preprocessor conditional directive
> from all the source files. Would you like me to do this?

If I understand the concern correctly, it is not really important
to address now for these new tests that check functionality only available
since kernel v5.1. It could be addressed by followup work.

>
> > The second one is that we fail to compile on older distributions because
> > of missing name_to_handle_at() so we need configure check for that
> > syscall and fallback definition in lapi/ header, or at least configure
> > check and ifdef in the fanotify_get_fid() function. Which should be as
> > easy as adding a name_to_handle_at line to AC_CHECK_FUNCS() in the
> > configure.ac and using the macro from config.h.
>
> Sure. I've gone ahead an updated it to accommodate for this. Prior to
> submitting through another patches series, changes can be found here:
> https://github.com/matthewbobrowski/ltp/commit/54264db0e574d2f90e716a510fcb1da11ee174dc.
>
> I think we can do better and also provide a fallback definition though,
> thoughts? Don't believe that it would take much effort.
>

No reason to do that. Those tests will only be supported on kernel >= v5.1
old distros are less interesting for these tests.

Please post the patches for  fanotify_dirent_3 branch.

Thanks,
Amir.

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

* [LTP] [PATCH v2 1/3] syscalls/fanotify13: new test to verify FAN_REPORT_FID functionality
  2019-05-15 14:50       ` Amir Goldstein
@ 2019-05-19  4:39         ` Matthew Bobrowski
  0 siblings, 0 replies; 9+ messages in thread
From: Matthew Bobrowski @ 2019-05-19  4:39 UTC (permalink / raw)
  To: ltp

On Wed, May 15, 2019 at 05:50:03PM +0300, Amir Goldstein wrote:
> > On Fri, Apr 26, 2019 at 05:27:48PM +0200, Cyril Hrubis wrote:
> > > Hi!
> > > I've tried these tests on buildservice to check that there are no
> > > problems on slightly older distributions and found two.
> > >
> > > The first one is that we do define fallback definitions in fanotify.h
> > > but then ifdef the whole test code in #if defined(HAVE_SYS_FANOTIFY_H)
> > > so that it's efectively disabled on older distros even with fallback
> > > definitions in place. Also it's TST_TEST_TCONF() but that is just easy
> > > to fix typo. I guess that we can remove the ifdef and sys/fanotify.h
> > > include from the test sources since we conditionally include the
> > > sys/fanotify.h in the local fanotify.h already.
> >
> > OK. In that case I can write a patch that is to be applied prior to this series
> > which essentially just removes this specific preprocessor conditional directive
> > from all the source files. Would you like me to do this?
> 
> If I understand the concern correctly, it is not really important
> to address now for these new tests that check functionality only available
> since kernel v5.1. It could be addressed by followup work.

OK, no problem, this is fine with me.
 
> > > The second one is that we fail to compile on older distributions because
> > > of missing name_to_handle_at() so we need configure check for that
> > > syscall and fallback definition in lapi/ header, or at least configure
> > > check and ifdef in the fanotify_get_fid() function. Which should be as
> > > easy as adding a name_to_handle_at line to AC_CHECK_FUNCS() in the
> > > configure.ac and using the macro from config.h.
> >
> > Sure. I've gone ahead an updated it to accommodate for this. Prior to
> > submitting through another patches series, changes can be found here:
> > https://github.com/matthewbobrowski/ltp/commit/54264db0e574d2f90e716a510fcb1da11ee174dc.
> >
> > I think we can do better and also provide a fallback definition though,
> > thoughts? Don't believe that it would take much effort.
> 
> No reason to do that. Those tests will only be supported on kernel >= v5.1
> old distros are less interesting for these tests.
> 
> Please post the patches for fanotify_dirent_3 branch.

OK. I've rebased fanotify_dirent_3 of upstream/master and resubmitting
the patch series now.

-- 
Matthew Bobrowski

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

end of thread, other threads:[~2019-05-19  4:39 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-04-20 12:49 [LTP] [PATCH v2 0/3] FAN_REPORT_FID and Directory Modification Events Matthew Bobrowski
2019-04-20 12:49 ` [LTP] [PATCH v2 1/3] syscalls/fanotify13: new test to verify FAN_REPORT_FID functionality Matthew Bobrowski
2019-04-26 15:27   ` Cyril Hrubis
2019-04-27  4:53     ` Matthew Bobrowski
2019-05-07  7:40       ` Matthew Bobrowski
2019-05-15 14:50       ` Amir Goldstein
2019-05-19  4:39         ` Matthew Bobrowski
2019-04-20 12:50 ` [LTP] [PATCH v2 2/3] syscalls/fanotify14: new test to validate FAN_REPORT_FID interface return values Matthew Bobrowski
2019-04-20 12:50 ` [LTP] [PATCH v2 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.