Linux Test Project
 help / color / mirror / Atom feed
* [LTP] [PATCH v2 0/5] fanotify: update pidfd tests for FAN_REPORT_TID
@ 2026-06-16 21:04 AnonymeMeow
  2026-06-16 21:04 ` [LTP] [PATCH v2 1/5] fanotify20: Skip FAN_REPORT_PIDFD | FAN_REPORT_TID test on v7.2+ AnonymeMeow
                   ` (4 more replies)
  0 siblings, 5 replies; 7+ messages in thread
From: AnonymeMeow @ 2026-06-16 21:04 UTC (permalink / raw)
  To: jack; +Cc: amir73il, ltp, AnonymeMeow

This patch set updates fanotify pidfd tests for the kernel change that
adds FAN_REPORT_PIDFD support together with FAN_REPORT_TID.

Link: https://lore.kernel.org/lkml/20260607003343.425939-1-anonymemeow@gmail.com/

---

Changes since v1:
 - Added upstream commit reference in comment
 - skip FAN_REPORT_PIDFD | FAN_REPORT_TID tests for kernel v7.2+
 - Added pthread link flag

v1: https://lore.kernel.org/ltp/20260615180629.7148-1-anonymemeow@gmail.com/

---

AnonymeMeow (5):
  fanotify20: Skip FAN_REPORT_PIDFD | FAN_REPORT_TID test on v7.2+
  fanotify21: Stop relying on exited child for pidfd error
  fanotify21: Simplify read_pidfd_fdinfo()
  fanotify21: Add test variants for FAN_REPORT_TID
  fanotify21: Add FAN_REPORT_TID pidfd coverage

 include/lapi/pidfd.h                          |   4 +
 testcases/kernel/syscalls/fanotify/Makefile   |   2 +-
 .../kernel/syscalls/fanotify/fanotify20.c     |  14 +-
 .../kernel/syscalls/fanotify/fanotify21.c     | 192 +++++++++++-------
 4 files changed, 135 insertions(+), 77 deletions(-)

-- 
2.54.0


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

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

* [LTP] [PATCH v2 1/5] fanotify20: Skip FAN_REPORT_PIDFD | FAN_REPORT_TID test on v7.2+
  2026-06-16 21:04 [LTP] [PATCH v2 0/5] fanotify: update pidfd tests for FAN_REPORT_TID AnonymeMeow
@ 2026-06-16 21:04 ` AnonymeMeow
  2026-06-17  7:37   ` [LTP] " linuxtestproject.agent
  2026-06-16 21:04 ` [LTP] [PATCH v2 2/5] fanotify21: Stop relying on exited child for pidfd error AnonymeMeow
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 7+ messages in thread
From: AnonymeMeow @ 2026-06-16 21:04 UTC (permalink / raw)
  To: jack; +Cc: amir73il, ltp, AnonymeMeow

fanotify_init() used to reject FAN_REPORT_PIDFD combined with
FAN_REPORT_TID with EINVAL. Since Linux v7.2, fanotify supports
reporting pidfds for thread IDs, so this combination is expected to
succeed.

Signed-off-by: AnonymeMeow <anonymemeow@gmail.com>
---
 testcases/kernel/syscalls/fanotify/fanotify20.c | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/testcases/kernel/syscalls/fanotify/fanotify20.c b/testcases/kernel/syscalls/fanotify/fanotify20.c
index b32ecf6aa..f395d77ee 100644
--- a/testcases/kernel/syscalls/fanotify/fanotify20.c
+++ b/testcases/kernel/syscalls/fanotify/fanotify20.c
@@ -8,13 +8,15 @@
 
 /*\
  * This source file contains a test case which ensures that the
- * :manpage:`fanotify(7)` API returns an expected error code when provided an
- * invalid initialization flag alongside FAN_REPORT_PIDFD. Additionally, it
- * checks that the operability with existing FAN_REPORT_* flags is maintained
- * and functioning as intended.
+ * :manpage:`fanotify(7)` API returns an expected error code when provided
+ * unsupported initialization flags, e.g. FAN_REPORT_PIDFD combined with
+ * FAN_REPORT_TID. Additionally, it checks that the operability with
+ * supported FAN_REPORT_* flags is maintained and functioning as intended.
  *
  * NOTE: FAN_REPORT_PIDFD support was added in v5.15-rc1 in
  * af579beb666a ("fanotify: add pidfd support to the fanotify API").
+ * FAN_REPORT_PIDFD combined with FAN_REPORT_TID is supported since v7.2-rc1
+ * in 17171128513b ("fanotify: report thread pidfds for FAN_REPORT_TID").
  */
 
 #define _GNU_SOURCE
@@ -45,6 +47,10 @@ static struct test_case_t {
 
 static void do_setup(void)
 {
+	if (tst_kvercmp(7, 2, 0) >= 0)
+		tst_brk(TCONF, "FAN_REPORT_PIDFD | FAN_REPORT_TID is supported "
+			       "since v7.2, skipping test");
+
 	/*
 	 * An explicit check for FAN_REPORT_PIDFD is performed early on in the
 	 * test initialization as it's a prerequisite for all test cases.
-- 
2.54.0


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

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

* [LTP] [PATCH v2 2/5] fanotify21: Stop relying on exited child for pidfd error
  2026-06-16 21:04 [LTP] [PATCH v2 0/5] fanotify: update pidfd tests for FAN_REPORT_TID AnonymeMeow
  2026-06-16 21:04 ` [LTP] [PATCH v2 1/5] fanotify20: Skip FAN_REPORT_PIDFD | FAN_REPORT_TID test on v7.2+ AnonymeMeow
@ 2026-06-16 21:04 ` AnonymeMeow
  2026-06-16 21:04 ` [LTP] [PATCH v2 3/5] fanotify21: Simplify read_pidfd_fdinfo() AnonymeMeow
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: AnonymeMeow @ 2026-06-16 21:04 UTC (permalink / raw)
  To: jack; +Cc: amir73il, ltp, AnonymeMeow

fanotify21 used to verify the pidfd error case by generating an event
from a child process and reading the event after the child had exited.
This is no longer a stable way to trigger a pidfd error, because newer
kernels can report pidfds for exited event processes.

Read the event from a child process in a descendant PID namespace
instead. The reader cannot get the pidfd in the parent PID namespace
from fanotify, so pidfd creation will fail and the test can verify
FAN_NOPIDFD, or -ESRCH with FAN_REPORT_FD_ERROR.

Signed-off-by: AnonymeMeow <anonymemeow@gmail.com>
Reviewed-by: Jan Kara <jack@suse.cz>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
---
 .../kernel/syscalls/fanotify/fanotify21.c     | 55 ++++++++-----------
 1 file changed, 24 insertions(+), 31 deletions(-)

diff --git a/testcases/kernel/syscalls/fanotify/fanotify21.c b/testcases/kernel/syscalls/fanotify/fanotify21.c
index 4d2115469..bd1a43513 100644
--- a/testcases/kernel/syscalls/fanotify/fanotify21.c
+++ b/testcases/kernel/syscalls/fanotify/fanotify21.c
@@ -42,7 +42,6 @@ struct pidfd_fdinfo_t {
 
 static struct test_case_t {
 	char *name;
-	int fork;
 	int want_pidfd_err;
 	int remount_ro;
 } test_cases[] = {
@@ -50,18 +49,15 @@ static struct test_case_t {
 		"return a valid pidfd for event created by self",
 		0,
 		0,
-		0,
 	},
 	{
-		"return invalid pidfd for event created by terminated child",
-		1,
+		"return invalid pidfd for reader in descendant PID namespace",
 		1,
 		0,
 	},
 	{
 		"fail to open rw fd for event created on read-only mount",
 		0,
-		0,
 		1,
 	},
 };
@@ -72,6 +68,11 @@ static struct pidfd_fdinfo_t *self_pidfd_fdinfo;
 
 static int fd_error_unsupported;
 
+static struct tst_clone_args clone_args = {
+	.flags = CLONE_NEWPID,
+	.exit_signal = SIGCHLD,
+};
+
 static struct pidfd_fdinfo_t *read_pidfd_fdinfo(int pidfd)
 {
 	char *fdinfo_path;
@@ -100,24 +101,6 @@ static void generate_event(void)
 	SAFE_CLOSE(fd);
 }
 
-static void do_fork(void)
-{
-	int status;
-	pid_t child;
-
-	child = SAFE_FORK();
-	if (child == 0) {
-		SAFE_CLOSE(fanotify_fd);
-		generate_event();
-		exit(EXIT_SUCCESS);
-	}
-
-	SAFE_WAITPID(child, &status, 0);
-	if (WIFEXITED(status) && WEXITSTATUS(status) != 0)
-		tst_brk(TBROK,
-			"child process terminated incorrectly");
-}
-
 static void do_setup(void)
 {
 	int pidfd;
@@ -165,6 +148,8 @@ static void do_test(unsigned int num)
 	int nopidfd_err = tc->want_pidfd_err ?
 			  (tst_variant ? -ESRCH : FAN_NOPIDFD) : 0;
 	int fd_err = (tc->remount_ro && tst_variant) ? -EROFS : 0;
+	pid_t reader_pid;
+	int reader_exit_status;
 
 	tst_res(TINFO, "Test #%d.%d: %s %s", num, tst_variant, tc->name,
 			tst_variant ? "(FAN_REPORT_FD_ERROR)" : "");
@@ -178,15 +163,20 @@ static void do_test(unsigned int num)
 	SAFE_MOUNT("none", MOUNT_PATH, "none", MS_BIND | MS_REMOUNT |
 		   (tc->remount_ro ? MS_RDONLY : 0), NULL);
 
+	generate_event();
+
 	/*
-	 * Generate the event in either self or a child process. Event
-	 * generation in a child process is done so that the FAN_NOPIDFD case
-	 * can be verified.
+	 * Read the event in either self or a child process in a descendant
+	 * PID namespace. A reader in a descendant PID namespace cannot obtain
+	 * the pidfd of the event process in the parent PID namespace so that
+	 * the FAN_NOPIDFD case can be verified.
 	 */
-	if (tc->fork)
-		do_fork();
-	else
-		generate_event();
+	if (tc->want_pidfd_err && (reader_pid = SAFE_CLONE(&clone_args))) {
+		SAFE_WAITPID(reader_pid, &reader_exit_status, 0);
+		if (!WIFEXITED(reader_exit_status) || WEXITSTATUS(reader_exit_status))
+			tst_brk(TBROK, "reader process exited incorrectly");
+		return;
+	}
 
 	/*
 	 * Read all of the queued events into the provided event
@@ -274,7 +264,7 @@ static void do_test(unsigned int num)
 			goto next_event;
 		} else if (tc->want_pidfd_err && info->pidfd == nopidfd_err) {
 			tst_res(TPASS,
-				"pid: %u terminated before pidfd was created, "
+				"pid: %u is invisible in reader PID namespace, "
 				"pidfd set to the value of: %d, as expected",
 				(unsigned int)event->pid,
 				nopidfd_err);
@@ -343,6 +333,9 @@ next_event:
 		if (event_pidfd_fdinfo)
 			free(event_pidfd_fdinfo);
 	}
+
+	if (tc->want_pidfd_err)
+		exit(0);
 }
 
 static void do_cleanup(void)
-- 
2.54.0


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

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

* [LTP] [PATCH v2 3/5] fanotify21: Simplify read_pidfd_fdinfo()
  2026-06-16 21:04 [LTP] [PATCH v2 0/5] fanotify: update pidfd tests for FAN_REPORT_TID AnonymeMeow
  2026-06-16 21:04 ` [LTP] [PATCH v2 1/5] fanotify20: Skip FAN_REPORT_PIDFD | FAN_REPORT_TID test on v7.2+ AnonymeMeow
  2026-06-16 21:04 ` [LTP] [PATCH v2 2/5] fanotify21: Stop relying on exited child for pidfd error AnonymeMeow
@ 2026-06-16 21:04 ` AnonymeMeow
  2026-06-16 21:04 ` [LTP] [PATCH v2 4/5] fanotify21: Add test variants for FAN_REPORT_TID AnonymeMeow
  2026-06-16 21:04 ` [LTP] [PATCH v2 5/5] fanotify21: Add FAN_REPORT_TID pidfd coverage AnonymeMeow
  4 siblings, 0 replies; 7+ messages in thread
From: AnonymeMeow @ 2026-06-16 21:04 UTC (permalink / raw)
  To: jack; +Cc: amir73il, ltp, AnonymeMeow

Let callers provide storage for struct pidfd_fdinfo_t instead of
allocating it in read_pidfd_fdinfo() every time. This removes
unnecessary allocation/free paths and the NULL checks after
read_pidfd_fdinfo() and simplifies the code.

Signed-off-by: AnonymeMeow <anonymemeow@gmail.com>
Reviewed-by: Jan Kara <jack@suse.cz>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
---
 .../kernel/syscalls/fanotify/fanotify21.c     | 61 ++++++-------------
 1 file changed, 20 insertions(+), 41 deletions(-)

diff --git a/testcases/kernel/syscalls/fanotify/fanotify21.c b/testcases/kernel/syscalls/fanotify/fanotify21.c
index bd1a43513..22f9767db 100644
--- a/testcases/kernel/syscalls/fanotify/fanotify21.c
+++ b/testcases/kernel/syscalls/fanotify/fanotify21.c
@@ -64,7 +64,7 @@ static struct test_case_t {
 
 static int fanotify_fd;
 static char event_buf[BUF_SZ];
-static struct pidfd_fdinfo_t *self_pidfd_fdinfo;
+static struct pidfd_fdinfo_t exp_pidfd_fdinfo;
 
 static int fd_error_unsupported;
 
@@ -73,12 +73,9 @@ static struct tst_clone_args clone_args = {
 	.exit_signal = SIGCHLD,
 };
 
-static struct pidfd_fdinfo_t *read_pidfd_fdinfo(int pidfd)
+static void read_pidfd_fdinfo(int pidfd, struct pidfd_fdinfo_t *pidfd_fdinfo)
 {
 	char *fdinfo_path;
-	struct pidfd_fdinfo_t *pidfd_fdinfo;
-
-	pidfd_fdinfo = SAFE_MALLOC(sizeof(struct pidfd_fdinfo_t));
 
 	SAFE_ASPRINTF(&fdinfo_path, "/proc/self/fdinfo/%d", pidfd);
 	SAFE_FILE_LINES_SCANF(fdinfo_path, "pos: %d", &pidfd_fdinfo->pos);
@@ -88,8 +85,6 @@ static struct pidfd_fdinfo_t *read_pidfd_fdinfo(int pidfd)
 	SAFE_FILE_LINES_SCANF(fdinfo_path, "NSpid: %d", &pidfd_fdinfo->ns_pid);
 
 	free(fdinfo_path);
-
-	return pidfd_fdinfo;
 }
 
 static void generate_event(void)
@@ -133,12 +128,9 @@ static void do_setup(void)
 
 	pidfd = SAFE_PIDFD_OPEN(getpid(), 0);
 
-	self_pidfd_fdinfo = read_pidfd_fdinfo(pidfd);
-	if (self_pidfd_fdinfo == NULL) {
-		tst_brk(TBROK,
-			"pidfd=%d, failed to read pidfd fdinfo",
-			pidfd);
-	}
+	read_pidfd_fdinfo(pidfd, &exp_pidfd_fdinfo);
+
+	SAFE_CLOSE(pidfd);
 }
 
 static void do_test(unsigned int num)
@@ -195,7 +187,7 @@ static void do_test(unsigned int num)
 	while (i < len) {
 		struct fanotify_event_metadata *event;
 		struct fanotify_event_info_pidfd *info;
-		struct pidfd_fdinfo_t *event_pidfd_fdinfo = NULL;
+		struct pidfd_fdinfo_t event_pidfd_fdinfo;
 
 		event = (struct fanotify_event_metadata *)&event_buf[i];
 		info = (struct fanotify_event_info_pidfd *)(event + 1);
@@ -275,39 +267,32 @@ static void do_test(unsigned int num)
 		 * No pidfd errors occurred, continue with verifying pidfd
 		 * fdinfo validity.
 		 */
-		event_pidfd_fdinfo = read_pidfd_fdinfo(info->pidfd);
-		if (event_pidfd_fdinfo == NULL) {
-			tst_brk(TBROK,
-				"reading fdinfo for pidfd: %d "
-				"describing pid: %u failed",
-				info->pidfd,
-				(unsigned int)event->pid);
-			goto next_event;
-		} else if (event_pidfd_fdinfo->pid != event->pid) {
+		read_pidfd_fdinfo(info->pidfd, &event_pidfd_fdinfo);
+		if (event_pidfd_fdinfo.pid != event->pid) {
 			tst_res(TFAIL,
 				"pidfd provided for incorrect pid "
 				"(expected pidfd for pid: %u, got pidfd for "
 				"pid: %u)",
 				(unsigned int)event->pid,
-				(unsigned int)event_pidfd_fdinfo->pid);
+				(unsigned int)event_pidfd_fdinfo.pid);
 			goto next_event;
-		} else if (memcmp(event_pidfd_fdinfo, self_pidfd_fdinfo,
+		} else if (memcmp(&event_pidfd_fdinfo, &exp_pidfd_fdinfo,
 				  sizeof(struct pidfd_fdinfo_t))) {
 			tst_res(TFAIL,
 				"pidfd fdinfo values for self and event differ "
 				"(expected pos: %d, flags: %x, mnt_id: %d, "
 				"pid: %d, ns_pid: %d, got pos: %d, "
 				"flags: %x, mnt_id: %d, pid: %d, ns_pid: %d",
-				self_pidfd_fdinfo->pos,
-				self_pidfd_fdinfo->flags,
-				self_pidfd_fdinfo->mnt_id,
-				self_pidfd_fdinfo->pid,
-				self_pidfd_fdinfo->ns_pid,
-				event_pidfd_fdinfo->pos,
-				event_pidfd_fdinfo->flags,
-				event_pidfd_fdinfo->mnt_id,
-				event_pidfd_fdinfo->pid,
-				event_pidfd_fdinfo->ns_pid);
+				exp_pidfd_fdinfo.pos,
+				exp_pidfd_fdinfo.flags,
+				exp_pidfd_fdinfo.mnt_id,
+				exp_pidfd_fdinfo.pid,
+				exp_pidfd_fdinfo.ns_pid,
+				event_pidfd_fdinfo.pos,
+				event_pidfd_fdinfo.flags,
+				event_pidfd_fdinfo.mnt_id,
+				event_pidfd_fdinfo.pid,
+				event_pidfd_fdinfo.ns_pid);
 			goto next_event;
 		} else {
 			tst_res(TPASS,
@@ -329,9 +314,6 @@ next_event:
 
 		if (info && info->pidfd >= 0)
 			SAFE_CLOSE(info->pidfd);
-
-		if (event_pidfd_fdinfo)
-			free(event_pidfd_fdinfo);
 	}
 
 	if (tc->want_pidfd_err)
@@ -343,9 +325,6 @@ static void do_cleanup(void)
 	if (fanotify_fd >= 0)
 		SAFE_CLOSE(fanotify_fd);
 
-	if (self_pidfd_fdinfo)
-		free(self_pidfd_fdinfo);
-
 	/* Unmount the bind mount */
 	SAFE_UMOUNT(MOUNT_PATH);
 }
-- 
2.54.0


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

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

* [LTP] [PATCH v2 4/5] fanotify21: Add test variants for FAN_REPORT_TID
  2026-06-16 21:04 [LTP] [PATCH v2 0/5] fanotify: update pidfd tests for FAN_REPORT_TID AnonymeMeow
                   ` (2 preceding siblings ...)
  2026-06-16 21:04 ` [LTP] [PATCH v2 3/5] fanotify21: Simplify read_pidfd_fdinfo() AnonymeMeow
@ 2026-06-16 21:04 ` AnonymeMeow
  2026-06-16 21:04 ` [LTP] [PATCH v2 5/5] fanotify21: Add FAN_REPORT_TID pidfd coverage AnonymeMeow
  4 siblings, 0 replies; 7+ messages in thread
From: AnonymeMeow @ 2026-06-16 21:04 UTC (permalink / raw)
  To: jack; +Cc: amir73il, ltp, AnonymeMeow

Add test variants for FAN_REPORT_PIDFD combined with FAN_REPORT_TID,
both with and without FAN_REPORT_FD_ERROR. Add PIDFD_THREAD fallback
definition for old headers.

Signed-off-by: AnonymeMeow <anonymemeow@gmail.com>
Reviewed-by: Jan Kara <jack@suse.cz>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
---
 include/lapi/pidfd.h                          |  4 ++
 .../kernel/syscalls/fanotify/fanotify21.c     | 57 ++++++++++++++-----
 2 files changed, 48 insertions(+), 13 deletions(-)

diff --git a/include/lapi/pidfd.h b/include/lapi/pidfd.h
index a3205032c..eb4e3466d 100644
--- a/include/lapi/pidfd.h
+++ b/include/lapi/pidfd.h
@@ -43,6 +43,10 @@ struct pidfd_info {
 # define PIDFD_NONBLOCK O_NONBLOCK
 #endif
 
+#ifndef PIDFD_THREAD
+# define PIDFD_THREAD O_EXCL
+#endif
+
 #ifndef PIDFS_IOCTL_MAGIC
 # define PIDFS_IOCTL_MAGIC	0xFF
 #endif
diff --git a/testcases/kernel/syscalls/fanotify/fanotify21.c b/testcases/kernel/syscalls/fanotify/fanotify21.c
index 22f9767db..c05c69d58 100644
--- a/testcases/kernel/syscalls/fanotify/fanotify21.c
+++ b/testcases/kernel/syscalls/fanotify/fanotify21.c
@@ -12,6 +12,8 @@
  *
  * NOTE: FAN_REPORT_PIDFD support was added in v5.15-rc1 in
  * af579beb666a ("fanotify: add pidfd support to the fanotify API").
+ * FAN_REPORT_PIDFD combined with FAN_REPORT_TID is supported since v7.2-rc1
+ * in 17171128513b ("fanotify: report thread pidfds for FAN_REPORT_TID").
  */
 
 #define _GNU_SOURCE
@@ -32,6 +34,9 @@
 #define MOUNT_PATH	"fs_mnt"
 #define TEST_FILE	MOUNT_PATH "/testfile"
 
+#define TST_VARIANT_FD_ERROR (tst_variant & 1)
+#define TST_VARIANT_PIDFD_THREAD (tst_variant & 2)
+
 struct pidfd_fdinfo_t {
 	int pos;
 	int flags;
@@ -67,6 +72,7 @@ static char event_buf[BUF_SZ];
 static struct pidfd_fdinfo_t exp_pidfd_fdinfo;
 
 static int fd_error_unsupported;
+static int thread_pidfd_unsupported;
 
 static struct tst_clone_args clone_args = {
 	.flags = CLONE_NEWPID,
@@ -90,21 +96,37 @@ static void read_pidfd_fdinfo(int pidfd, struct pidfd_fdinfo_t *pidfd_fdinfo)
 static void generate_event(void)
 {
 	int fd;
+	int pidfd;
+
+	pidfd = TST_VARIANT_PIDFD_THREAD ? SAFE_PIDFD_OPEN(tst_gettid(), PIDFD_THREAD)
+					 : SAFE_PIDFD_OPEN(tst_getpid(), 0);
+	read_pidfd_fdinfo(pidfd, &exp_pidfd_fdinfo);
+	SAFE_CLOSE(pidfd);
 
 	/* Generate a single FAN_OPEN event on the watched object. */
 	fd = SAFE_OPEN(TEST_FILE, O_RDONLY);
 	SAFE_CLOSE(fd);
 }
 
+static const char *test_variant_name(void)
+{
+	switch (tst_variant) {
+	case 0: return "";
+	case 1: return "(FAN_REPORT_FD_ERROR)";
+	case 2: return "(FAN_REPORT_TID)";
+	case 3: return "(FAN_REPORT_FD_ERROR | FAN_REPORT_TID)";
+	}
+	return NULL;
+}
+
 static void do_setup(void)
 {
-	int pidfd;
 	int init_flags = FAN_REPORT_PIDFD;
 
 	/* Bind mount so remount ro/rw always work */
 	SAFE_MOUNT(MOUNT_PATH, MOUNT_PATH, "none", MS_BIND, NULL);
 
-	if (tst_variant) {
+	if (TST_VARIANT_FD_ERROR) {
 		fanotify_fd = -1;
 		fd_error_unsupported = fanotify_init_flags_supported_on_fs(FAN_REPORT_FD_ERROR, ".");
 		if (fd_error_unsupported)
@@ -112,6 +134,15 @@ static void do_setup(void)
 		init_flags |= FAN_REPORT_FD_ERROR;
 	}
 
+	if (TST_VARIANT_PIDFD_THREAD) {
+		fanotify_fd = -1;
+		thread_pidfd_unsupported = fanotify_init_flags_supported_on_fs(
+			FAN_REPORT_PIDFD | FAN_REPORT_TID, ".");
+		if (thread_pidfd_unsupported)
+			return;
+		init_flags |= FAN_REPORT_TID;
+	}
+
 	SAFE_TOUCH(TEST_FILE, 0666, NULL);
 
 	/*
@@ -125,12 +156,6 @@ static void do_setup(void)
 	fanotify_fd = SAFE_FANOTIFY_INIT(init_flags, O_RDWR);
 	SAFE_FANOTIFY_MARK(fanotify_fd, FAN_MARK_ADD, FAN_OPEN, AT_FDCWD,
 			   TEST_FILE);
-
-	pidfd = SAFE_PIDFD_OPEN(getpid(), 0);
-
-	read_pidfd_fdinfo(pidfd, &exp_pidfd_fdinfo);
-
-	SAFE_CLOSE(pidfd);
 }
 
 static void do_test(unsigned int num)
@@ -138,19 +163,25 @@ 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_VARIANT_FD_ERROR ? -ESRCH : FAN_NOPIDFD) : 0;
+	int fd_err = (tc->remount_ro && TST_VARIANT_FD_ERROR) ? -EROFS : 0;
 	pid_t reader_pid;
 	int reader_exit_status;
 
 	tst_res(TINFO, "Test #%d.%d: %s %s", num, tst_variant, tc->name,
-			tst_variant ? "(FAN_REPORT_FD_ERROR)" : "");
+		       test_variant_name());
 
-	if (fd_error_unsupported && tst_variant) {
+	if (fd_error_unsupported && TST_VARIANT_FD_ERROR) {
 		FANOTIFY_INIT_FLAGS_ERR_MSG(FAN_REPORT_FD_ERROR, fd_error_unsupported);
 		return;
 	}
 
+	if (thread_pidfd_unsupported && TST_VARIANT_PIDFD_THREAD) {
+		FANOTIFY_INIT_FLAGS_ERR_MSG(
+			FAN_REPORT_PIDFD | FAN_REPORT_TID, thread_pidfd_unsupported);
+		return;
+	}
+
 	/* remount ro/rw the bind mount */
 	SAFE_MOUNT("none", MOUNT_PATH, "none", MS_BIND | MS_REMOUNT |
 		   (tc->remount_ro ? MS_RDONLY : 0), NULL);
@@ -333,7 +364,7 @@ static struct tst_test test = {
 	.setup = do_setup,
 	.test = do_test,
 	.tcnt = ARRAY_SIZE(test_cases),
-	.test_variants = 2,
+	.test_variants = 4,
 	.cleanup = do_cleanup,
 	.all_filesystems = 1,
 	.needs_root = 1,
-- 
2.54.0


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

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

* [LTP] [PATCH v2 5/5] fanotify21: Add FAN_REPORT_TID pidfd coverage
  2026-06-16 21:04 [LTP] [PATCH v2 0/5] fanotify: update pidfd tests for FAN_REPORT_TID AnonymeMeow
                   ` (3 preceding siblings ...)
  2026-06-16 21:04 ` [LTP] [PATCH v2 4/5] fanotify21: Add test variants for FAN_REPORT_TID AnonymeMeow
@ 2026-06-16 21:04 ` AnonymeMeow
  4 siblings, 0 replies; 7+ messages in thread
From: AnonymeMeow @ 2026-06-16 21:04 UTC (permalink / raw)
  To: jack; +Cc: amir73il, ltp, AnonymeMeow

Add a test case that generates an event from a thread. Without
FAN_REPORT_TID, the reported pidfd is expected to refer to the thread
group leader. With FAN_REPORT_TID, it is expected to refer to the
triggering thread. Keep the event thread alive until the reported pidfd
is verified, because pidfd fdinfo reports Pid: -1 after the thread
exits.

Signed-off-by: AnonymeMeow <anonymemeow@gmail.com>
---

This patch is exactly the same as v1 except that the pthread link flag
is added to fanotify21 target.

---
 testcases/kernel/syscalls/fanotify/Makefile   |  2 +-
 .../kernel/syscalls/fanotify/fanotify21.c     | 47 ++++++++++++++++++-
 2 files changed, 47 insertions(+), 2 deletions(-)

diff --git a/testcases/kernel/syscalls/fanotify/Makefile b/testcases/kernel/syscalls/fanotify/Makefile
index 3628094ba..b20bb50e9 100644
--- a/testcases/kernel/syscalls/fanotify/Makefile
+++ b/testcases/kernel/syscalls/fanotify/Makefile
@@ -2,7 +2,7 @@
 #  Copyright (c) Jan Kara <jack@suse.cz>, 2013
 
 top_srcdir		?= ../../../..
-fanotify11: CFLAGS+=-pthread
+fanotify11 fanotify21: CFLAGS+=-pthread
 include $(top_srcdir)/include/mk/testcases.mk
 
 include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/syscalls/fanotify/fanotify21.c b/testcases/kernel/syscalls/fanotify/fanotify21.c
index c05c69d58..c97ec4f92 100644
--- a/testcases/kernel/syscalls/fanotify/fanotify21.c
+++ b/testcases/kernel/syscalls/fanotify/fanotify21.c
@@ -25,6 +25,7 @@
 #include "tst_test.h"
 #include "tst_safe_stdio.h"
 #include "tst_safe_macros.h"
+#include "tst_safe_pthread.h"
 #include "lapi/pidfd.h"
 
 #ifdef HAVE_SYS_FANOTIFY_H
@@ -47,6 +48,7 @@ struct pidfd_fdinfo_t {
 
 static struct test_case_t {
 	char *name;
+	int event_by_thread;
 	int want_pidfd_err;
 	int remount_ro;
 } test_cases[] = {
@@ -54,15 +56,24 @@ static struct test_case_t {
 		"return a valid pidfd for event created by self",
 		0,
 		0,
+		0,
+	},
+	{
+		"return a valid pidfd for event created by thread",
+		1,
+		0,
+		0,
 	},
 	{
 		"return invalid pidfd for reader in descendant PID namespace",
+		0,
 		1,
 		0,
 	},
 	{
 		"fail to open rw fd for event created on read-only mount",
 		0,
+		0,
 		1,
 	},
 };
@@ -108,6 +119,26 @@ static void generate_event(void)
 	SAFE_CLOSE(fd);
 }
 
+static void *generate_event_pthread(void *args LTP_ATTRIBUTE_UNUSED)
+{
+	generate_event();
+	TST_CHECKPOINT_WAIT(0);
+	return NULL;
+}
+
+static pthread_t event_thread_create(void)
+{
+	pthread_t pthread_id;
+	SAFE_PTHREAD_CREATE(&pthread_id, NULL, generate_event_pthread, NULL);
+	return pthread_id;
+}
+
+static void event_thread_join(pthread_t pthread_id)
+{
+	TST_CHECKPOINT_WAKE(0);
+	SAFE_PTHREAD_JOIN(pthread_id, NULL);
+}
+
 static const char *test_variant_name(void)
 {
 	switch (tst_variant) {
@@ -165,6 +196,7 @@ static void do_test(unsigned int num)
 	int nopidfd_err = tc->want_pidfd_err ?
 			  (TST_VARIANT_FD_ERROR ? -ESRCH : FAN_NOPIDFD) : 0;
 	int fd_err = (tc->remount_ro && TST_VARIANT_FD_ERROR) ? -EROFS : 0;
+	pthread_t event_thread;
 	pid_t reader_pid;
 	int reader_exit_status;
 
@@ -186,7 +218,16 @@ static void do_test(unsigned int num)
 	SAFE_MOUNT("none", MOUNT_PATH, "none", MS_BIND | MS_REMOUNT |
 		   (tc->remount_ro ? MS_RDONLY : 0), NULL);
 
-	generate_event();
+	/*
+	 * Generate the event by either self or a thread. Event generation in
+	 * a thread is done so that in FAN_REPORT_TID mode the pidfd can be
+	 * verified to refer to the tid, not the tgid. The thread waits until
+	 * the pidfd is verified before exiting.
+	 */
+	if (tc->event_by_thread)
+		event_thread = event_thread_create();
+	else
+		generate_event();
 
 	/*
 	 * Read the event in either self or a child process in a descendant
@@ -349,6 +390,9 @@ next_event:
 
 	if (tc->want_pidfd_err)
 		exit(0);
+
+	if (tc->event_by_thread)
+		event_thread_join(event_thread);
 }
 
 static void do_cleanup(void)
@@ -371,6 +415,7 @@ static struct tst_test test = {
 	.mount_device = 1,
 	.mntpoint = MOUNT_PATH,
 	.forks_child = 1,
+	.needs_checkpoints = 1,
 };
 
 #else
-- 
2.54.0


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

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

* Re: [LTP] fanotify20: Skip FAN_REPORT_PIDFD | FAN_REPORT_TID test on v7.2+
  2026-06-16 21:04 ` [LTP] [PATCH v2 1/5] fanotify20: Skip FAN_REPORT_PIDFD | FAN_REPORT_TID test on v7.2+ AnonymeMeow
@ 2026-06-17  7:37   ` linuxtestproject.agent
  0 siblings, 0 replies; 7+ messages in thread
From: linuxtestproject.agent @ 2026-06-17  7:37 UTC (permalink / raw)
  To: AnonymeMeow; +Cc: ltp

Hi AnonymeMeow,

On Wed, Jun 17, 2026, AnonymeMeow wrote:
> fanotify20: Skip FAN_REPORT_PIDFD | FAN_REPORT_TID test on v7.2+

--- [PATCH 1/5] ---

> +	if (tst_kvercmp(7, 2, 0) >= 0)
> +		tst_brk(TCONF, "FAN_REPORT_PIDFD | FAN_REPORT_TID is supported "
> +			       "since v7.2, skipping test");

tst_brk(TCONF) in setup aborts ALL test cases. The second test case
(FAN_REPORT_PIDFD | FAN_REPORT_FID | FAN_REPORT_DFID_NAME expected to
succeed) is still valid on v7.2+ but will never run.

Should this be a per-test-case skip instead, so that only the EINVAL
case is skipped on v7.2+?

--- [PATCH 4/5] ---

> fanotify21: Add test variants for FAN_REPORT_TID

> +	if (TST_VARIANT_PIDFD_THREAD) {
> +		fanotify_fd = -1;
> +		thread_pidfd_unsupported = fanotify_init_flags_supported_on_fs(
> +			FAN_REPORT_PIDFD | FAN_REPORT_TID, ".");
> +		if (thread_pidfd_unsupported)
> +			return;
> +		init_flags |= FAN_REPORT_TID;
> +	}

FAN_REPORT_PIDFD combined with FAN_REPORT_TID is a v7.2 feature and
v7.2 has not been released yet (latest stable is v7.1). Per LTP
convention, tests exercising unreleased kernel features need a
[STAGING] subject prefix and should go into runtest/staging until
the kernel release is finalized.

This applies to patches 4/5 and 5/5 which add FAN_REPORT_TID variant
coverage.

Verdict - Needs revision

Pre-existing issues (not introduced by this series):

- testcases/kernel/syscalls/fanotify/Makefile: per-target CFLAGS is
  placed before testcases.mk instead of between the two includes.
- testcases/kernel/syscalls/fanotify/fanotify21.c: `fanotify_fd` is
  initialized to 0 (implicit) and the cleanup guard uses `>= 0`
  instead of the LTP-conventional `-1` init + `!= -1` guard.

---
Note:

The agent can sometimes produce false positives although often its
findings are genuine. If you find issues with the review, please
comment this email or ignore the suggestions.

Regards,
LTP AI Reviewer

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

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

end of thread, other threads:[~2026-06-17  7:38 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-16 21:04 [LTP] [PATCH v2 0/5] fanotify: update pidfd tests for FAN_REPORT_TID AnonymeMeow
2026-06-16 21:04 ` [LTP] [PATCH v2 1/5] fanotify20: Skip FAN_REPORT_PIDFD | FAN_REPORT_TID test on v7.2+ AnonymeMeow
2026-06-17  7:37   ` [LTP] " linuxtestproject.agent
2026-06-16 21:04 ` [LTP] [PATCH v2 2/5] fanotify21: Stop relying on exited child for pidfd error AnonymeMeow
2026-06-16 21:04 ` [LTP] [PATCH v2 3/5] fanotify21: Simplify read_pidfd_fdinfo() AnonymeMeow
2026-06-16 21:04 ` [LTP] [PATCH v2 4/5] fanotify21: Add test variants for FAN_REPORT_TID AnonymeMeow
2026-06-16 21:04 ` [LTP] [PATCH v2 5/5] fanotify21: Add FAN_REPORT_TID pidfd coverage AnonymeMeow

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox