[LTP] [PATCH 5/5] fanotify21: Test reporting fd open errors with FAN_REPORT_FD_ERROR

Amir Goldstein amir73il@gmail.com
Wed Jan 22 18:24:40 CET 2025


Expect to get -EROFS as event->fd.
Expect to get -ESRCH instead of FAN_NOPIDFD.

Signed-off-by: Amir Goldstein <amir73il@gmail.com>
---
 .../kernel/syscalls/fanotify/fanotify21.c     | 61 ++++++++++++++++---
 1 file changed, 51 insertions(+), 10 deletions(-)

diff --git a/testcases/kernel/syscalls/fanotify/fanotify21.c b/testcases/kernel/syscalls/fanotify/fanotify21.c
index 4324019fa..8765767f2 100644
--- a/testcases/kernel/syscalls/fanotify/fanotify21.c
+++ b/testcases/kernel/syscalls/fanotify/fanotify21.c
@@ -57,7 +57,7 @@ static struct test_case_t {
 	{
 		"return invalid pidfd for event created by terminated child",
 		1,
-		FAN_NOPIDFD,
+		1,
 		0,
 	},
 	{
@@ -72,6 +72,8 @@ static int fanotify_fd;
 static char event_buf[BUF_SZ];
 static struct pidfd_fdinfo_t *self_pidfd_fdinfo;
 
+static int fd_error_unsupported;
+
 static struct pidfd_fdinfo_t *read_pidfd_fdinfo(int pidfd)
 {
 	char *fdinfo_path;
@@ -121,6 +123,15 @@ static void do_fork(void)
 static void do_setup(void)
 {
 	int pidfd;
+	int init_flags = FAN_REPORT_PIDFD;
+
+	if (tst_variant) {
+		fanotify_fd = -1;
+		fd_error_unsupported = fanotify_init_flags_supported_on_fs(FAN_REPORT_FD_ERROR, ".");
+		if (fd_error_unsupported)
+			return;
+		init_flags |= FAN_REPORT_FD_ERROR;
+	}
 
 	SAFE_TOUCH(TEST_FILE, 0666, NULL);
 
@@ -132,7 +143,7 @@ static void do_setup(void)
 	REQUIRE_FANOTIFY_INIT_FLAGS_SUPPORTED_ON_FS(FAN_REPORT_PIDFD,
 						    TEST_FILE);
 
-	fanotify_fd = SAFE_FANOTIFY_INIT(FAN_REPORT_PIDFD, O_RDWR);
+	fanotify_fd = SAFE_FANOTIFY_INIT(init_flags, O_RDWR);
 	SAFE_FANOTIFY_MARK(fanotify_fd, FAN_MARK_ADD, FAN_OPEN, AT_FDCWD,
 			   TEST_FILE);
 
@@ -150,8 +161,17 @@ static void do_test(unsigned int num)
 {
 	int i = 0, len;
 	struct test_case_t *tc = &test_cases[num];
+	int nopidfd_err = tc->want_pidfd_err ?
+			  (tst_variant ? -ESRCH : FAN_NOPIDFD) : 0;
+	int fd_err = (tc->remount_ro && tst_variant) ? -EROFS : 0;
 
-	tst_res(TINFO, "Test #%d: %s", num, tc->name);
+	tst_res(TINFO, "Test #%d.%d: %s %s", num, tst_variant, tc->name,
+			tst_variant ? "(FAN_REPORT_FD_ERROR)" : "");
+
+	if (fd_error_unsupported && tst_variant) {
+		FANOTIFY_INIT_FLAGS_ERR_MSG(FAN_REPORT_FD_ERROR, fd_error_unsupported);
+		return;
+	}
 
 	if (tc->remount_ro) {
 		/* SAFE_MOUNT fails to remount FUSE */
@@ -179,12 +199,12 @@ static void do_test(unsigned int num)
 	 */
 	len = read(fanotify_fd, event_buf, sizeof(event_buf));
 	if (len < 0) {
-		if (tc->remount_ro && errno == EROFS) {
+		if (tc->remount_ro && !fd_err && errno == EROFS) {
 			tst_res(TPASS, "cannot read event with rw fd from a ro fs");
 			return;
 		}
 		tst_brk(TBROK | TERRNO, "reading fanotify events failed");
-	} else if (tc->remount_ro) {
+	} else if (tc->remount_ro && !fd_err) {
 		tst_res(TFAIL, "got unexpected event with rw fd from a ro fs");
 	}
 	while (i < len) {
@@ -218,6 +238,28 @@ static void do_test(unsigned int num)
 			goto next_event;
 		}
 
+		/*
+		 * Check if event->fd reported any errors during
+		 * creation and whether they're expected.
+		 */
+		if (!fd_err && event->fd >= 0) {
+			tst_res(TPASS,
+				"event->fd %d is valid as expected",
+				event->fd);
+		} else if (fd_err && event->fd == fd_err) {
+			tst_res(TPASS,
+				"event->fd is error %d as expected",
+				event->fd);
+		} else if (fd_err) {
+			tst_res(TFAIL,
+				"event->fd is %d, but expected error %d",
+				event->fd, fd_err);
+		} else {
+			tst_res(TFAIL,
+				"event->fd creation failed with error %d",
+				event->fd);
+		}
+
 		/*
 		 * Check if pidfd information object reported any errors during
 		 * creation and whether they're expected.
@@ -229,20 +271,18 @@ static void do_test(unsigned int num)
 				(unsigned int)event->pid,
 				info->pidfd);
 			goto next_event;
-		} else if (tc->want_pidfd_err &&
-			   info->pidfd != tc->want_pidfd_err) {
+		} else if (tc->want_pidfd_err && info->pidfd != nopidfd_err) {
 			tst_res(TFAIL,
 				"pidfd set to an unexpected error: %d for pid: %u",
 				info->pidfd,
 				(unsigned int)event->pid);
 			goto next_event;
-		} else if (tc->want_pidfd_err &&
-			   info->pidfd == tc->want_pidfd_err) {
+		} else if (tc->want_pidfd_err && info->pidfd == nopidfd_err) {
 			tst_res(TPASS,
 				"pid: %u terminated before pidfd was created, "
 				"pidfd set to the value of: %d, as expected",
 				(unsigned int)event->pid,
-				FAN_NOPIDFD);
+				nopidfd_err);
 			goto next_event;
 		}
 
@@ -323,6 +363,7 @@ static struct tst_test test = {
 	.setup = do_setup,
 	.test = do_test,
 	.tcnt = ARRAY_SIZE(test_cases),
+	.test_variants = 2,
 	.cleanup = do_cleanup,
 	.all_filesystems = 1,
 	.needs_root = 1,
-- 
2.34.1



More information about the ltp mailing list