[LTP] [PATCH v1 1/2] newipc: Factor out generic get_ipc_idx_from_id() helper

Stephen Bertram sbertram@redhat.com
Thu Jul 30 21:49:50 CEST 2026


From: Stephen Bertram <sbertram@redhat.com>

get_shm_idx_from_id()'s per-index STAT loop will be needed again for
semctl01's SEM_STAT lookup. Move it into a generic get_ipc_idx_from_id()
helper in libs/newipc, taking a per-family stat() wrapper, so IPC tests
that need to translate an id to its live kernel index can share one
implementation instead of duplicating the loop.

shmctl01 is converted to use the new helper. No functional change.

Signed-off-by: Stephen Bertram <sbertram@redhat.com>
Assisted-by: Cursor:Sonnet-5
---
Test: ./kirk -w 4 -f syscalls_32 -p shmctl01 -i 1000
After changes:
Total runs:  32000
Runtime:    24m 57s
Passed:     384000
Failed:     0
Skipped:    0
Broken:     0
Warnings:   0

 include/tse_newipc.h                        | 20 ++++++++++++++++++++
 libs/newipc/tse_newipc.c                    | 13 +++++++++++++
 testcases/kernel/syscalls/shmctl/shmctl01.c | 14 +++++++-------
 3 files changed, 40 insertions(+), 7 deletions(-)

diff --git a/include/tse_newipc.h b/include/tse_newipc.h
index 1d3bbd129..175a60234 100644
--- a/include/tse_newipc.h
+++ b/include/tse_newipc.h
@@ -49,4 +49,24 @@ void *probe_free_addr(const char *file, const int lineno);
 #define PROBE_FREE_ADDR() \
 	probe_free_addr(__FILE__, __LINE__)
 
+/**
+ * get_ipc_idx_from_id() - Find the kernel index of an IPC resource by id.
+ *
+ * @id: The msqid/semid/shmid to look for.
+ * @max_idx: Highest kernel index to search, from IPC_INFO/SEM_INFO/SHM_INFO.
+ * @stat_fn: Per-family *_STAT wrapper called as stat_fn(idx, buf) for
+ *           each idx in [0, max_idx]; must return the id at idx, or -1
+ *           on error, without aborting the test.
+ * @buf: Buffer passed through to @stat_fn.
+ *
+ * SysV *_STAT commands (MSG_STAT/SEM_STAT/SHM_STAT) take a kernel array
+ * index rather than the id returned by *get(), and that index is not
+ * guaranteed to match the id when other IPC users are active. This walks
+ * the live indices to find the one that currently maps to @id.
+ *
+ * Return: The kernel index mapping to @id, or -1 if none was found.
+ */
+int get_ipc_idx_from_id(int id, int max_idx,
+			int (*stat_fn)(int idx, void *buf), void *buf);
+
 #endif /* tse_newipc.h */
diff --git a/libs/newipc/tse_newipc.c b/libs/newipc/tse_newipc.c
index f7edda6b5..aee286a31 100644
--- a/libs/newipc/tse_newipc.c
+++ b/libs/newipc/tse_newipc.c
@@ -86,3 +86,16 @@ void *probe_free_addr(const char *file, const int lineno)
 
 	return addr;
 }
+
+int get_ipc_idx_from_id(int id, int max_idx,
+			int (*stat_fn)(int idx, void *buf), void *buf)
+{
+	int i;
+
+	for (i = 0; i <= max_idx; i++) {
+		if (stat_fn(i, buf) == id)
+			return i;
+	}
+
+	return -1;
+}
diff --git a/testcases/kernel/syscalls/shmctl/shmctl01.c b/testcases/kernel/syscalls/shmctl/shmctl01.c
index 05aea58cc..bfc11fa39 100644
--- a/testcases/kernel/syscalls/shmctl/shmctl01.c
+++ b/testcases/kernel/syscalls/shmctl/shmctl01.c
@@ -224,20 +224,20 @@ static void dummy_sighandler(int sig)
 	(void)sig;
 }
 
+static int shm_stat(int idx, void *buf)
+{
+	return shmctl(idx, SHM_STAT, buf);
+}
+
 static int get_shm_idx_from_id(int shm_id)
 {
 	struct shm_info dummy;
 	struct shmid_ds dummy_ds;
-	int max_idx, i;
+	int max_idx;
 
 	max_idx = SAFE_SHMCTL(shm_id, SHM_INFO, (void *)&dummy);
 
-	for (i = 0; i <= max_idx; i++) {
-		if (shmctl(i, SHM_STAT, &dummy_ds) == shm_id)
-			return i;
-	}
-
-	return -1;
+	return get_ipc_idx_from_id(shm_id, max_idx, shm_stat, &dummy_ds);
 }
 
 static void setup(void)
-- 
2.55.0



More information about the ltp mailing list