All of lore.kernel.org
 help / color / mirror / Atom feed
* [LTP] [PATCH v2 1/2] libs/libltpnewipc: Add libnewmsgctl.c
@ 2020-06-18  9:41 Yang Xu
  2020-06-18  9:41 ` [LTP] [PATCH v2 2/2] syscalls/msgstress: scale number of processes accodingly to available RAM Yang Xu
                   ` (2 more replies)
  0 siblings, 3 replies; 26+ messages in thread
From: Yang Xu @ 2020-06-18  9:41 UTC (permalink / raw)
  To: ltp

From: Yang Xu <xuyang2018.jy@cn.fujitsu.com>

Add libnewmsgctl.c into ltp new ipc libs, so the upcoming msgstress cleanup cases
can use doreader/dowirter functions such as old libmsgctl.c does.

Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
---
 include/libnewmsgctl.h           |  22 +++++++
 libs/libltpnewipc/libnewmsgctl.c | 102 +++++++++++++++++++++++++++++++
 2 files changed, 124 insertions(+)
 create mode 100644 include/libnewmsgctl.h
 create mode 100644 libs/libltpnewipc/libnewmsgctl.c

diff --git a/include/libnewmsgctl.h b/include/libnewmsgctl.h
new file mode 100644
index 000000000..e48a04277
--- /dev/null
+++ b/include/libnewmsgctl.h
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2020 FUJITSU LIMITED. All rights reserved.
+ */
+
+#ifndef __LIBNEWMSGCTL_H__
+#define __LIBNEWMSGCTL_H__
+
+struct mbuffer {
+	long type;
+	struct {
+		char len;
+		char pbytes[99];
+	} data;
+};
+
+void doreader(long key, int tid, long type, int child, int nreps);
+void dowriter(long key, int tid, long type, int child, int nreps);
+void fill_buffer(char *buf, char val, int size);
+int verify(char *buf, char val, int size, int child);
+
+#endif /*__LIBNEWMSGCTL_H__ */
diff --git a/libs/libltpnewipc/libnewmsgctl.c b/libs/libltpnewipc/libnewmsgctl.c
new file mode 100644
index 000000000..1f6eed74a
--- /dev/null
+++ b/libs/libltpnewipc/libnewmsgctl.c
@@ -0,0 +1,102 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2020 FUJITSU LIMITED. All rights reserved.
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/msg.h>
+
+#define TST_NO_DEFAULT_MAIN
+#include "tst_test.h"
+#include "tst_safe_sysv_ipc.h"
+#include "libnewmsgctl.h"
+
+void doreader(long key, int tid, long type, int child, int nreps)
+{
+	int i, size;
+	int id;
+	struct mbuffer buffer;
+
+	id = SAFE_MSGGET(key, 0);
+	if (id != tid) {
+		tst_res(TFAIL,
+			"Message queue mismatch in the reader of child group %d for message queue id %d\n",
+			child, id);
+		return;
+	}
+	for (i = 0; i < nreps; i++) {
+		memset(&buffer, 0, sizeof(buffer));
+
+		size = SAFE_MSGRCV(id, &buffer, 100, type, 0);
+		if (buffer.type != type) {
+			tst_res(TFAIL, "Type mismatch in child %d, read #%d, for message got %ld, exected %ld",
+				child, (i + 1), buffer.type, type);
+			return;
+		}
+		if (buffer.data.len + 1 != size) {
+			tst_res(TFAIL, "Size mismatch in child %d, read #%d, for message got %d, expected %d",
+				child, (i + 1), buffer.data.len + 1, size);
+			return;
+		}
+		if (verify(buffer.data.pbytes, (key % 255), size - 1, child)) {
+			tst_res(TFAIL, "Verify failed in child %d read # = %d, key = %lx\n",
+				child, (i + 1), key);
+			return;
+		}
+		key++;
+	}
+}
+
+void dowriter(long key, int tid, long type, int child, int nreps)
+{
+	int i, size;
+	int id;
+	struct mbuffer buffer;
+
+	id = SAFE_MSGGET(key, 0);
+	if (id != tid) {
+		tst_res(TFAIL, "Message queue mismatch in the reader of child group %d for message queue id %d\n",
+			child, id);
+		return;
+	}
+
+	for (i = 0; i < nreps; i++) {
+		memset(&buffer, 0, sizeof(buffer));
+
+		do {
+			size = (lrand48() % 99);
+		} while (size == 0);
+		fill_buffer(buffer.data.pbytes, (key % 255), size);
+		buffer.data.len = size;
+		buffer.type = type;
+		SAFE_MSGSND(id, &buffer, size + 1, 0);
+		key++;
+	}
+}
+
+void fill_buffer(char *buf, char val, int size)
+{
+	int i;
+
+	for (i = 0; i < size; i++)
+		buf[i] = val;
+}
+
+/* Check a buffer for correct values */
+int verify(char *buf, char val, int size, int child)
+{
+	while (size-- > 0) {
+		if (*buf++ != val) {
+			tst_res(TFAIL, "Verify error in child %d, *buf = %x, val = %x, size = %d\n",
+				child, *buf, val, size);
+			return 1;
+		}
+	}
+	return 0;
+}
-- 
2.23.0


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

* [LTP] [PATCH v2 2/2] syscalls/msgstress: scale number of processes accodingly to available RAM
  2020-06-18  9:41 [LTP] [PATCH v2 1/2] libs/libltpnewipc: Add libnewmsgctl.c Yang Xu
@ 2020-06-18  9:41 ` Yang Xu
  2020-07-22 15:45   ` Cyril Hrubis
  2020-06-24  5:04 ` [LTP] [PATCH v2 1/2] libs/libltpnewipc: Add libnewmsgctl.c Yang Xu
  2020-07-22 15:01 ` Cyril Hrubis
  2 siblings, 1 reply; 26+ messages in thread
From: Yang Xu @ 2020-06-18  9:41 UTC (permalink / raw)
  To: ltp

From: Yang Xu <xuyang2018.jy@cn.fujitsu.com>

In these tests, fork may fail because of EAGAIN error in the following situations:
 1)Reaching the RLIMIT_NPROC soft resource limit
 2)Reaching /proc/sys/kernel/threads-max limit
 3)Reaching /proc/sys/kernel/pid_max limit
 4)the PID limit (pids.max) imposed by the cgroup "process number" (PIDs) controller was reached

According to kernel code kernel/fork.c, for thread_max it has the following
calculation formula:
	THREAD_SIZE = PAGE_SIZE << THREAD_SIZE_ORDER
	max_threads = totalram_pages / (8 * THREAD_SIZE / PAGE_SIZE);
The default maximum number of threads is set to a safe value: the thread structures can take up
at most one eighth of the memory. the pid limit is equal to max_threads/2.
 For example(on x86_64), 4G memory, page_size is 4k,THREAD_SIZE_ORDER is 1
 max_threads = 2^32/(8 * 8 * 1024) = 65536
 RLIMIT_NPROC = 32768  // 0.5

Also, pids cgroup and systemd also has this limit. On old systemd version, ths limit is 0.8 *thread_num.
On newer systemd version, the limit is 0.33 *thread_num. In here, we use 0.3.

Aparting from this changes, use new api for these cases and use some SAFE MACRO. Merge msgstress03.c into
msgstress01.c and use -r option to read actual msgmni value on procfs instead.

Fixes #509

Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
---
 runtest/syscalls                              |   4 +-
 runtest/syscalls-ipc                          |   4 +-
 .../kernel/syscalls/ipc/msgstress/.gitignore  |   1 -
 .../kernel/syscalls/ipc/msgstress/Makefile    |   4 +-
 .../syscalls/ipc/msgstress/msgstress01.c      | 317 +++++-------
 .../syscalls/ipc/msgstress/msgstress02.c      | 461 +++++++-----------
 .../syscalls/ipc/msgstress/msgstress03.c      | 290 -----------
 .../syscalls/ipc/msgstress/msgstress04.c      | 442 ++++++-----------
 8 files changed, 449 insertions(+), 1074 deletions(-)
 delete mode 100644 testcases/kernel/syscalls/ipc/msgstress/msgstress03.c

diff --git a/runtest/syscalls b/runtest/syscalls
index ee7e2a0d2..f4640bf0b 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -798,9 +798,9 @@ msgctl02 msgctl02
 msgctl03 msgctl03
 msgctl04 msgctl04
 msgctl05 msgctl05
-msgstress01 msgstress01
+msgstress01 msgstress01 -l 100000
 msgstress02 msgstress02
-msgstress03 msgstress03
+msgstress03 msgstress01 -r y
 msgstress04 msgstress04
 msgctl12 msgctl12
 
diff --git a/runtest/syscalls-ipc b/runtest/syscalls-ipc
index c3a35896c..ab613fdfa 100644
--- a/runtest/syscalls-ipc
+++ b/runtest/syscalls-ipc
@@ -3,9 +3,9 @@ msgctl02 msgctl02
 msgctl03 msgctl03
 msgctl04 msgctl04
 msgctl05 msgctl05
-msgstress01 msgstress01
+msgstress01 msgstress01  -l 100000
 msgstress02 msgstress02
-msgstress03 msgstress03
+msgstress03 msgstress01  -r y
 msgstress04 msgstress04
 msgctl12 msgctl12
 
diff --git a/testcases/kernel/syscalls/ipc/msgstress/.gitignore b/testcases/kernel/syscalls/ipc/msgstress/.gitignore
index a8f675399..e1df4cda8 100644
--- a/testcases/kernel/syscalls/ipc/msgstress/.gitignore
+++ b/testcases/kernel/syscalls/ipc/msgstress/.gitignore
@@ -1,4 +1,3 @@
 /msgstress01
 /msgstress02
-/msgstress03
 /msgstress04
diff --git a/testcases/kernel/syscalls/ipc/msgstress/Makefile b/testcases/kernel/syscalls/ipc/msgstress/Makefile
index f62cd1f48..a11cbcf2e 100644
--- a/testcases/kernel/syscalls/ipc/msgstress/Makefile
+++ b/testcases/kernel/syscalls/ipc/msgstress/Makefile
@@ -3,10 +3,10 @@
 
 top_srcdir              ?= ../../../../..
 
-LTPLIBS = ltpipc
+LTPLIBS = ltpnewipc
 
 include $(top_srcdir)/include/mk/testcases.mk
 
-LDLIBS  += -lltpipc
+LDLIBS  += -lltpnewipc
 
 include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/syscalls/ipc/msgstress/msgstress01.c b/testcases/kernel/syscalls/ipc/msgstress/msgstress01.c
index 0a660c042..c5a59151c 100644
--- a/testcases/kernel/syscalls/ipc/msgstress/msgstress01.c
+++ b/testcases/kernel/syscalls/ipc/msgstress/msgstress01.c
@@ -1,25 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /*
  * Copyright (c) International Business Machines  Corp., 2002
  *
- * This program is free software;  you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY;  without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
- * the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program;  if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
  * 06/30/2001   Port to Linux   nsharoff@us.ibm.com
  * 11/06/2002   Port to LTP     dbarrera@us.ibm.com
- */
-
-/*
+ * 06/15/2020   Convert to new api xuyang2018.jy@cn.fujitsu.com
+ *
  * Get and manipulate a message queue.
  */
 
@@ -31,101 +17,61 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <unistd.h>
-#include <values.h>
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <sys/stat.h>
 #include <sys/ipc.h>
 #include <sys/msg.h>
-#include "test.h"
-#include "ipcmsg.h"
-#include "libmsgctl.h"
+#include "tst_test.h"
+#include "libnewipc.h"
+#include "tst_safe_sysv_ipc.h"
+#include "libnewmsgctl.h"
 
-char *TCID = "msgstress01";
-int TST_TOTAL = 1;
-
-#ifndef CONFIG_COLDFIRE
-#define MAXNPROCS	1000000	/* This value is set to an arbitrary high limit. */
-#else
-#define MAXNPROCS	 100000	/* Coldfire can't deal with 1000000 */
-#endif
+#define MAXNPROCS       1000000
 #define MAXNREPS	100000
 
 static key_t keyarray[MAXNPROCS];
 static int pidarray[MAXNPROCS];
 static int tid;
 static int MSGMNI, nprocs, nreps;
-static int procstat;
-static int mykid;
-
-void setup(void);
-void cleanup(void);
-
-static int dotest(key_t key, int child_process);
-static void sig_handler();
-
 static char *opt_nprocs;
 static char *opt_nreps;
-
-static option_t options[] = {
-	{"n:", NULL, &opt_nprocs},
-	{"l:", NULL, &opt_nreps},
-	{NULL, NULL, NULL},
+static char *opt_msgmnifile;
+static void cleanup(void);
+
+static struct tst_option options[] = {
+	{"n:", &opt_nprocs, "-n N     Number of processes"},
+	{"l:", &opt_nreps, "-l N     Number of iterations"},
+	{"r:", &opt_msgmnifile, "-r Y/N use actual msgmni value under procfs"},
+	{NULL, NULL, NULL}
 };
 
-static void usage(void)
+static void dotest(key_t key, int child_process)
 {
-	printf("  -n      Number of processes\n");
-	printf("  -l      Number of iterations\n");
+	int pid;
+
+	tid = SAFE_MSGGET(key, IPC_CREAT | S_IRUSR | S_IWUSR);
+
+	pid = SAFE_FORK();
+	if (pid == 0) {
+		doreader(key, tid, 1, child_process, nreps);
+		exit(0);
+	}
+
+	dowriter(key, tid, 1, child_process, nreps);
+	tst_reap_children();
+	SAFE_MSGCTL(tid, IPC_RMID, NULL);
 }
 
-int main(int argc, char **argv)
+static void verify_msgstress(void)
 {
 	int i, j, ok, pid;
 	int count, status;
-	struct sigaction act;
-
-	tst_parse_opts(argc, argv, options, usage);
-
-	setup();
-
-	nreps = MAXNREPS;
-	nprocs = MSGMNI;
-
-	if (opt_nreps) {
-		nreps = atoi(opt_nreps);
-		if (nreps > MAXNREPS) {
-			tst_resm(TINFO,
-				 "Requested number of iterations too large, "
-				 "setting to Max. of %d", MAXNREPS);
-			nreps = MAXNREPS;
-		}
-	}
-
-	if (opt_nprocs) {
-		nprocs = atoi(opt_nprocs);
-		if (nprocs > MSGMNI) {
-			tst_resm(TINFO,
-				 "Requested number of processes too large, "
-				 "setting to Max. of %d", MSGMNI);
-			nprocs = MSGMNI;
-		}
-	}
 
 	srand(getpid());
 	tid = -1;
 
-	/* Setup signal handling routine */
-	memset(&act, 0, sizeof(act));
-	act.sa_handler = sig_handler;
-	sigemptyset(&act.sa_mask);
-	sigaddset(&act.sa_mask, SIGTERM);
-	if (sigaction(SIGTERM, &act, NULL) < 0) {
-		tst_brkm(TFAIL, NULL, "Sigset SIGTERM failed");
-	}
-	/* Set up array of unique keys for use in allocating message
-	 * queues
-	 */
+	/* Set up array of unique keys for use in allocating message queues */
 	for (i = 0; i < nprocs; i++) {
 		ok = 1;
 		do {
@@ -146,156 +92,115 @@ int main(int argc, char **argv)
 		} while (ok == 0);
 	}
 
-	/* Fork a number of processes, each of which will
+	/*
+	 * Fork a number of processes, each of which will
 	 * create a message queue with one reader/writer
 	 * pair which will read and write a number (iterations)
 	 * of random length messages with specific values.
 	 */
-
 	for (i = 0; i < nprocs; i++) {
-		fflush(stdout);
-		if ((pid = FORK_OR_VFORK()) < 0) {
-			tst_brkm(TFAIL,
-				 NULL,
-				 "\tFork failed (may be OK if under stress)");
-		}
-		/* Child does this */
+		pid = SAFE_FORK();
 		if (pid == 0) {
-			procstat = 1;
-			exit(dotest(keyarray[i], i));
+			dotest(keyarray[i], i);
+			exit(0);
 		}
 		pidarray[i] = pid;
 	}
-
 	count = 0;
-	while (1) {
-		if ((wait(&status)) > 0) {
-			if (status >> 8 != 0) {
-				tst_brkm(TFAIL, NULL,
-					 "Child exit status = %d",
-					 status >> 8);
-			}
-			count++;
-		} else {
-			if (errno != EINTR) {
-				break;
-			}
-#ifdef DEBUG
-			tst_resm(TINFO, "Signal detected during wait");
-#endif
-		}
+	while (count < nprocs) {
+		SAFE_WAIT(&status);
+		if (!WIFEXITED(status))
+			tst_res(TFAIL, "child process doesn't terminate normally");
+		count++;
 	}
-	/* Make sure proper number of children exited */
-	if (count != nprocs) {
-		tst_brkm(TFAIL,
-			 NULL,
+	if (count != nprocs)
+		tst_brk(TFAIL,
 			 "Wrong number of children exited, Saw %d, Expected %d",
 			 count, nprocs);
-	}
-
-	tst_resm(TPASS, "Test ran successfully!");
 
+	tst_res(TPASS, "Test ran successfully!");
 	cleanup();
-	tst_exit();
 }
 
-static int dotest(key_t key, int child_process)
-{
-	int id, pid;
-	int ret, status;
-
-	sighold(SIGTERM);
-	TEST(msgget(key, IPC_CREAT | S_IRUSR | S_IWUSR));
-	if (TEST_RETURN < 0) {
-		printf("msgget() error in child %d: %s\n",
-			child_process, strerror(TEST_ERRNO));
-
-		return FAIL;
-	}
-	tid = id = TEST_RETURN;
-	sigrelse(SIGTERM);
-
-	fflush(stdout);
-	if ((pid = FORK_OR_VFORK()) < 0) {
-		printf("\tFork failed (may be OK if under stress)\n");
-		TEST(msgctl(tid, IPC_RMID, 0));
-		if (TEST_RETURN < 0) {
-			printf("mscgtl() error in cleanup: %s\n",
-				strerror(TEST_ERRNO));
-		}
-		return FAIL;
-	}
-	/* Child does this */
-	if (pid == 0)
-		exit(doreader(key, id, 1, child_process, nreps));
-	/* Parent does this */
-	mykid = pid;
-	procstat = 2;
-	ret = dowriter(key, id, 1, child_process, nreps);
-	wait(&status);
-
-	if (ret != PASS)
-		exit(FAIL);
-
-	if ((!WIFEXITED(status) || (WEXITSTATUS(status) != PASS)))
-		exit(FAIL);
-
-	TEST(msgctl(id, IPC_RMID, 0));
-	if (TEST_RETURN < 0) {
-		printf("msgctl() errno %d: %s\n",
-			TEST_ERRNO, strerror(TEST_ERRNO));
-
-		return FAIL;
-	}
-	return PASS;
-}
-
-static void sig_handler(void)
-{
-}
-
-void setup(void)
+static void setup(void)
 {
 	int nr_msgqs;
+	int threads_max;
+	int free_pids;
 
-	tst_tmpdir();
+	SAFE_FILE_SCANF("/proc/sys/kernel/msgmni", "%d", &nr_msgqs);
+	SAFE_FILE_SCANF("/proc/sys/kernel/threads-max", "%d", &threads_max);
 
-	tst_sig(FORK, DEF_HANDLER, cleanup);
+	nr_msgqs -= GET_USED_QUEUES();
+	if (nr_msgqs <= 0)
+		tst_brk(TCONF, "Max number of message queues already used, cannot create more.");
 
-	TEST_PAUSE;
+	if (opt_msgmnifile)
+		MSGMNI = nr_msgqs;
+	else
+		MSGMNI = min(nr_msgqs, NR_MSGQUEUES);
 
-	nr_msgqs = get_max_msgqueues();
-	if (nr_msgqs < 0)
-		cleanup();
+	if (opt_nreps) {
+		nreps = SAFE_STRTOL(opt_nreps, 1, INT_MAX);
+		nreps = min(nreps, MAXNREPS);
+	} else {
+		nreps = 10000;
+	}
 
-	nr_msgqs -= get_used_msgqueues();
-	if (nr_msgqs <= 0) {
-		tst_resm(TBROK,
-			 "Max number of message queues already used, cannot create more.");
-		cleanup();
+	if (opt_nprocs) {
+		nprocs = SAFE_STRTOL(opt_nprocs, 1, INT_MAX);
+		nprocs = min(nprocs, MAXNPROCS);
+		nprocs = min(nprocs, MSGMNI);
+	} else {
+		nprocs = MSGMNI;
 	}
 
 	/*
-	 * Since msgmni scales to the memory size, it may reach huge values
-	 * that are not necessary for this test.
-	 * That's why we define NR_MSGQUEUES as a high boundary for it.
+	 * fork may fail because of EAGAIN error in the following situations:
+	 * 1)Reaching the RLIMIT_NPROC soft resource limit
+	 * 2)Reaching /proc/sys/kernel/threads-max limit
+	 * 3)Reaching /proc/sys/kernel/pid_max limit
+	 * 4)the PID limit (pids.max) imposed by the cgroup "process number" (PIDs) controller was reached
+	 *
+	 * According to kernel code kernel/fork.c, for thread_max it has the following
+	 * calculation formula:
+	 * THREAD_SIZE = PAGE_SIZE << THREAD_SIZE_ORDER
+	 * max_threads = totalram_pages / (8 * THREAD_SIZE / PAGE_SIZE);
+	 * The default maximum number of threads is set to a safe value: the thread
+	 * structures can take up@most one eighth of the memory.
+	 * the pid limit is equal to max_threads/2.
+	 * For example(on x86_64), 4G memory, page_size is 4k,THREAD_SIZE_ORDER is 1
+	 * max_threads = 2^32/(8 * 8 * 1024) = 65536
+	 * RLIMIT_NPROC = 32768  // 0.5
+	 *
+	 * Also, pids cgroup and systemd also has this limit. On old systemd version,
+	 * ths limit is 0.8 *thread_num. On newer systemd version, the limit is 0.33 *
+	 * thread_num. In here, we use 0.3.
 	 */
-	MSGMNI = min(nr_msgqs, NR_MSGQUEUES);
+	nprocs = min(nprocs, 0.3 * threads_max);
+	free_pids = tst_get_free_pids();
+	if (free_pids < 0)
+		tst_brk(TBROK, "Can't obtain free_pid count");
+	if (!free_pids)
+		tst_brk(TBROK, "No free pids");
+
+	nprocs = min(nprocs, free_pids * 0.8);
+
+	SAFE_SIGNAL(SIGTERM, SIG_IGN);
+	tst_res(TINFO, "Number of message queues is %d, process is %d, iterations is %d", MSGMNI, nprocs, nreps);
 }
 
 void cleanup(void)
 {
-	int status;
-
-#ifdef DEBUG
-	tst_resm(TINFO, "Removing the message queue");
-#endif
-	(void)msgctl(tid, IPC_RMID, NULL);
-	if ((status = msgctl(tid, IPC_STAT, NULL)) != -1) {
-		(void)msgctl(tid, IPC_RMID, NULL);
-		tst_resm(TFAIL, "msgctl(tid, IPC_RMID) failed");
-
-	}
-
-	tst_rmdir();
+	if (tid >= 0)
+		SAFE_MSGCTL(tid, IPC_RMID, NULL);
 }
+
+static struct tst_test test = {
+	.needs_tmpdir = 1,
+	.options = options,
+	.setup = setup,
+	.cleanup = cleanup,
+	.forks_child = 1,
+	.test_all = verify_msgstress,
+};
diff --git a/testcases/kernel/syscalls/ipc/msgstress/msgstress02.c b/testcases/kernel/syscalls/ipc/msgstress/msgstress02.c
index e15131043..030dcfe99 100644
--- a/testcases/kernel/syscalls/ipc/msgstress/msgstress02.c
+++ b/testcases/kernel/syscalls/ipc/msgstress/msgstress02.c
@@ -1,31 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /*
  * Copyright (c) International Business Machines  Corp., 2002
  *
- * This program is free software;  you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY;  without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
- * the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program;  if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
  * 06/30/2001   Port to Linux   nsharoff@us.ibm.com
  * 11/11/2002   Port to LTP     dbarrera@us.ibm.com
- */
-
-/*
+ * 06/15/2020   Convert to new api xuyang2018.jy@cn.fujitsu.com
+ *
  * Get and manipulate a message queue.
  */
-
 #define _XOPEN_SOURCE 500
 #include <sys/stat.h>
-#include <sys/types.h>
 #include <sys/ipc.h>
 #include <sys/msg.h>
 #include <sys/wait.h>
@@ -35,19 +19,13 @@
 #include <string.h>
 #include <stdlib.h>
 #include <unistd.h>
-#include "test.h"
-#include "ipcmsg.h"
-#include "libmsgctl.h"
-
-char *TCID = "msgstress02";
-int TST_TOTAL = 1;
+#include "tst_test.h"
+#include "libnewipc.h"
+#include "tst_safe_sysv_ipc.h"
+#include "libnewmsgctl.h"
 
 #define MAXNREPS	1000
-#ifndef CONFIG_COLDFIRE
-#define MAXNPROCS	 1000000	/* This value is set to an arbitrary high limit. */
-#else
-#define MAXNPROCS	 100000	/* Coldfire can't deal with 1000000 */
-#endif
+#define MAXNPROCS	1000000
 #define MAXNKIDS	10
 
 static key_t keyarray[MAXNPROCS];
@@ -58,157 +36,19 @@ static int tid;
 static int nprocs, nreps, nkids, MSGMNI;
 static int procstat;
 
-void setup(void);
-void cleanup(void);
-
-static void term(int);
-static int dotest(key_t, int);
-static void cleanup_msgqueue(int i, int tid);
+static void cleanup(void);
 
 static char *opt_nprocs;
 static char *opt_nkids;
 static char *opt_nreps;
 
-static option_t options[] = {
-	{"n:", NULL, &opt_nprocs},
-	{"c:", NULL, &opt_nkids},
-	{"l:", NULL, &opt_nreps},
-	{NULL, NULL, NULL},
+static struct tst_option options[] = {
+	{"n:", &opt_nprocs, "-n N     Number of processes"},
+	{"c:", &opt_nkids, "-c N     Number of read/write child pairs"},
+	{"l:", &opt_nreps, "-l N     Number of iterations"},
+	{NULL, NULL, NULL}
 };
 
-static void usage(void)
-{
-	printf("  -n      Number of processes\n");
-	printf("  -c      Number of read/write child pairs\n");
-	printf("  -l      Number of iterations\n");
-}
-
-int main(int argc, char **argv)
-{
-	int i, j, ok, pid;
-	int count, status;
-
-	tst_parse_opts(argc, argv, options, usage);
-
-	setup();
-
-	nreps = MAXNREPS;
-	nprocs = MSGMNI;
-	nkids = MAXNKIDS;
-
-	if (opt_nreps) {
-		nreps = atoi(opt_nreps);
-		if (nreps > MAXNREPS) {
-			tst_resm(TINFO,
-				 "Requested number of iterations too large, "
-				 "setting to Max. of %d", MAXNREPS);
-			nreps = MAXNREPS;
-		}
-	}
-
-	if (opt_nprocs) {
-		nprocs = atoi(opt_nprocs);
-		if (nprocs > MSGMNI) {
-			tst_resm(TINFO,
-				 "Requested number of processes too large, "
-				 "setting to Max. of %d", MSGMNI);
-			nprocs = MSGMNI;
-		}
-	}
-
-	if (opt_nkids) {
-		nkids = atoi(opt_nkids);
-		if (nkids > MAXNKIDS) {
-			tst_resm(TINFO,
-				 "Requested number of read/write pairs too "
-				 "large, setting to Max. of %d", MAXNKIDS);
-			nkids = MAXNKIDS;
-		}
-	}
-
-	procstat = 0;
-	srand48((unsigned)getpid() + (unsigned)(getppid() << 16));
-	tid = -1;
-
-	/* Setup signal handleing routine */
-	if (sigset(SIGTERM, term) == SIG_ERR) {
-		tst_brkm(TFAIL, NULL, "Sigset SIGTERM failed");
-	}
-	/* Set up array of unique keys for use in allocating message
-	 * queues
-	 */
-	for (i = 0; i < nprocs; i++) {
-		ok = 1;
-		do {
-			/* Get random key */
-			keyarray[i] = (key_t) lrand48();
-			/* Make sure key is unique and not private */
-			if (keyarray[i] == IPC_PRIVATE) {
-				ok = 0;
-				continue;
-			}
-			for (j = 0; j < i; j++) {
-				if (keyarray[j] == keyarray[i]) {
-					ok = 0;
-					break;
-				}
-				ok = 1;
-			}
-		} while (ok == 0);
-	}
-	/* Fork a number of processes (nprocs), each of which will
-	 * create a message queue with several (nkids) reader/writer
-	 * pairs which will read and write a number (iterations)
-	 * of random length messages with specific values (keys).
-	 */
-
-	for (i = 0; i < nprocs; i++) {
-		fflush(stdout);
-		if ((pid = FORK_OR_VFORK()) < 0) {
-			tst_brkm(TFAIL,
-				 NULL,
-				 "\tFork failed (may be OK if under stress)");
-		}
-		/* Child does this */
-		if (pid == 0) {
-			procstat = 1;
-			exit(dotest(keyarray[i], i));
-		}
-		pidarray[i] = pid;
-	}
-
-	count = 0;
-	while (1) {
-		if ((wait(&status)) > 0) {
-			if (status >> 8 != PASS) {
-				tst_brkm(TFAIL, NULL,
-					 "Child exit status = %d",
-					 status >> 8);
-			}
-			count++;
-		} else {
-			if (errno != EINTR) {
-				break;
-			}
-#ifdef DEBUG
-			tst_resm(TINFO, "Signal detected during wait");
-#endif
-		}
-	}
-	/* Make sure proper number of children exited */
-	if (count != nprocs) {
-		tst_brkm(TFAIL,
-			 NULL,
-			 "Wrong number of children exited, Saw %d, Expected %d",
-			 count, nprocs);
-	}
-
-	tst_resm(TPASS, "Test ran successfully!");
-
-	cleanup();
-	tst_exit();
-}
-
 static void cleanup_msgqueue(int i, int tid)
 {
 	/*
@@ -226,78 +66,88 @@ static void cleanup_msgqueue(int i, int tid)
 		(void)kill(wkidarray[i], SIGKILL);
 	}
 
-	if (msgctl(tid, IPC_RMID, 0) < 0) {
-		tst_brkm(TFAIL | TERRNO, NULL, "Msgctl error in cleanup");
+	SAFE_MSGCTL(tid, IPC_RMID, NULL);
+}
+
+static void term(int sig LTP_ATTRIBUTE_UNUSED)
+{
+	int i;
+
+	if (procstat == 0) {
+		tst_res(TINFO, "SIGTERM signal received, test killing kids");
+		for (i = 0; i < nprocs; i++) {
+			if (pidarray[i] > 0)
+				if (kill(pidarray[i], SIGTERM) < 0)
+					tst_brk(TBROK, "Kill failed to kill child %d", i);
+		}
+		return;
+	}
+
+	if (procstat == 2) {
+		fflush(stdout);
+		exit(0);
+	}
+
+	if (tid == -1) {
+		exit(1);
+	}
+	for (i = 0; i < nkids; i++) {
+		if (rkidarray[i] > 0)
+			(void)kill(rkidarray[i], SIGTERM);
+		if (wkidarray[i] > 0)
+			(void)kill(wkidarray[i], SIGTERM);
 	}
 }
 
-static int dotest(key_t key, int child_process)
+static void dotest(key_t key, int child_process)
 {
-	int id, pid;
-	int i, count, status, exit_status;
+	int pid;
+	int i, count, status;
 
 	sighold(SIGTERM);
-	if ((id = msgget(key, IPC_CREAT | S_IRUSR | S_IWUSR)) < 0) {
-		printf("msgget() error in child %d: %s\n",
-			child_process, strerror(errno));
-		return FAIL;
-	}
-	tid = id;
+	tid = SAFE_MSGGET(key, IPC_CREAT | S_IRUSR | S_IWUSR);
 	sigrelse(SIGTERM);
 
-	exit_status = PASS;
-
 	for (i = 0; i < nkids; i++) {
-		fflush(stdout);
-		if ((pid = FORK_OR_VFORK()) < 0) {
-			printf("Fork failure in the first child of child group %d\n",
+		pid = fork();
+		if (pid < 0) {
+			tst_res(TFAIL, "Fork failure in the first child of child group %d\n",
 				child_process);
 			cleanup_msgqueue(i, tid);
-			return FAIL;
+			return;
 		}
-		/* First child does this */
 		if (pid == 0) {
 			procstat = 2;
-			exit(doreader(key, tid, getpid(),
-					child_process, nreps));
+			doreader(key, tid, getpid(), child_process, nreps);
+			exit(0);
 		}
 		rkidarray[i] = pid;
-		fflush(stdout);
-		if ((pid = FORK_OR_VFORK()) < 0) {
-			printf("Fork failure in the second child of child group %d\n",
+		pid = fork();
+		if (pid < 0) {
+			tst_res(TFAIL, "Fork failure in the first child of child group %d\n",
 				child_process);
-			/*
-			 * Kill the reader child process
-			 */
-			(void)kill(rkidarray[i], SIGKILL);
-
 			cleanup_msgqueue(i, tid);
-			return FAIL;
+			return;
 		}
-		/* Second child does this */
 		if (pid == 0) {
 			procstat = 2;
-			exit(dowriter(key, tid, rkidarray[i],
-					child_process, nreps));
+			dowriter(key, tid, rkidarray[i], child_process, nreps);
+			exit(0);
 		}
 		wkidarray[i] = pid;
 	}
-	/* Parent does this */
 	count = 0;
-	while (1) {
+	while (count < (nkids * 2)) {
 		if ((wait(&status)) > 0) {
-			if (status >> 8 != PASS) {
-				printf("Child exit status = %d from child group %d\n",
+			if (status >> 8 != 0) {
+				tst_res(TFAIL, "Child exit status = %d from child group %d\n",
 					status >> 8, child_process);
 				for (i = 0; i < nkids; i++) {
-					kill(rkidarray[i], SIGTERM);
-					kill(wkidarray[i], SIGTERM);
-				}
-				if (msgctl(tid, IPC_RMID, 0) < 0) {
-					printf("msgctl() error: %s\n",
-						strerror(errno));
+					(void)kill(rkidarray[i], SIGTERM);
+					(void)kill(wkidarray[i], SIGTERM);
 				}
-				return FAIL;
+				SAFE_MSGCTL(tid, IPC_RMID, NULL);
+				return;
 			}
 			count++;
 		} else {
@@ -308,101 +158,138 @@ static int dotest(key_t key, int child_process)
 	}
 	/* Make sure proper number of children exited */
 	if (count != (nkids * 2)) {
-		printf("Wrong number of children exited in child group %d, saw %d, expected %d\n",
+		tst_res(TFAIL, "Wrong number of children exited in child group %d, saw %d, expected %d\n",
 			child_process, count, (nkids * 2));
-		if (msgctl(tid, IPC_RMID, 0) < 0) {
-			printf("msgctl() error: %s\n", strerror(errno));
-		}
-		return FAIL;
-	}
-	if (msgctl(id, IPC_RMID, 0) < 0) {
-		printf("msgctl() failure in child group %d: %s\n",
-			child_process, strerror(errno));
-		return FAIL;
+		SAFE_MSGCTL(tid, IPC_RMID, NULL);
+		return;
 	}
-	return exit_status;
+	SAFE_MSGCTL(tid, IPC_RMID, NULL);
 }
 
-static void term(int sig LTP_ATTRIBUTE_UNUSED)
+static void verify_msgstress(void)
 {
-	int i;
+	int i, j, ok, pid;
+	int count, status;
 
-	if (procstat == 0) {
-#ifdef DEBUG
-		tst_resm(TINFO, "SIGTERM signal received, test killing kids");
-#endif
-		for (i = 0; i < nprocs; i++) {
-			if (pidarray[i] > 0) {
-				if (kill(pidarray[i], SIGTERM) < 0) {
-					printf("Kill failed to kill child %d",
-						i);
-					exit(FAIL);
+	procstat = 0;
+	srand48((unsigned)getpid() + (unsigned)(getppid() << 16));
+	tid = -1;
+
+	/* Set up array of unique keys for use in allocating messag queues*/
+	for (i = 0; i < nprocs; i++) {
+		ok = 1;
+		do {
+			/* Get random key */
+			keyarray[i] = (key_t) lrand48();
+			/* Make sure key is unique and not private */
+			if (keyarray[i] == IPC_PRIVATE) {
+				ok = 0;
+				continue;
+			}
+			for (j = 0; j < i; j++) {
+				if (keyarray[j] == keyarray[i]) {
+					ok = 0;
+					break;
 				}
+				ok = 1;
 			}
-		}
-		return;
+		} while (ok == 0);
 	}
-
-	if (procstat == 2) {
-		fflush(stdout);
-		exit(PASS);
+	/* Fork a number of processes (nprocs), each of which will
+	 * create a message queue with several (nkids) reader/writer
+	 * pairs which will read and write a number (iterations)
+	 * of random length messages with specific values (keys).
+	 */
+	for (i = 0; i < nprocs; i++) {
+		pid = SAFE_FORK();
+		if (pid == 0) {
+			procstat = 1;
+			dotest(keyarray[i], i);
+			exit(0);
+		}
+		pidarray[i] = pid;
 	}
-
-	if (tid == -1) {
-		exit(FAIL);
+	count = 0;
+	while (count < nprocs) {
+		SAFE_WAIT(&status);
+		if (!WIFEXITED(status))
+			tst_res(TFAIL, "child process doesn't terminate normally");
+		count++;
 	}
-	for (i = 0; i < nkids; i++) {
-		if (rkidarray[i] > 0)
-			kill(rkidarray[i], SIGTERM);
-		if (wkidarray[i] > 0)
-			kill(wkidarray[i], SIGTERM);
+	/* Make sure proper number of children exited */
+	if (count != nprocs) {
+		tst_brk(TFAIL,
+			"Wrong number of children exited, Saw %d, Expected %d",
+			count, nprocs);
 	}
+
+	tst_res(TPASS, "Test ran successfully!");
+	cleanup();
 }
 
-void setup(void)
+static void setup(void)
 {
 	int nr_msgqs;
+	int threads_max;
+	int free_pids;
 
-	tst_tmpdir();
+	SAFE_FILE_SCANF("/proc/sys/kernel/msgmni", "%d", &nr_msgqs);
+	SAFE_FILE_SCANF("/proc/sys/kernel/threads-max", "%d", &threads_max);
 
-	tst_sig(FORK, DEF_HANDLER, cleanup);
+	MSGMNI = nr_msgqs - GET_USED_QUEUES();
+	if (MSGMNI <= 0)
+		tst_brk(TCONF, "Max number of message queues already used, cannot create more.");
 
-	TEST_PAUSE;
+	tst_res(TINFO, "Found %d available message queues", MSGMNI);
 
-	nr_msgqs = get_max_msgqueues();
-	if (nr_msgqs < 0)
-		cleanup();
+	if (opt_nreps) {
+		nreps = SAFE_STRTOL(opt_nreps, 1, INT_MAX);
+		nreps = min(nreps, MAXNREPS);
+	} else {
+		nreps = 1000;
+	}
 
-	nr_msgqs -= get_used_msgqueues();
-	if (nr_msgqs <= 0) {
-		tst_resm(TBROK,
-			 "Max number of message queues already used, cannot create more.");
-		cleanup();
+	if (opt_nkids) {
+		nkids = SAFE_STRTOL(opt_nkids, 1, INT_MAX);
+		nkids = min(nkids, MAXNKIDS);
+	} else {
+		nkids = MAXNKIDS;
 	}
 
-	/*
-	 * Since msgmni scales to the memory size, it may reach huge values
-	 * that are not necessary for this test.
-	 * That's why we define NR_MSGQUEUES as a high boundary for it.
-	 */
-	MSGMNI = min(nr_msgqs, NR_MSGQUEUES);
-}
+	if (opt_nprocs) {
+		nprocs = SAFE_STRTOL(opt_nprocs, 1, INT_MAX);
+		nprocs = min(nprocs, MAXNPROCS);
+		nprocs = min(nprocs, nr_msgqs);
+	} else {
+		nprocs = NR_MSGQUEUES;
+	}
 
-void cleanup(void)
-{
-	int status;
+	free_pids = tst_get_free_pids();
+	if (free_pids < 0)
+		tst_brk(TBROK, "Can't obtain free_pid count");
+	if (!free_pids)
+		tst_brk(TBROK, "No free pids");
 
-#ifdef DEBUG
-	tst_resm(TINFO, "Removing the message queue");
-#endif
-	fflush(stdout);
-	(void)msgctl(tid, IPC_RMID, NULL);
-	if ((status = msgctl(tid, IPC_STAT, NULL)) != -1) {
-		(void)msgctl(tid, IPC_RMID, NULL);
-		tst_resm(TFAIL, "msgctl(tid, IPC_RMID) failed");
+	free_pids = min(free_pids, 0.3 * threads_max);
+	nprocs = min(nprocs, (free_pids / 2) / (1 + 2 * nkids));
+	if (!nprocs)
+		tst_brk(TBROK, "Not enough free pids");
 
-	}
+	SAFE_SIGNAL(SIGTERM, term);
+	tst_res(TINFO, "%d processes %d read/write pais, %d repeats", nprocs, nkids, nreps);
+}
 
-	fflush(stdout);
-	tst_rmdir();
+void cleanup(void)
+{
+	if (tid >= 0)
+		SAFE_MSGCTL(tid, IPC_RMID, NULL);
 }
+
+static struct tst_test test = {
+	.needs_tmpdir = 1,
+	.options = options,
+	.setup = setup,
+	.cleanup = cleanup,
+	.forks_child = 1,
+	.test_all = verify_msgstress,
+};
diff --git a/testcases/kernel/syscalls/ipc/msgstress/msgstress03.c b/testcases/kernel/syscalls/ipc/msgstress/msgstress03.c
deleted file mode 100644
index 294b401b1..000000000
--- a/testcases/kernel/syscalls/ipc/msgstress/msgstress03.c
+++ /dev/null
@@ -1,290 +0,0 @@
-/*
- * Copyright (c) International Business Machines  Corp., 2002
- *
- * This program is free software;  you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY;  without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
- * the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program;  if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * 06/30/2001   Port to Linux   nsharoff@us.ibm.com
- * 11/06/2002   Port to LTP     dbarrera@us.ibm.com
- */
-
-/*
- * Get and manipulate a message queue.
- * Same as msgstress01 but gets the actual msgmni value under procfs.
- */
-
-#define _XOPEN_SOURCE 500
-#include <signal.h>
-#include <errno.h>
-#include <string.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <values.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <sys/stat.h>
-#include <sys/ipc.h>
-#include <sys/msg.h>
-#include "test.h"
-#include "ipcmsg.h"
-#include "libmsgctl.h"
-
-char *TCID = "msgstress03";
-int TST_TOTAL = 1;
-
-#define MAXNPROCS	10000	/*These should be sufficient */
-#define MAXNREPS	10000	/*Else they srewup the system un-necessarily */
-
-static key_t keyarray[MAXNPROCS];
-static int pidarray[MAXNPROCS];
-static int tid;
-static int MSGMNI, nprocs, nreps;
-static int procstat;
-static int mykid;
-
-void setup(void);
-void cleanup(void);
-
-static int dotest(key_t key, int child_process);
-static void sig_handler(int signo);
-
-static char *opt_nprocs;
-static char *opt_nreps;
-
-static option_t options[] = {
-	{"n:", NULL, &opt_nprocs},
-	{"l:", NULL, &opt_nreps},
-	{NULL, NULL, NULL},
-};
-
-static void usage(void)
-{
-	printf("  -n      Number of processes\n");
-	printf("  -l      Number of iterations\n");
-}
-
-int main(int argc, char **argv)
-{
-	int i, j, ok, pid;
-	int count, status;
-	struct sigaction act;
-
-	tst_parse_opts(argc, argv, options, usage);
-
-	setup();
-
-	nreps = MAXNREPS;
-	nprocs = MSGMNI;
-
-	if (opt_nreps) {
-		nreps = atoi(opt_nreps);
-		if (nreps > MAXNREPS) {
-			tst_resm(TINFO,
-				 "Requested number of iterations too large, "
-				 "setting to Max. of %d", MAXNREPS);
-			nreps = MAXNREPS;
-		}
-	}
-
-	if (opt_nprocs) {
-		nprocs = atoi(opt_nprocs);
-		if (nprocs > MSGMNI) {
-			tst_resm(TINFO,
-				 "Requested number of processes too large, "
-				 "setting to Max. of %d", MSGMNI);
-			nprocs = MSGMNI;
-		}
-	}
-
-	srand(getpid());
-	tid = -1;
-
-	/* Setup signal handling routine */
-	memset(&act, 0, sizeof(act));
-	act.sa_handler = sig_handler;
-	sigemptyset(&act.sa_mask);
-	sigaddset(&act.sa_mask, SIGTERM);
-	if (sigaction(SIGTERM, &act, NULL) < 0) {
-		tst_brkm(TFAIL, NULL, "Sigset SIGTERM failed");
-	}
-	/* Set up array of unique keys for use in allocating message
-	 * queues
-	 */
-	for (i = 0; i < nprocs; i++) {
-		ok = 1;
-		do {
-			/* Get random key */
-			keyarray[i] = (key_t) rand();
-			/* Make sure key is unique and not private */
-			if (keyarray[i] == IPC_PRIVATE) {
-				ok = 0;
-				continue;
-			}
-			for (j = 0; j < i; j++) {
-				if (keyarray[j] == keyarray[i]) {
-					ok = 0;
-					break;
-				}
-				ok = 1;
-			}
-		} while (ok == 0);
-	}
-
-	/* Fork a number of processes, each of which will
-	 * create a message queue with one reader/writer
-	 * pair which will read and write a number (iterations)
-	 * of random length messages with specific values.
-	 */
-
-	for (i = 0; i < nprocs; i++) {
-		fflush(stdout);
-		if ((pid = FORK_OR_VFORK()) < 0) {
-			tst_brkm(TFAIL,
-				 NULL,
-				 "\tFork failed (may be OK if under stress)");
-		}
-		/* Child does this */
-		if (pid == 0) {
-			procstat = 1;
-			exit(dotest(keyarray[i], i));
-		}
-		pidarray[i] = pid;
-	}
-
-	count = 0;
-	while (1) {
-		if ((wait(&status)) > 0) {
-			if (status >> 8 != 0) {
-				tst_brkm(TFAIL, NULL,
-					 "Child exit status = %d",
-					 status >> 8);
-			}
-			count++;
-		} else {
-			if (errno != EINTR) {
-				break;
-			}
-#ifdef DEBUG
-			tst_resm(TINFO, "Signal detected during wait");
-#endif
-		}
-	}
-	/* Make sure proper number of children exited */
-	if (count != nprocs) {
-		tst_brkm(TFAIL,
-			 NULL,
-			 "Wrong number of children exited, Saw %d, Expected %d",
-			 count, nprocs);
-	}
-
-	tst_resm(TPASS, "Test ran successfully!");
-
-	cleanup();
-	tst_exit();
-}
-
-static int dotest(key_t key, int child_process)
-{
-	int id, pid;
-	int ret, status;
-
-	sighold(SIGTERM);
-	TEST(msgget(key, IPC_CREAT | S_IRUSR | S_IWUSR));
-	if (TEST_RETURN < 0) {
-		printf("msgget() error in child %d: %s\n",
-			child_process, strerror(TEST_ERRNO));
-		return FAIL;
-	}
-	tid = id = TEST_RETURN;
-	sigrelse(SIGTERM);
-
-	fflush(stdout);
-	if ((pid = FORK_OR_VFORK()) < 0) {
-		printf("Fork failed (may be OK if under stress)\n");
-		TEST(msgctl(tid, IPC_RMID, 0));
-		if (TEST_RETURN < 0) {
-			printf("msgctl() error in cleanup: %s\n",
-				strerror(TEST_ERRNO));
-		}
-		return FAIL;
-	}
-	if (pid == 0)
-		exit(doreader(key, id, 1, child_process, nreps));
-
-	mykid = pid;
-	procstat = 2;
-	ret = dowriter(key, id, 1, child_process, nreps);
-	wait(&status);
-
-	if (ret != PASS)
-		exit(FAIL);
-
-	if ((!WIFEXITED(status) || (WEXITSTATUS(status) != PASS)))
-		exit(FAIL);
-
-	TEST(msgctl(id, IPC_RMID, 0));
-	if (TEST_RETURN < 0) {
-		printf("msgctl() failed: %s\n",
-			strerror(TEST_ERRNO));
-		return FAIL;
-	}
-	return PASS;
-}
-
-static void sig_handler(int signo LTP_ATTRIBUTE_UNUSED)
-{
-}
-
-void setup(void)
-{
-	int nr_msgqs;
-
-	tst_tmpdir();
-
-	tst_sig(FORK, DEF_HANDLER, cleanup);
-
-	TEST_PAUSE;
-
-	nr_msgqs = get_max_msgqueues();
-	if (nr_msgqs < 0)
-		cleanup();
-
-	MSGMNI = nr_msgqs - get_used_msgqueues();
-	if (MSGMNI > MAXNPROCS)
-		MSGMNI = MAXNPROCS;
-	if (MSGMNI <= 0) {
-		tst_resm(TBROK,
-			 "Max number of message queues already used, cannot create more.");
-		cleanup();
-	}
-}
-
-void cleanup(void)
-{
-	int status;
-
-#ifdef DEBUG
-	tst_resm(TINFO, "Removing the message queue");
-#endif
-	(void)msgctl(tid, IPC_RMID, NULL);
-	if ((status = msgctl(tid, IPC_STAT, NULL)) != -1) {
-		(void)msgctl(tid, IPC_RMID, NULL);
-		tst_resm(TFAIL, "msgctl(tid, IPC_RMID) failed");
-
-	}
-
-	tst_rmdir();
-}
diff --git a/testcases/kernel/syscalls/ipc/msgstress/msgstress04.c b/testcases/kernel/syscalls/ipc/msgstress/msgstress04.c
index f1c124990..5762e72f1 100644
--- a/testcases/kernel/syscalls/ipc/msgstress/msgstress04.c
+++ b/testcases/kernel/syscalls/ipc/msgstress/msgstress04.c
@@ -1,32 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /*
  * Copyright (c) International Business Machines  Corp., 2002
  *
- * This program is free software;  you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY;  without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
- * the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program;  if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
  * 06/30/2001   Port to Linux   nsharoff@us.ibm.com
  * 11/11/2002   Port to LTP     dbarrera@us.ibm.com
- */
-
-/*
+ * 06/15/2020   Convert to new api xuyang2018.jy@cn.fujitsu.com
+ *
  * Get and manipulate a message queue.
  * Same as msgstress02 but gets the actual msgmni value under procfs.
  */
-
 #define _XOPEN_SOURCE 500
 #include <sys/stat.h>
-#include <sys/types.h>
 #include <sys/ipc.h>
 #include <sys/msg.h>
 #include <sys/wait.h>
@@ -36,23 +20,15 @@
 #include <string.h>
 #include <stdlib.h>
 #include <unistd.h>
-#include "test.h"
-#include "ipcmsg.h"
-#include "libmsgctl.h"
-
-char *TCID = "msgstress04";
-int TST_TOTAL = 1;
+#include "tst_test.h"
+#include "libnewipc.h"
+#include "tst_safe_sysv_ipc.h"
+#include "libnewmsgctl.h"
 
 #define MAXNREPS	1000
-#ifndef CONFIG_COLDFIRE
-#define MAXNPROCS	 1000000	/* This value is set to an arbitrary high limit. */
-#else
-#define MAXNPROCS	 100000	/* Coldfire can't deal with 1000000 */
-#endif
+#define MAXNPROCS	1000000
 #define MAXNKIDS	10
-#define DEFNKIDS	2
 
-static int maxnkids = MAXNKIDS;	/* Used if pid_max is exceeded */
 static key_t keyarray[MAXNPROCS];
 static int pidarray[MAXNPROCS];
 static int rkidarray[MAXNKIDS];
@@ -62,86 +38,116 @@ static int nprocs, nreps, nkids, MSGMNI;
 static int maxnprocs;
 static int procstat;
 
-void setup(void);
-void cleanup(void);
+static void cleanup(void);
 
 static void term(int);
-static int dotest(key_t, int);
-static void dotest_iteration(int off);
-static void cleanup_msgqueue(int i, int tid);
+static void dotest(key_t, int);
 
 static char *opt_maxnprocs;
 static char *opt_nkids;
 static char *opt_nreps;
 
-static option_t options[] = {
-	{"n:", NULL, &opt_maxnprocs},
-	{"c:", NULL, &opt_nkids},
-	{"l:", NULL, &opt_nreps},
-	{NULL, NULL, NULL},
+static struct tst_option options[] = {
+	{"n:", &opt_maxnprocs, "-n N     Number of processes"},
+	{"c:", &opt_nkids, "-c N     Number of read/write child pairs"},
+	{"l:", &opt_nreps, "-l N     Number of iterations"},
+	{NULL, NULL, NULL}
 };
 
-static void usage(void)
+static void cleanup_msgqueue(int i, int tid)
 {
-	printf("  -n      Number of processes\n");
-	printf("  -c      Number of read/write child pairs\n");
-	printf("  -l      Number of iterations\n");
-}
+	/*
+	 * Decrease the value of i by 1 because it
+	 * is getting incremented even if the fork
+	 * is failing.
+	 */
 
+	i--;
+	/*
+	 * Kill all children & free message queue.
+	 */
+	for (; i >= 0; i--) {
+		(void)kill(rkidarray[i], SIGKILL);
+		(void)kill(wkidarray[i], SIGKILL);
+	}
+	SAFE_MSGCTL(tid, IPC_RMID, NULL);
+}
 
-int main(int argc, char **argv)
+static void term(int sig LTP_ATTRIBUTE_UNUSED)
 {
-	int i, j, ok;
+	int i;
 
-	tst_parse_opts(argc, argv, options, usage);
+	if (procstat == 0) {
+		tst_res(TINFO, "SIGTERM signal received, test killing kids");
+		for (i = 0; i < nprocs; i++) {
+			if (pidarray[i] > 0)
+				if (kill(pidarray[i], SIGTERM) < 0)
+					tst_brk(TBROK, "Kill failed to kill child %d", i);
+		}
+		return;
+	}
 
-	setup();
+	if (procstat == 2)
+		exit(0);
 
-	nreps = MAXNREPS;
-	nkids = MAXNKIDS;
+	if (tid == -1)
+		exit(1);
 
-	if (opt_nreps) {
-		nreps = atoi(opt_nreps);
-		if (nreps > MAXNREPS) {
-			tst_resm(TINFO,
-				 "Requested number of iterations too large, "
-				 "setting to Max. of %d", MAXNREPS);
-			nreps = MAXNREPS;
-		}
+	for (i = 0; i < nkids; i++) {
+		if (rkidarray[i] > 0)
+			(void)kill(rkidarray[i], SIGTERM);
+		if (wkidarray[i] > 0)
+			(void)kill(wkidarray[i], SIGTERM);
 	}
+}
 
-	if (opt_nkids) {
-		nkids = atoi(opt_nkids);
-		if (nkids > MAXNKIDS) {
-			tst_resm(TINFO,
-				 "Requested number of read/write pairs too "
-				 "large, setting to Max. of %d", MAXNKIDS);
-			nkids = MAXNKIDS;
+static void dotest_iteration(int off)
+{
+	key_t key;
+	int i, count, status;
+	pid_t pid;
+	memset(pidarray, 0, sizeof(pidarray));
+
+	for (i = 0; i < nprocs; i++) {
+		key = keyarray[off + i];
+		pid = SAFE_FORK();
+		if (pid == 0) {
+			procstat = 1;
+			dotest(key, i);
+			exit(0);
 		}
+		pidarray[i] = pid;
 	}
 
-
-	if (opt_maxnprocs) {
-		if (atoi(opt_maxnprocs) > maxnprocs) {
-			tst_resm(TINFO,
-				 "Requested number of processes too large, "
-				 "setting to Max. of %d", MSGMNI);
+	count = 0;
+	while (1) {
+		if ((wait(&status)) > 0) {
+			if (status >> 8 != 0)
+				tst_brk(TFAIL,
+					"Child exit status = %d", status >> 8);
+			count++;
 		} else {
-			maxnprocs = atoi(opt_maxnprocs);
+			if (errno != EINTR)
+				break;
+			tst_res(TINFO, "Signal detected during wait");
 		}
 	}
+	/* Make sure proper number of children exited */
+	if (count != nprocs)
+		tst_brk(TFAIL,
+			"Wrong number of children exited, Saw %d, Expected %d",
+			count, nprocs);
+}
+
+static void verify_msgstress(void)
+{
+	int i, j, ok;
 
 	procstat = 0;
 	srand48((unsigned)getpid() + (unsigned)(getppid() << 16));
 	tid = -1;
 
-	/* Setup signal handling routine */
-	if (sigset(SIGTERM, term) == SIG_ERR)
-		tst_brkm(TFAIL, cleanup, "Sigset SIGTERM failed");
-
-	/* Set up array of unique keys for use in allocating message
-	 * queues
-	 */
+	/*Set up array of unique keys for use in allocating message queues*/
 	for (i = 0; i < MSGMNI; i++) {
 		ok = 1;
 		do {
@@ -161,15 +167,11 @@ int main(int argc, char **argv)
 			}
 		} while (ok == 0);
 	}
-	/* Fork a number of processes, each of which will
+	/* Fork a number of processes (nprocs), each of which will
 	 * create a message queue with several (nkids) reader/writer
 	 * pairs which will read and write a number (iterations)
 	 * of random length messages with specific values (keys).
-	 *
-	 * We do not fork more than maxnprocs@a time and
-	 * we fork until all the message queues get used.
 	 */
-
 	if (MSGMNI <= maxnprocs) {
 		nprocs = MSGMNI;
 		dotest_iteration(0);
@@ -178,132 +180,49 @@ int main(int argc, char **argv)
 			nprocs = maxnprocs;
 			dotest_iteration(i * maxnprocs);
 		}
-
 		nprocs = MSGMNI % maxnprocs;
 		dotest_iteration(i * maxnprocs);
 	}
 
-	tst_resm(TPASS, "Test ran successfully!");
-
+	tst_res(TPASS, "Test ran successfully!");
 	cleanup();
-	tst_exit();
 }
 
-static void dotest_iteration(int off)
-{
-	key_t key;
-	int i, count, status;
-	pid_t pid;
-
-	memset(pidarray, 0, sizeof(pidarray));
-
-	for (i = 0; i < nprocs; i++) {
-		key = keyarray[off + i];
-
-		if ((pid = FORK_OR_VFORK()) < 0)
-			tst_brkm(TFAIL, cleanup,
-				 "Fork failed (may be OK if under stress)");
-
-		/* Child does this */
-		if (pid == 0) {
-			procstat = 1;
-			exit(dotest(key, i));
-		}
-		pidarray[i] = pid;
-	}
-
-	count = 0;
-	while (1) {
-		if ((wait(&status)) > 0) {
-			if (status >> 8 != PASS)
-				tst_brkm(TFAIL, cleanup,
-					"Child exit status = %d", status >> 8);
-			count++;
-		} else {
-			if (errno != EINTR) {
-				break;
-			}
-#ifdef DEBUG
-			tst_resm(TINFO, "Signal detected during wait");
-#endif
-		}
-	}
-	/* Make sure proper number of children exited */
-	if (count != nprocs)
-		tst_brkm(TFAIL, cleanup,
-			 "Wrong number of children exited, Saw %d, Expected %d",
-			 count, nprocs);
-}
-
-static void cleanup_msgqueue(int i, int tid)
-{
-	/*
-	 * Decrease the value of i by 1 because it
-	 * is getting incremented even if the fork
-	 * is failing.
-	 */
-
-	i--;
-	/*
-	 * Kill all children & free message queue.
-	 */
-	for (; i >= 0; i--) {
-		(void)kill(rkidarray[i], SIGKILL);
-		(void)kill(wkidarray[i], SIGKILL);
-	}
-
-	if (msgctl(tid, IPC_RMID, 0) < 0) {
-		printf("Msgctl error in cleanup_msgqueue %d\n", errno);
-		exit(FAIL);
-	}
-}
-
-static int dotest(key_t key, int child_process)
+static void dotest(key_t key, int child_process)
 {
 	int id, pid;
-	int i, count, status, exit_status;
+	int i, count, status;
 
 	sighold(SIGTERM);
-	if ((id = msgget(key, IPC_CREAT | S_IRUSR | S_IWUSR)) < 0) {
-		printf("msgget() error in child %d: %s\n",
-			child_process, strerror(errno));
-		return FAIL;
-	}
+	id = SAFE_MSGGET(key, IPC_CREAT | S_IRUSR | S_IWUSR);
 	tid = id;
 	sigrelse(SIGTERM);
 
-	exit_status = PASS;
-
 	for (i = 0; i < nkids; i++) {
-		if ((pid = FORK_OR_VFORK()) < 0) {
-			printf("Fork failure in the first child of child group %d\n",
+		pid = fork();
+		if (pid < 0) {
+			tst_res(TFAIL, "Fork failure in the first child of child group %d\n",
 				child_process);
 			cleanup_msgqueue(i, tid);
-			return FAIL;
+			return;
 		}
-		/* First child does this */
 		if (pid == 0) {
 			procstat = 2;
-			exit(doreader(key, tid, getpid(),
-					child_process, nreps));
+			doreader(key, tid, getpid(), child_process, nreps);
+			exit(0);
 		}
 		rkidarray[i] = pid;
-		if ((pid = FORK_OR_VFORK()) < 0) {
-			printf("Fork failure in the second child of child group %d\n",
+		pid = fork();
+		if (pid < 0) {
+			tst_res(TFAIL, "Fork failure in the first child of child group %d\n",
 				child_process);
-			/*
-			 * Kill the reader child process
-			 */
-			(void)kill(rkidarray[i], SIGKILL);
-
 			cleanup_msgqueue(i, tid);
-			return FAIL;
+			return;
 		}
-		/* Second child does this */
 		if (pid == 0) {
 			procstat = 2;
-			exit(dowriter(key, tid, rkidarray[i],
-					child_process, nreps));
+			dowriter(key, tid, rkidarray[i], child_process, nreps);
+			exit(0);
 		}
 		wkidarray[i] = pid;
 	}
@@ -311,18 +230,15 @@ static int dotest(key_t key, int child_process)
 	count = 0;
 	while (1) {
 		if ((wait(&status)) > 0) {
-			if (status >> 8 != PASS) {
+			if (status >> 8 != 0) {
 				printf("Child exit status = %d from child group %d\n",
 					status >> 8, child_process);
 				for (i = 0; i < nkids; i++) {
 					kill(rkidarray[i], SIGTERM);
 					kill(wkidarray[i], SIGTERM);
 				}
-				if (msgctl(tid, IPC_RMID, 0) < 0) {
-					printf("msgctl() error: %s\n",
-						strerror(errno));
-				}
-				return FAIL;
+				SAFE_MSGCTL(tid, IPC_RMID, NULL);
+				return;
 			}
 			count++;
 		} else {
@@ -335,116 +251,74 @@ static int dotest(key_t key, int child_process)
 	if (count != (nkids * 2)) {
 		printf("Wrong number of children exited in child group %d, saw %d, expected %d\n",
 			child_process, count, (nkids * 2));
-		if (msgctl(tid, IPC_RMID, 0) < 0) {
-			printf("msgctl() error: %s\n", strerror(errno));
-		}
-		return FAIL;
-	}
-	if (msgctl(id, IPC_RMID, 0) < 0) {
-		printf("msgctl() failure in child group %d: %s\n",
-			child_process, strerror(errno));
-		return FAIL;
-	}
-	return exit_status;
-}
-
-/* ARGSUSED */
-static void term(int sig LTP_ATTRIBUTE_UNUSED)
-{
-	int i;
-
-	if (procstat == 0) {
-#ifdef DEBUG
-		tst_resm(TINFO, "SIGTERM signal received, test killing kids");
-#endif
-		for (i = 0; i < nprocs; i++) {
-			if (pidarray[i] > 0) {
-				if (kill(pidarray[i], SIGTERM) < 0) {
-					tst_resm(TBROK,
-						 "Kill failed to kill child %d",
-						 i);
-					exit(FAIL);
-				}
-			}
-		}
+		SAFE_MSGCTL(tid, IPC_RMID, NULL);
 		return;
 	}
-
-	if (procstat == 2) {
-		exit(PASS);
-	}
-
-	if (tid == -1) {
-		exit(FAIL);
-	}
-	for (i = 0; i < nkids; i++) {
-		if (rkidarray[i] > 0)
-			kill(rkidarray[i], SIGTERM);
-		if (wkidarray[i] > 0)
-			kill(wkidarray[i], SIGTERM);
-	}
+	SAFE_MSGCTL(id, IPC_RMID, NULL);
 }
 
-void setup(void)
+static void setup(void)
 {
-	int nr_msgqs, free_pids;
+	int nr_msgqs;
+	int threads_max;
+	int free_pids;
 
-	tst_tmpdir();
-	/* You will want to enable some signal handling so you can capture
-	 * unexpected signals like SIGSEGV.
-	 */
-	tst_sig(FORK, DEF_HANDLER, cleanup);
+	SAFE_FILE_SCANF("/proc/sys/kernel/msgmni", "%d", &nr_msgqs);
+	SAFE_FILE_SCANF("/proc/sys/kernel/threads-max", "%d", &threads_max);
 
-	/* One cavet that hasn't been fixed yet.  TEST_PAUSE contains the code to
-	 * fork the test with the -c option.  You want to make sure you do this
-	 * before you create your temporary directory.
-	 */
-	TEST_PAUSE;
+	MSGMNI = nr_msgqs - GET_USED_QUEUES();
+	if (MSGMNI <= 0)
+		tst_brk(TCONF, "Max number of message queues already used, cannot create more.");
 
-	nr_msgqs = get_max_msgqueues();
-	if (nr_msgqs < 0)
-		tst_brkm(TBROK, cleanup, "get_max_msgqueues() failed");
+	tst_res(TINFO, "Found %d available message queues", MSGMNI);
 
-	MSGMNI = nr_msgqs - get_used_msgqueues();
-	if (MSGMNI <= 0)
-		tst_brkm(TBROK, cleanup,
-			 "Max number of message queues already used, cannot create more.");
+	nreps = MAXNREPS;
+	nkids = MAXNKIDS;
 
-	tst_resm(TINFO, "Found %d available message queues", MSGMNI);
+	if (opt_nreps) {
+		nreps = SAFE_STRTOL(opt_nreps, 1, INT_MAX);
+		nreps = min(nreps, MAXNREPS);
+	}
 
-	free_pids = tst_get_free_pids(cleanup);
-	if (free_pids < 0) {
-		tst_brkm(TBROK, cleanup, "Can't obtain free_pid count");
-	} else if (!free_pids) {
-		tst_brkm(TBROK, cleanup, "No free pids");
+	if (opt_nkids) {
+		nkids = SAFE_STRTOL(opt_nkids, 1, INT_MAX);
+		nkids = min(nkids, MAXNKIDS);
 	}
 
-	/* We don't use more than a half of available pids.
-	 * For each child we fork up to 2*maxnkids grandchildren. */
-	maxnprocs = (free_pids / 2) / (1 + 2 * maxnkids);
+	free_pids = tst_get_free_pids();
+	if (free_pids < 0)
+		tst_brk(TBROK, "Can't obtain free_pid count");
+	if (!free_pids)
+		tst_brk(TBROK, "No free pids");
 
+	/*
+	 * We don't use more than a half of available pids.
+	 * For each child we fork up to 2*maxnkids grandchildren.
+	 */
+	free_pids = min(free_pids, 0.3 * threads_max);
+	maxnprocs = (free_pids / 2) / (1 + 2 * nkids);
 	if (!maxnprocs)
-		tst_brkm(TBROK, cleanup, "Not enough free pids");
+		tst_brk(TBROK, "Not enough free pids");
 
-	tst_resm(TINFO, "Using upto %d pids", free_pids / 2);
+	if (opt_maxnprocs) {
+		maxnprocs = SAFE_STRTOL(opt_maxnprocs, 1, maxnprocs);
+	}
+
+	SAFE_SIGNAL(SIGTERM, term);
+	tst_res(TINFO, "Using upto %d pids, %d processes %d read/write pais, %d repeats", free_pids/2, maxnprocs, nkids, nreps);
 }
 
 void cleanup(void)
 {
-	int status;
-
-	/*
-	 * Remove the message queue from the system
-	 */
-#ifdef DEBUG
-	tst_resm(TINFO, "Removing the message queue");
-#endif
-	(void)msgctl(tid, IPC_RMID, NULL);
-	if ((status = msgctl(tid, IPC_STAT, NULL)) != -1) {
-		(void)msgctl(tid, IPC_RMID, NULL);
-		tst_resm(TFAIL, "msgctl(tid, IPC_RMID) failed");
-
-	}
-
-	tst_rmdir();
+	if (tid >= 0)
+		SAFE_MSGCTL(tid, IPC_RMID, NULL);
 }
+
+static struct tst_test test = {
+	.needs_tmpdir = 1,
+	.options = options,
+	.setup = setup,
+	.cleanup = cleanup,
+	.forks_child = 1,
+	.test_all = verify_msgstress,
+};
-- 
2.23.0


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

* [LTP] [PATCH v2 1/2] libs/libltpnewipc: Add libnewmsgctl.c
  2020-06-18  9:41 [LTP] [PATCH v2 1/2] libs/libltpnewipc: Add libnewmsgctl.c Yang Xu
  2020-06-18  9:41 ` [LTP] [PATCH v2 2/2] syscalls/msgstress: scale number of processes accodingly to available RAM Yang Xu
@ 2020-06-24  5:04 ` Yang Xu
  2020-07-16  1:07   ` Yang Xu
  2020-07-22 15:01 ` Cyril Hrubis
  2 siblings, 1 reply; 26+ messages in thread
From: Yang Xu @ 2020-06-24  5:04 UTC (permalink / raw)
  To: ltp

Hi
If we convert msgstress test cases into new api with using 
libnewmsgctl.c, the old libmsgctl.c is useless and we can remove them.

Best Regards
Yang Xu
> From: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
> 
> Add libnewmsgctl.c into ltp new ipc libs, so the upcoming msgstress cleanup cases
> can use doreader/dowirter functions such as old libmsgctl.c does.
> 
> Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
> ---
>   include/libnewmsgctl.h           |  22 +++++++
>   libs/libltpnewipc/libnewmsgctl.c | 102 +++++++++++++++++++++++++++++++
>   2 files changed, 124 insertions(+)
>   create mode 100644 include/libnewmsgctl.h
>   create mode 100644 libs/libltpnewipc/libnewmsgctl.c
> 
> diff --git a/include/libnewmsgctl.h b/include/libnewmsgctl.h
> new file mode 100644
> index 000000000..e48a04277
> --- /dev/null
> +++ b/include/libnewmsgctl.h
> @@ -0,0 +1,22 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (c) 2020 FUJITSU LIMITED. All rights reserved.
> + */
> +
> +#ifndef __LIBNEWMSGCTL_H__
> +#define __LIBNEWMSGCTL_H__
> +
> +struct mbuffer {
> +	long type;
> +	struct {
> +		char len;
> +		char pbytes[99];
> +	} data;
> +};
> +
> +void doreader(long key, int tid, long type, int child, int nreps);
> +void dowriter(long key, int tid, long type, int child, int nreps);
> +void fill_buffer(char *buf, char val, int size);
> +int verify(char *buf, char val, int size, int child);
> +
> +#endif /*__LIBNEWMSGCTL_H__ */
> diff --git a/libs/libltpnewipc/libnewmsgctl.c b/libs/libltpnewipc/libnewmsgctl.c
> new file mode 100644
> index 000000000..1f6eed74a
> --- /dev/null
> +++ b/libs/libltpnewipc/libnewmsgctl.c
> @@ -0,0 +1,102 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (c) 2020 FUJITSU LIMITED. All rights reserved.
> + */
> +
> +#include <errno.h>
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <sys/stat.h>
> +#include <sys/types.h>
> +#include <sys/ipc.h>
> +#include <sys/msg.h>
> +
> +#define TST_NO_DEFAULT_MAIN
> +#include "tst_test.h"
> +#include "tst_safe_sysv_ipc.h"
> +#include "libnewmsgctl.h"
> +
> +void doreader(long key, int tid, long type, int child, int nreps)
> +{
> +	int i, size;
> +	int id;
> +	struct mbuffer buffer;
> +
> +	id = SAFE_MSGGET(key, 0);
> +	if (id != tid) {
> +		tst_res(TFAIL,
> +			"Message queue mismatch in the reader of child group %d for message queue id %d\n",
> +			child, id);
> +		return;
> +	}
> +	for (i = 0; i < nreps; i++) {
> +		memset(&buffer, 0, sizeof(buffer));
> +
> +		size = SAFE_MSGRCV(id, &buffer, 100, type, 0);
> +		if (buffer.type != type) {
> +			tst_res(TFAIL, "Type mismatch in child %d, read #%d, for message got %ld, exected %ld",
> +				child, (i + 1), buffer.type, type);
> +			return;
> +		}
> +		if (buffer.data.len + 1 != size) {
> +			tst_res(TFAIL, "Size mismatch in child %d, read #%d, for message got %d, expected %d",
> +				child, (i + 1), buffer.data.len + 1, size);
> +			return;
> +		}
> +		if (verify(buffer.data.pbytes, (key % 255), size - 1, child)) {
> +			tst_res(TFAIL, "Verify failed in child %d read # = %d, key = %lx\n",
> +				child, (i + 1), key);
> +			return;
> +		}
> +		key++;
> +	}
> +}
> +
> +void dowriter(long key, int tid, long type, int child, int nreps)
> +{
> +	int i, size;
> +	int id;
> +	struct mbuffer buffer;
> +
> +	id = SAFE_MSGGET(key, 0);
> +	if (id != tid) {
> +		tst_res(TFAIL, "Message queue mismatch in the reader of child group %d for message queue id %d\n",
> +			child, id);
> +		return;
> +	}
> +
> +	for (i = 0; i < nreps; i++) {
> +		memset(&buffer, 0, sizeof(buffer));
> +
> +		do {
> +			size = (lrand48() % 99);
> +		} while (size == 0);
> +		fill_buffer(buffer.data.pbytes, (key % 255), size);
> +		buffer.data.len = size;
> +		buffer.type = type;
> +		SAFE_MSGSND(id, &buffer, size + 1, 0);
> +		key++;
> +	}
> +}
> +
> +void fill_buffer(char *buf, char val, int size)
> +{
> +	int i;
> +
> +	for (i = 0; i < size; i++)
> +		buf[i] = val;
> +}
> +
> +/* Check a buffer for correct values */
> +int verify(char *buf, char val, int size, int child)
> +{
> +	while (size-- > 0) {
> +		if (*buf++ != val) {
> +			tst_res(TFAIL, "Verify error in child %d, *buf = %x, val = %x, size = %d\n",
> +				child, *buf, val, size);
> +			return 1;
> +		}
> +	}
> +	return 0;
> +}
> 



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

* [LTP] [PATCH v2 1/2] libs/libltpnewipc: Add libnewmsgctl.c
  2020-06-24  5:04 ` [LTP] [PATCH v2 1/2] libs/libltpnewipc: Add libnewmsgctl.c Yang Xu
@ 2020-07-16  1:07   ` Yang Xu
  0 siblings, 0 replies; 26+ messages in thread
From: Yang Xu @ 2020-07-16  1:07 UTC (permalink / raw)
  To: ltp

Hi!
Does anyone have some comment for this patch set?

Best Regards
Yang Xu
> Hi
> If we convert msgstress test cases into new api with using 
> libnewmsgctl.c, the old libmsgctl.c is useless and we can remove them.
> 
> Best Regards
> Yang Xu
>> From: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
>>
>> Add libnewmsgctl.c into ltp new ipc libs, so the upcoming msgstress 
>> cleanup cases
>> can use doreader/dowirter functions such as old libmsgctl.c does.
>>
>> Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
>> ---
>> ? include/libnewmsgctl.h?????????? |? 22 +++++++
>> ? libs/libltpnewipc/libnewmsgctl.c | 102 +++++++++++++++++++++++++++++++
>> ? 2 files changed, 124 insertions(+)
>> ? create mode 100644 include/libnewmsgctl.h
>> ? create mode 100644 libs/libltpnewipc/libnewmsgctl.c
>>
>> diff --git a/include/libnewmsgctl.h b/include/libnewmsgctl.h
>> new file mode 100644
>> index 000000000..e48a04277
>> --- /dev/null
>> +++ b/include/libnewmsgctl.h
>> @@ -0,0 +1,22 @@
>> +// SPDX-License-Identifier: GPL-2.0-or-later
>> +/*
>> + * Copyright (c) 2020 FUJITSU LIMITED. All rights reserved.
>> + */
>> +
>> +#ifndef __LIBNEWMSGCTL_H__
>> +#define __LIBNEWMSGCTL_H__
>> +
>> +struct mbuffer {
>> +??? long type;
>> +??? struct {
>> +??????? char len;
>> +??????? char pbytes[99];
>> +??? } data;
>> +};
>> +
>> +void doreader(long key, int tid, long type, int child, int nreps);
>> +void dowriter(long key, int tid, long type, int child, int nreps);
>> +void fill_buffer(char *buf, char val, int size);
>> +int verify(char *buf, char val, int size, int child);
>> +
>> +#endif /*__LIBNEWMSGCTL_H__ */
>> diff --git a/libs/libltpnewipc/libnewmsgctl.c 
>> b/libs/libltpnewipc/libnewmsgctl.c
>> new file mode 100644
>> index 000000000..1f6eed74a
>> --- /dev/null
>> +++ b/libs/libltpnewipc/libnewmsgctl.c
>> @@ -0,0 +1,102 @@
>> +// SPDX-License-Identifier: GPL-2.0-or-later
>> +/*
>> + * Copyright (c) 2020 FUJITSU LIMITED. All rights reserved.
>> + */
>> +
>> +#include <errno.h>
>> +#include <stdio.h>
>> +#include <stdlib.h>
>> +#include <string.h>
>> +#include <sys/stat.h>
>> +#include <sys/types.h>
>> +#include <sys/ipc.h>
>> +#include <sys/msg.h>
>> +
>> +#define TST_NO_DEFAULT_MAIN
>> +#include "tst_test.h"
>> +#include "tst_safe_sysv_ipc.h"
>> +#include "libnewmsgctl.h"
>> +
>> +void doreader(long key, int tid, long type, int child, int nreps)
>> +{
>> +??? int i, size;
>> +??? int id;
>> +??? struct mbuffer buffer;
>> +
>> +??? id = SAFE_MSGGET(key, 0);
>> +??? if (id != tid) {
>> +??????? tst_res(TFAIL,
>> +??????????? "Message queue mismatch in the reader of child group %d 
>> for message queue id %d\n",
>> +??????????? child, id);
>> +??????? return;
>> +??? }
>> +??? for (i = 0; i < nreps; i++) {
>> +??????? memset(&buffer, 0, sizeof(buffer));
>> +
>> +??????? size = SAFE_MSGRCV(id, &buffer, 100, type, 0);
>> +??????? if (buffer.type != type) {
>> +??????????? tst_res(TFAIL, "Type mismatch in child %d, read #%d, for 
>> message got %ld, exected %ld",
>> +??????????????? child, (i + 1), buffer.type, type);
>> +??????????? return;
>> +??????? }
>> +??????? if (buffer.data.len + 1 != size) {
>> +??????????? tst_res(TFAIL, "Size mismatch in child %d, read #%d, for 
>> message got %d, expected %d",
>> +??????????????? child, (i + 1), buffer.data.len + 1, size);
>> +??????????? return;
>> +??????? }
>> +??????? if (verify(buffer.data.pbytes, (key % 255), size - 1, child)) {
>> +??????????? tst_res(TFAIL, "Verify failed in child %d read # = %d, 
>> key = %lx\n",
>> +??????????????? child, (i + 1), key);
>> +??????????? return;
>> +??????? }
>> +??????? key++;
>> +??? }
>> +}
>> +
>> +void dowriter(long key, int tid, long type, int child, int nreps)
>> +{
>> +??? int i, size;
>> +??? int id;
>> +??? struct mbuffer buffer;
>> +
>> +??? id = SAFE_MSGGET(key, 0);
>> +??? if (id != tid) {
>> +??????? tst_res(TFAIL, "Message queue mismatch in the reader of child 
>> group %d for message queue id %d\n",
>> +??????????? child, id);
>> +??????? return;
>> +??? }
>> +
>> +??? for (i = 0; i < nreps; i++) {
>> +??????? memset(&buffer, 0, sizeof(buffer));
>> +
>> +??????? do {
>> +??????????? size = (lrand48() % 99);
>> +??????? } while (size == 0);
>> +??????? fill_buffer(buffer.data.pbytes, (key % 255), size);
>> +??????? buffer.data.len = size;
>> +??????? buffer.type = type;
>> +??????? SAFE_MSGSND(id, &buffer, size + 1, 0);
>> +??????? key++;
>> +??? }
>> +}
>> +
>> +void fill_buffer(char *buf, char val, int size)
>> +{
>> +??? int i;
>> +
>> +??? for (i = 0; i < size; i++)
>> +??????? buf[i] = val;
>> +}
>> +
>> +/* Check a buffer for correct values */
>> +int verify(char *buf, char val, int size, int child)
>> +{
>> +??? while (size-- > 0) {
>> +??????? if (*buf++ != val) {
>> +??????????? tst_res(TFAIL, "Verify error in child %d, *buf = %x, val 
>> = %x, size = %d\n",
>> +??????????????? child, *buf, val, size);
>> +??????????? return 1;
>> +??????? }
>> +??? }
>> +??? return 0;
>> +}
>>



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

* [LTP] [PATCH v2 1/2] libs/libltpnewipc: Add libnewmsgctl.c
  2020-06-18  9:41 [LTP] [PATCH v2 1/2] libs/libltpnewipc: Add libnewmsgctl.c Yang Xu
  2020-06-18  9:41 ` [LTP] [PATCH v2 2/2] syscalls/msgstress: scale number of processes accodingly to available RAM Yang Xu
  2020-06-24  5:04 ` [LTP] [PATCH v2 1/2] libs/libltpnewipc: Add libnewmsgctl.c Yang Xu
@ 2020-07-22 15:01 ` Cyril Hrubis
  2020-07-23  6:29   ` Yang Xu
  2 siblings, 1 reply; 26+ messages in thread
From: Cyril Hrubis @ 2020-07-22 15:01 UTC (permalink / raw)
  To: ltp

Hi!
> Add libnewmsgctl.c into ltp new ipc libs, so the upcoming msgstress cleanup cases
> can use doreader/dowirter functions such as old libmsgctl.c does.
> 
> Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
> ---
>  include/libnewmsgctl.h           |  22 +++++++
>  libs/libltpnewipc/libnewmsgctl.c | 102 +++++++++++++++++++++++++++++++
>  2 files changed, 124 insertions(+)
>  create mode 100644 include/libnewmsgctl.h
>  create mode 100644 libs/libltpnewipc/libnewmsgctl.c

As far as I can tell this is only used in msgstress testcases right?

So unless we plan to use it from different tests it does not make much
sense to export it to the top level include and libs.

Or alternatively we do have libltpnewipc we can pust put the
libnewmsgctl.c to that directory and with that we will have a single
System V IPC helper library.

-- 
Cyril Hrubis
chrubis@suse.cz

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

* [LTP] [PATCH v2 2/2] syscalls/msgstress: scale number of processes accodingly to available RAM
  2020-06-18  9:41 ` [LTP] [PATCH v2 2/2] syscalls/msgstress: scale number of processes accodingly to available RAM Yang Xu
@ 2020-07-22 15:45   ` Cyril Hrubis
  2020-07-23  6:34     ` Yang Xu
  2020-10-21 12:57     ` [LTP] [PATCH v3 1/4] syscalls/msgstress: Add common file for msgstress Yang Xu
  0 siblings, 2 replies; 26+ messages in thread
From: Cyril Hrubis @ 2020-07-22 15:45 UTC (permalink / raw)
  To: ltp

Hi!
The main problem with this patch is that it's doing too much.

The conversion to the new library should be ideally done in a separate
patch, then we should start working on getting the limits right.

For the limits I would really like to introduce a library function that
would return how many processes test can run before the system runs out
of memory then we can build on the top of that and create a library
function to return now many message queues we can run. As it is the code
is still copy&pasted between the testcases.

So please can we do things in smaller, well defined, steps?

-- 
Cyril Hrubis
chrubis@suse.cz

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

* [LTP] [PATCH v2 1/2] libs/libltpnewipc: Add libnewmsgctl.c
  2020-07-22 15:01 ` Cyril Hrubis
@ 2020-07-23  6:29   ` Yang Xu
  0 siblings, 0 replies; 26+ messages in thread
From: Yang Xu @ 2020-07-23  6:29 UTC (permalink / raw)
  To: ltp

Hi Cyril


> As far as I can tell this is only used in msgstress testcases right?
> 
> So unless we plan to use it from different tests it does not make much
> sense to export it to the top level include and libs.
> 
> Or alternatively we do have libltpnewipc we can pust put the
> libnewmsgctl.c to that directory and with that we will have a single
> System V IPC helper library.
I think your word means merge libnewmsgctl.c and head file into 
libnewipc.c. So we only have a single system V ipc lib. I will do it.

Best Regards
Yang Xu



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

* [LTP] [PATCH v2 2/2] syscalls/msgstress: scale number of processes accodingly to available RAM
  2020-07-22 15:45   ` Cyril Hrubis
@ 2020-07-23  6:34     ` Yang Xu
  2020-10-21 12:57     ` [LTP] [PATCH v3 1/4] syscalls/msgstress: Add common file for msgstress Yang Xu
  1 sibling, 0 replies; 26+ messages in thread
From: Yang Xu @ 2020-07-23  6:34 UTC (permalink / raw)
  To: ltp

HI Cyril


> Hi!
> The main problem with this patch is that it's doing too much.
Sorry for this. This patch is really unfriendly to the reviewer because 
it is too much.
> 
> The conversion to the new library should be ideally done in a separate
> patch, then we should start working on getting the limits right.
Yes, I will do this as your advise.
> 
> For the limits I would really like to introduce a library function that
> would return how many processes test can run before the system runs out
> of memory then we can build on the top of that and create a library
> function to return now many message queues we can run. As it is the code
> is still copy&pasted between the testcases.
Will do it.
> 
> So please can we do things in smaller, well defined, steps?
Of course.
> 



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

* [LTP] [PATCH v3 1/4] syscalls/msgstress: Add common file for msgstress
  2020-07-22 15:45   ` Cyril Hrubis
  2020-07-23  6:34     ` Yang Xu
@ 2020-10-21 12:57     ` Yang Xu
  2020-10-21 12:57       ` [LTP] [PATCH v3 2/4] syscalls/msgstress*: cleanup and convert into new api Yang Xu
                         ` (3 more replies)
  1 sibling, 4 replies; 26+ messages in thread
From: Yang Xu @ 2020-10-21 12:57 UTC (permalink / raw)
  To: ltp

Copy old libmsgctl.c three functions(doreader,dowriter, fill_buffer, verify)
into this common file. The reason for not putting it into lib directory because
only msgstress cases use these functions. So raising them into lib level makes
no sense.

Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
---
 .../kernel/syscalls/ipc/msgstress/Makefile    |  2 +-
 .../syscalls/ipc/msgstress/msgstress_common.c | 95 +++++++++++++++++++
 .../syscalls/ipc/msgstress/msgstress_common.h | 26 +++++
 3 files changed, 122 insertions(+), 1 deletion(-)
 create mode 100644 testcases/kernel/syscalls/ipc/msgstress/msgstress_common.c
 create mode 100644 testcases/kernel/syscalls/ipc/msgstress/msgstress_common.h

diff --git a/testcases/kernel/syscalls/ipc/msgstress/Makefile b/testcases/kernel/syscalls/ipc/msgstress/Makefile
index b821bda01..2c8fa8e5b 100644
--- a/testcases/kernel/syscalls/ipc/msgstress/Makefile
+++ b/testcases/kernel/syscalls/ipc/msgstress/Makefile
@@ -6,7 +6,7 @@ top_srcdir              ?= ../../../../..
 LTPLIBS = ltpipc
 
 include $(top_srcdir)/include/mk/testcases.mk
-
+FILTER_OUT_MAKE_TARGETS         := msgstress_common
 LTPLDLIBS  += -lltpipc
 
 include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/syscalls/ipc/msgstress/msgstress_common.c b/testcases/kernel/syscalls/ipc/msgstress/msgstress_common.c
new file mode 100644
index 000000000..3431355f6
--- /dev/null
+++ b/testcases/kernel/syscalls/ipc/msgstress/msgstress_common.c
@@ -0,0 +1,95 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) International Business Machines  Corp., 2002
+ * Copyright (c) 2013 Oracle and/or its affiliates. All Rights Reserved.
+ * Copyright (c) 2020 FUJITSU LIMITED. All rights reserved?
+ */
+
+#define TST_NO_DEFAULT_MAIN
+#include "msgstress_common.h"
+
+int verify(char *buf, char val, int size, int child)
+{
+	while (size-- > 0) {
+		if (*buf++ != val) {
+			tst_res(TFAIL, "Verify error in child %d, *buf = %x, "
+				"val = %x, size = %d\n", child, *buf, val,
+				size);
+			return 1;
+		}
+	}
+	return 0;
+}
+
+void do_reader(long key, int tid, long type, int child, int nreps)
+{
+	int i, size;
+	int id;
+	struct mbuffer buffer;
+
+	id = SAFE_MSGGET(key, 0);
+	if (id != tid) {
+		tst_res(TFAIL,
+			"Message queue mismatch in the reader of child group"
+			" %d for message queue id %d\n", child, id);
+		return;
+	}
+	for (i = 0; i < nreps; i++) {
+		memset(&buffer, 0, sizeof(buffer));
+
+		size = SAFE_MSGRCV(id, &buffer, 100, type, 0);
+		if (buffer.type != type) {
+			tst_res(TFAIL, "Type mismatch in child %d, read #%d, "
+				"for message got %ld, exected %ld",
+				child, (i + 1), buffer.type, type);
+			return;
+		}
+		if (buffer.data.len + 1 != size) {
+			tst_res(TFAIL, "Size mismatch in child %d, read #%d, "
+				"for message got %d, expected %d",
+				child, (i + 1), buffer.data.len + 1, size);
+			return;
+		}
+		if (verify(buffer.data.pbytes, (key % 255), size - 1, child)) {
+			tst_res(TFAIL, "Verify failed in child %d read # = %d, "
+				"key = %lx\n", child, (i + 1), key);
+			return;
+		}
+		key++;
+	}
+}
+
+void fill_buffer(char *buf, char val, int size)
+{
+	int i;
+
+	for (i = 0; i < size; i++)
+		buf[i] = val;
+}
+
+void do_writer(long key, int tid, long type, int child, int nreps)
+{
+	int i, size;
+	int id;
+	struct mbuffer buffer;
+
+	id = SAFE_MSGGET(key, 0);
+	if (id != tid) {
+		tst_res(TFAIL, "Message queue mismatch in the reader of child"
+			" group %d for message queue id %d\n", child, id);
+		return;
+	}
+
+	for (i = 0; i < nreps; i++) {
+		memset(&buffer, 0, sizeof(buffer));
+
+		do {
+			size = (lrand48() % 99);
+		} while (size == 0);
+		fill_buffer(buffer.data.pbytes, (key % 255), size);
+		buffer.data.len = size;
+		buffer.type = type;
+		SAFE_MSGSND(id, &buffer, size + 1, 0);
+		key++;
+	}
+}
diff --git a/testcases/kernel/syscalls/ipc/msgstress/msgstress_common.h b/testcases/kernel/syscalls/ipc/msgstress/msgstress_common.h
new file mode 100644
index 000000000..81e2f288b
--- /dev/null
+++ b/testcases/kernel/syscalls/ipc/msgstress/msgstress_common.h
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2020 FUJITSU LIMITED. All rights reserved.
+ * Author: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
+ */
+
+#ifndef MSGSTRESS_COMMON_H
+#define MSGSTRESS_COMMON_H
+
+#include <stdlib.h>
+#include "tst_safe_sysv_ipc.h"
+#include "tst_test.h"
+
+struct mbuffer {
+	long type;
+	struct {
+		char len;
+		char pbytes[99];
+	} data;
+};
+
+void do_reader(long key, int tid, long type, int child, int nreps);
+void do_writer(long key, int tid, long type, int child, int nreps);
+
+#endif
+
-- 
2.23.0




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

* [LTP] [PATCH v3 2/4] syscalls/msgstress*: cleanup and convert into new api
  2020-10-21 12:57     ` [LTP] [PATCH v3 1/4] syscalls/msgstress: Add common file for msgstress Yang Xu
@ 2020-10-21 12:57       ` Yang Xu
  2020-11-11 16:31         ` Cyril Hrubis
  2020-10-21 12:57       ` [LTP] [PATCH v3 3/4] libmsgctl: Remove it Yang Xu
                         ` (2 subsequent siblings)
  3 siblings, 1 reply; 26+ messages in thread
From: Yang Xu @ 2020-10-21 12:57 UTC (permalink / raw)
  To: ltp

1)use some safe macros
2)remove SIGTERM signal handler and ignore it
3)remove CODEFIRE ifdef

Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
---
 .../kernel/syscalls/ipc/msgstress/Makefile    |   7 +-
 .../syscalls/ipc/msgstress/msgstress01.c      | 282 ++++---------
 .../syscalls/ipc/msgstress/msgstress02.c      | 371 +++++------------
 .../syscalls/ipc/msgstress/msgstress03.c      | 277 ++++---------
 .../syscalls/ipc/msgstress/msgstress04.c      | 372 +++++-------------
 5 files changed, 366 insertions(+), 943 deletions(-)

diff --git a/testcases/kernel/syscalls/ipc/msgstress/Makefile b/testcases/kernel/syscalls/ipc/msgstress/Makefile
index 2c8fa8e5b..aac90df51 100644
--- a/testcases/kernel/syscalls/ipc/msgstress/Makefile
+++ b/testcases/kernel/syscalls/ipc/msgstress/Makefile
@@ -3,10 +3,13 @@
 
 top_srcdir              ?= ../../../../..
 
-LTPLIBS = ltpipc
+LTPLIBS = ltpnewipc
 
 include $(top_srcdir)/include/mk/testcases.mk
+
+LTPLDLIBS  = -lltpnewipc
 FILTER_OUT_MAKE_TARGETS         := msgstress_common
-LTPLDLIBS  += -lltpipc
+MAKE_TARGETS            := $(patsubst $(abs_srcdir)/%.c,%,$(wildcard $(abs_srcdir)/*[1-4].c))
+$(MAKE_TARGETS): %: msgstress_common.o
 
 include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/syscalls/ipc/msgstress/msgstress01.c b/testcases/kernel/syscalls/ipc/msgstress/msgstress01.c
index 0a660c042..0046039ad 100644
--- a/testcases/kernel/syscalls/ipc/msgstress/msgstress01.c
+++ b/testcases/kernel/syscalls/ipc/msgstress/msgstress01.c
@@ -1,25 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /*
  * Copyright (c) International Business Machines  Corp., 2002
- *
- * This program is free software;  you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY;  without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
- * the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program;  if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Copyright (c) 2020 FUJITSU LIMITED. All rights reserved.
  *
  * 06/30/2001   Port to Linux   nsharoff@us.ibm.com
  * 11/06/2002   Port to LTP     dbarrera@us.ibm.com
- */
-
-/*
+ * 10/21/2020   Convert to new api xuyang2018.jy@cn.fujitsu.com
+ *
  * Get and manipulate a message queue.
  */
 
@@ -31,105 +18,61 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <unistd.h>
-#include <values.h>
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <sys/stat.h>
 #include <sys/ipc.h>
 #include <sys/msg.h>
-#include "test.h"
-#include "ipcmsg.h"
-#include "libmsgctl.h"
+#include "tst_test.h"
+#include "libnewipc.h"
+#include "tst_safe_sysv_ipc.h"
+#include "msgstress_common.h"
 
-char *TCID = "msgstress01";
-int TST_TOTAL = 1;
-
-#ifndef CONFIG_COLDFIRE
-#define MAXNPROCS	1000000	/* This value is set to an arbitrary high limit. */
-#else
-#define MAXNPROCS	 100000	/* Coldfire can't deal with 1000000 */
-#endif
+#define MAXNPROCS       1000000
 #define MAXNREPS	100000
 
 static key_t keyarray[MAXNPROCS];
-static int pidarray[MAXNPROCS];
 static int tid;
 static int MSGMNI, nprocs, nreps;
-static int procstat;
-static int mykid;
-
-void setup(void);
-void cleanup(void);
-
-static int dotest(key_t key, int child_process);
-static void sig_handler();
-
 static char *opt_nprocs;
 static char *opt_nreps;
+static void cleanup(void);
 
-static option_t options[] = {
-	{"n:", NULL, &opt_nprocs},
-	{"l:", NULL, &opt_nreps},
-	{NULL, NULL, NULL},
+static struct tst_option options[] = {
+	{"n:", &opt_nprocs, "-n N     Number of processes"},
+	{"l:", &opt_nreps, "-l N     Number of iterations"},
+	{NULL, NULL, NULL}
 };
 
-static void usage(void)
-{
-	printf("  -n      Number of processes\n");
-	printf("  -l      Number of iterations\n");
-}
-
-int main(int argc, char **argv)
+static void dotest(key_t key, int child_process)
 {
-	int i, j, ok, pid;
-	int count, status;
-	struct sigaction act;
-
-	tst_parse_opts(argc, argv, options, usage);
-
-	setup();
+	int pid;
 
-	nreps = MAXNREPS;
-	nprocs = MSGMNI;
+	tid = SAFE_MSGGET(key, IPC_CREAT | S_IRUSR | S_IWUSR);
 
-	if (opt_nreps) {
-		nreps = atoi(opt_nreps);
-		if (nreps > MAXNREPS) {
-			tst_resm(TINFO,
-				 "Requested number of iterations too large, "
-				 "setting to Max. of %d", MAXNREPS);
-			nreps = MAXNREPS;
-		}
+	pid = SAFE_FORK();
+	if (pid == 0) {
+		do_reader(key, tid, 1, child_process, nreps);
+		exit(0);
 	}
 
-	if (opt_nprocs) {
-		nprocs = atoi(opt_nprocs);
-		if (nprocs > MSGMNI) {
-			tst_resm(TINFO,
-				 "Requested number of processes too large, "
-				 "setting to Max. of %d", MSGMNI);
-			nprocs = MSGMNI;
-		}
-	}
+	do_writer(key, tid, 1, child_process, nreps);
+	SAFE_WAIT(NULL);
+	SAFE_MSGCTL(tid, IPC_RMID, NULL);
+}
+
+static void verify_msgstress(void)
+{
+	int i, j, ok, pid;
+	int count;
 
 	srand(getpid());
 	tid = -1;
 
-	/* Setup signal handling routine */
-	memset(&act, 0, sizeof(act));
-	act.sa_handler = sig_handler;
-	sigemptyset(&act.sa_mask);
-	sigaddset(&act.sa_mask, SIGTERM);
-	if (sigaction(SIGTERM, &act, NULL) < 0) {
-		tst_brkm(TFAIL, NULL, "Sigset SIGTERM failed");
-	}
-	/* Set up array of unique keys for use in allocating message
-	 * queues
-	 */
+	/* Set up array of unique keys for use in allocating message queues */
 	for (i = 0; i < nprocs; i++) {
 		ok = 1;
 		do {
-			/* Get random key */
 			keyarray[i] = (key_t) rand();
 			/* Make sure key is unique and not private */
 			if (keyarray[i] == IPC_PRIVATE) {
@@ -146,156 +89,83 @@ int main(int argc, char **argv)
 		} while (ok == 0);
 	}
 
-	/* Fork a number of processes, each of which will
+	/*
+	 * Fork a number of processes, each of which will
 	 * create a message queue with one reader/writer
 	 * pair which will read and write a number (iterations)
 	 * of random length messages with specific values.
 	 */
-
 	for (i = 0; i < nprocs; i++) {
-		fflush(stdout);
-		if ((pid = FORK_OR_VFORK()) < 0) {
-			tst_brkm(TFAIL,
-				 NULL,
-				 "\tFork failed (may be OK if under stress)");
-		}
-		/* Child does this */
+		pid = SAFE_FORK();
 		if (pid == 0) {
-			procstat = 1;
-			exit(dotest(keyarray[i], i));
+			dotest(keyarray[i], i);
+			exit(0);
 		}
-		pidarray[i] = pid;
 	}
 
 	count = 0;
+
 	while (1) {
-		if ((wait(&status)) > 0) {
-			if (status >> 8 != 0) {
-				tst_brkm(TFAIL, NULL,
-					 "Child exit status = %d",
-					 status >> 8);
-			}
+		if (wait(NULL) > 0) {
 			count++;
 		} else {
-			if (errno != EINTR) {
+			if (errno != EINTR)
 				break;
-			}
-#ifdef DEBUG
-			tst_resm(TINFO, "Signal detected during wait");
-#endif
 		}
 	}
-	/* Make sure proper number of children exited */
-	if (count != nprocs) {
-		tst_brkm(TFAIL,
-			 NULL,
-			 "Wrong number of children exited, Saw %d, Expected %d",
-			 count, nprocs);
-	}
 
-	tst_resm(TPASS, "Test ran successfully!");
+	if (count != nprocs)
+		tst_brk(TFAIL, "Wrong number of children exited, Saw %d, Expected %d",
+			count, nprocs);
 
+	tst_res(TPASS, "Test ran successfully!");
 	cleanup();
-	tst_exit();
-}
-
-static int dotest(key_t key, int child_process)
-{
-	int id, pid;
-	int ret, status;
-
-	sighold(SIGTERM);
-	TEST(msgget(key, IPC_CREAT | S_IRUSR | S_IWUSR));
-	if (TEST_RETURN < 0) {
-		printf("msgget() error in child %d: %s\n",
-			child_process, strerror(TEST_ERRNO));
-
-		return FAIL;
-	}
-	tid = id = TEST_RETURN;
-	sigrelse(SIGTERM);
-
-	fflush(stdout);
-	if ((pid = FORK_OR_VFORK()) < 0) {
-		printf("\tFork failed (may be OK if under stress)\n");
-		TEST(msgctl(tid, IPC_RMID, 0));
-		if (TEST_RETURN < 0) {
-			printf("mscgtl() error in cleanup: %s\n",
-				strerror(TEST_ERRNO));
-		}
-		return FAIL;
-	}
-	/* Child does this */
-	if (pid == 0)
-		exit(doreader(key, id, 1, child_process, nreps));
-	/* Parent does this */
-	mykid = pid;
-	procstat = 2;
-	ret = dowriter(key, id, 1, child_process, nreps);
-	wait(&status);
-
-	if (ret != PASS)
-		exit(FAIL);
-
-	if ((!WIFEXITED(status) || (WEXITSTATUS(status) != PASS)))
-		exit(FAIL);
-
-	TEST(msgctl(id, IPC_RMID, 0));
-	if (TEST_RETURN < 0) {
-		printf("msgctl() errno %d: %s\n",
-			TEST_ERRNO, strerror(TEST_ERRNO));
-
-		return FAIL;
-	}
-	return PASS;
 }
 
-static void sig_handler(void)
-{
-}
-
-void setup(void)
+static void setup(void)
 {
 	int nr_msgqs;
 
-	tst_tmpdir();
+	SAFE_FILE_SCANF("/proc/sys/kernel/msgmni", "%d", &nr_msgqs);
 
-	tst_sig(FORK, DEF_HANDLER, cleanup);
+	nr_msgqs -= GET_USED_QUEUES();
+	if (nr_msgqs <= 0)
+		tst_brk(TCONF, "Max number of message queues already used, "
+			"cannot create more.");
 
-	TEST_PAUSE;
+	MSGMNI = min(nr_msgqs, NR_MSGQUEUES);
 
-	nr_msgqs = get_max_msgqueues();
-	if (nr_msgqs < 0)
-		cleanup();
+	if (opt_nreps) {
+		nreps = SAFE_STRTOL(opt_nreps, 1, INT_MAX);
+		nreps = min(nreps, MAXNREPS);
+	} else {
+		nreps = MAXNREPS;
+	}
 
-	nr_msgqs -= get_used_msgqueues();
-	if (nr_msgqs <= 0) {
-		tst_resm(TBROK,
-			 "Max number of message queues already used, cannot create more.");
-		cleanup();
+	if (opt_nprocs) {
+		nprocs = SAFE_STRTOL(opt_nprocs, 1, INT_MAX);
+		nprocs = min(nprocs, MAXNPROCS);
+		nprocs = min(nprocs, MSGMNI);
+	} else {
+		nprocs = MSGMNI;
 	}
 
-	/*
-	 * Since msgmni scales to the memory size, it may reach huge values
-	 * that are not necessary for this test.
-	 * That's why we define NR_MSGQUEUES as a high boundary for it.
-	 */
-	MSGMNI = min(nr_msgqs, NR_MSGQUEUES);
+	SAFE_SIGNAL(SIGTERM, SIG_IGN);
+	tst_res(TINFO, "Number of message queues is %d, process is %d, "
+		"iterations is %d", MSGMNI, nprocs, nreps);
 }
 
 void cleanup(void)
 {
-	int status;
-
-#ifdef DEBUG
-	tst_resm(TINFO, "Removing the message queue");
-#endif
-	(void)msgctl(tid, IPC_RMID, NULL);
-	if ((status = msgctl(tid, IPC_STAT, NULL)) != -1) {
-		(void)msgctl(tid, IPC_RMID, NULL);
-		tst_resm(TFAIL, "msgctl(tid, IPC_RMID) failed");
-
-	}
-
-	tst_rmdir();
+	if (tid >= 0)
+		SAFE_MSGCTL(tid, IPC_RMID, NULL);
 }
+
+static struct tst_test test = {
+	.needs_tmpdir = 1,
+	.options = options,
+	.setup = setup,
+	.cleanup = cleanup,
+	.forks_child = 1,
+	.test_all = verify_msgstress,
+};
diff --git a/testcases/kernel/syscalls/ipc/msgstress/msgstress02.c b/testcases/kernel/syscalls/ipc/msgstress/msgstress02.c
index e15131043..50e0310f0 100644
--- a/testcases/kernel/syscalls/ipc/msgstress/msgstress02.c
+++ b/testcases/kernel/syscalls/ipc/msgstress/msgstress02.c
@@ -1,25 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /*
  * Copyright (c) International Business Machines  Corp., 2002
- *
- * This program is free software;  you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY;  without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
- * the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program;  if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Copyright (c) 2020 FUJITSU LIMITED. All rights reserved.
  *
  * 06/30/2001   Port to Linux   nsharoff@us.ibm.com
  * 11/11/2002   Port to LTP     dbarrera@us.ibm.com
- */
-
-/*
+ * 10/21/2020   Convert to new api xuyang2018.jy@cn.fujitsu.com
+ *
  * Get and manipulate a message queue.
  */
 
@@ -35,19 +22,13 @@
 #include <string.h>
 #include <stdlib.h>
 #include <unistd.h>
-#include "test.h"
-#include "ipcmsg.h"
-#include "libmsgctl.h"
-
-char *TCID = "msgstress02";
-int TST_TOTAL = 1;
+#include "tst_test.h"
+#include "libnewipc.h"
+#include "tst_safe_sysv_ipc.h"
+#include "msgstress_common.h"
 
 #define MAXNREPS	1000
-#ifndef CONFIG_COLDFIRE
 #define MAXNPROCS	 1000000	/* This value is set to an arbitrary high limit. */
-#else
-#define MAXNPROCS	 100000	/* Coldfire can't deal with 1000000 */
-#endif
 #define MAXNKIDS	10
 
 static key_t keyarray[MAXNPROCS];
@@ -56,84 +37,43 @@ static int rkidarray[MAXNKIDS];
 static int wkidarray[MAXNKIDS];
 static int tid;
 static int nprocs, nreps, nkids, MSGMNI;
-static int procstat;
-
-void setup(void);
-void cleanup(void);
-
-static void term(int);
-static int dotest(key_t, int);
-static void cleanup_msgqueue(int i, int tid);
-
 static char *opt_nprocs;
 static char *opt_nkids;
 static char *opt_nreps;
-
-static option_t options[] = {
-	{"n:", NULL, &opt_nprocs},
-	{"c:", NULL, &opt_nkids},
-	{"l:", NULL, &opt_nreps},
-	{NULL, NULL, NULL},
+static void cleanup(void);
+static void dotest(key_t, int);
+
+static struct tst_option options[] = {
+	{"n:", &opt_nprocs, "-n N     Number of processes"},
+	{"c:", &opt_nkids, "-c -N    Number of read/write child pairs"},
+	{"l:", &opt_nreps, "-l N     Number of iterations"},
+	{NULL, NULL, NULL}
 };
 
-static void usage(void)
+static void cleanup_msgqueue(int i, int tid)
 {
-	printf("  -n      Number of processes\n");
-	printf("  -c      Number of read/write child pairs\n");
-	printf("  -l      Number of iterations\n");
+	/*
+	 * Decrease the value of i by 1 because it is getting incremented
+	 * even if the fork is failing.
+	 */
+	i--;
+
+	 /* Kill all children & free message queue. */
+	for (; i >= 0; i--) {
+		(void)kill(rkidarray[i], SIGKILL);
+		(void)kill(wkidarray[i], SIGKILL);
+	}
+	SAFE_MSGCTL(tid, IPC_RMID, 0);
 }
 
-int main(int argc, char **argv)
+static void verify_msgstress(void)
 {
 	int i, j, ok, pid;
-	int count, status;
-
-	tst_parse_opts(argc, argv, options, usage);
+	int count;
 
-	setup();
-
-	nreps = MAXNREPS;
-	nprocs = MSGMNI;
-	nkids = MAXNKIDS;
-
-	if (opt_nreps) {
-		nreps = atoi(opt_nreps);
-		if (nreps > MAXNREPS) {
-			tst_resm(TINFO,
-				 "Requested number of iterations too large, "
-				 "setting to Max. of %d", MAXNREPS);
-			nreps = MAXNREPS;
-		}
-	}
-
-	if (opt_nprocs) {
-		nprocs = atoi(opt_nprocs);
-		if (nprocs > MSGMNI) {
-			tst_resm(TINFO,
-				 "Requested number of processes too large, "
-				 "setting to Max. of %d", MSGMNI);
-			nprocs = MSGMNI;
-		}
-	}
-
-	if (opt_nkids) {
-		nkids = atoi(opt_nkids);
-		if (nkids > MAXNKIDS) {
-			tst_resm(TINFO,
-				 "Requested number of read/write pairs too "
-				 "large, setting to Max. of %d", MAXNKIDS);
-			nkids = MAXNKIDS;
-		}
-	}
-
-	procstat = 0;
 	srand48((unsigned)getpid() + (unsigned)(getppid() << 16));
 	tid = -1;
 
-	/* Setup signal handleing routine */
-	if (sigset(SIGTERM, term) == SIG_ERR) {
-		tst_brkm(TFAIL, NULL, "Sigset SIGTERM failed");
-	}
 	/* Set up array of unique keys for use in allocating message
 	 * queues
 	 */
@@ -163,142 +103,76 @@ int main(int argc, char **argv)
 	 */
 
 	for (i = 0; i < nprocs; i++) {
-		fflush(stdout);
-		if ((pid = FORK_OR_VFORK()) < 0) {
-			tst_brkm(TFAIL,
-				 NULL,
-				 "\tFork failed (may be OK if under stress)");
-		}
+		pid = SAFE_FORK();
 		/* Child does this */
 		if (pid == 0) {
-			procstat = 1;
-			exit(dotest(keyarray[i], i));
+			dotest(keyarray[i], i);
+			exit(0);
 		}
 		pidarray[i] = pid;
 	}
 
 	count = 0;
 	while (1) {
-		if ((wait(&status)) > 0) {
-			if (status >> 8 != PASS) {
-				tst_brkm(TFAIL, NULL,
-					 "Child exit status = %d",
-					 status >> 8);
-			}
+		if ((wait(NULL)) > 0) {
 			count++;
+
 		} else {
 			if (errno != EINTR) {
 				break;
 			}
-#ifdef DEBUG
-			tst_resm(TINFO, "Signal detected during wait");
-#endif
 		}
 	}
 	/* Make sure proper number of children exited */
-	if (count != nprocs) {
-		tst_brkm(TFAIL,
-			 NULL,
-			 "Wrong number of children exited, Saw %d, Expected %d",
-			 count, nprocs);
-	}
+	if (count != nprocs)
+		tst_brk(TFAIL,
+			"Wrong number of children exited, Saw %d, Expected %d",
+			count, nprocs);
 
-	tst_resm(TPASS, "Test ran successfully!");
+	tst_res(TPASS, "Test ran successfully!");
 
 	cleanup();
-	tst_exit();
-}
-
-static void cleanup_msgqueue(int i, int tid)
-{
-	/*
-	 * Decrease the value of i by 1 because it
-	 * is getting incremented even if the fork
-	 * is failing.
-	 */
-
-	i--;
-	/*
-	 * Kill all children & free message queue.
-	 */
-	for (; i >= 0; i--) {
-		(void)kill(rkidarray[i], SIGKILL);
-		(void)kill(wkidarray[i], SIGKILL);
-	}
-
-	if (msgctl(tid, IPC_RMID, 0) < 0) {
-		tst_brkm(TFAIL | TERRNO, NULL, "Msgctl error in cleanup");
-	}
 }
 
-static int dotest(key_t key, int child_process)
+static void dotest(key_t key, int child_process)
 {
-	int id, pid;
-	int i, count, status, exit_status;
-
-	sighold(SIGTERM);
-	if ((id = msgget(key, IPC_CREAT | S_IRUSR | S_IWUSR)) < 0) {
-		printf("msgget() error in child %d: %s\n",
-			child_process, strerror(errno));
-		return FAIL;
-	}
-	tid = id;
-	sigrelse(SIGTERM);
+	int pid, i, count;
 
-	exit_status = PASS;
+	tid = SAFE_MSGGET(key, IPC_CREAT | S_IRUSR | S_IWUSR);
 
 	for (i = 0; i < nkids; i++) {
-		fflush(stdout);
-		if ((pid = FORK_OR_VFORK()) < 0) {
-			printf("Fork failure in the first child of child group %d\n",
+		pid = fork();
+		if (pid < 0) {
+			tst_res(TFAIL, "Fork failure in the first child of child group %d\n",
 				child_process);
 			cleanup_msgqueue(i, tid);
-			return FAIL;
+			return;
 		}
 		/* First child does this */
 		if (pid == 0) {
-			procstat = 2;
-			exit(doreader(key, tid, getpid(),
-					child_process, nreps));
+			do_reader(key, tid, getpid(), child_process, nreps);
+			exit(0);
 		}
 		rkidarray[i] = pid;
-		fflush(stdout);
-		if ((pid = FORK_OR_VFORK()) < 0) {
-			printf("Fork failure in the second child of child group %d\n",
-				child_process);
-			/*
-			 * Kill the reader child process
-			 */
-			(void)kill(rkidarray[i], SIGKILL);
 
+		pid = fork();
+		if (pid < 0) {
+			tst_res(TFAIL, "Fork failure in the second child of child group %d\n",
+				child_process);
 			cleanup_msgqueue(i, tid);
-			return FAIL;
+			return;
 		}
 		/* Second child does this */
 		if (pid == 0) {
-			procstat = 2;
-			exit(dowriter(key, tid, rkidarray[i],
-					child_process, nreps));
+			do_writer(key, tid, rkidarray[i], child_process, nreps);
+			exit(0);
 		}
 		wkidarray[i] = pid;
 	}
 	/* Parent does this */
 	count = 0;
 	while (1) {
-		if ((wait(&status)) > 0) {
-			if (status >> 8 != PASS) {
-				printf("Child exit status = %d from child group %d\n",
-					status >> 8, child_process);
-				for (i = 0; i < nkids; i++) {
-					kill(rkidarray[i], SIGTERM);
-					kill(wkidarray[i], SIGTERM);
-				}
-				if (msgctl(tid, IPC_RMID, 0) < 0) {
-					printf("msgctl() error: %s\n",
-						strerror(errno));
-				}
-				return FAIL;
-			}
+		if ((wait(NULL)) > 0) {
 			count++;
 		} else {
 			if (errno != EINTR) {
@@ -307,102 +181,71 @@ static int dotest(key_t key, int child_process)
 		}
 	}
 	/* Make sure proper number of children exited */
-	if (count != (nkids * 2)) {
-		printf("Wrong number of children exited in child group %d, saw %d, expected %d\n",
-			child_process, count, (nkids * 2));
-		if (msgctl(tid, IPC_RMID, 0) < 0) {
-			printf("msgctl() error: %s\n", strerror(errno));
-		}
-		return FAIL;
-	}
-	if (msgctl(id, IPC_RMID, 0) < 0) {
-		printf("msgctl() failure in child group %d: %s\n",
-			child_process, strerror(errno));
-		return FAIL;
-	}
-	return exit_status;
-}
+	if (count != (nkids * 2))
+		tst_res(TFAIL, "Wrong number of children exited in child group "
+			"%d, saw %d, expected %d\n", child_process, count,
+			(nkids * 2));
 
-static void term(int sig LTP_ATTRIBUTE_UNUSED)
-{
-	int i;
-
-	if (procstat == 0) {
-#ifdef DEBUG
-		tst_resm(TINFO, "SIGTERM signal received, test killing kids");
-#endif
-		for (i = 0; i < nprocs; i++) {
-			if (pidarray[i] > 0) {
-				if (kill(pidarray[i], SIGTERM) < 0) {
-					printf("Kill failed to kill child %d",
-						i);
-					exit(FAIL);
-				}
-			}
-		}
-		return;
-	}
-
-	if (procstat == 2) {
-		fflush(stdout);
-		exit(PASS);
-	}
-
-	if (tid == -1) {
-		exit(FAIL);
-	}
-	for (i = 0; i < nkids; i++) {
-		if (rkidarray[i] > 0)
-			kill(rkidarray[i], SIGTERM);
-		if (wkidarray[i] > 0)
-			kill(wkidarray[i], SIGTERM);
-	}
+	SAFE_MSGCTL(tid, IPC_RMID, NULL);
 }
 
-void setup(void)
+static void setup(void)
 {
 	int nr_msgqs;
 
-	tst_tmpdir();
-
-	tst_sig(FORK, DEF_HANDLER, cleanup);
-
-	TEST_PAUSE;
-
-	nr_msgqs = get_max_msgqueues();
-	if (nr_msgqs < 0)
-		cleanup();
-
-	nr_msgqs -= get_used_msgqueues();
-	if (nr_msgqs <= 0) {
-		tst_resm(TBROK,
-			 "Max number of message queues already used, cannot create more.");
-		cleanup();
-	}
+	tid = -1;
+	SAFE_FILE_SCANF("/proc/sys/kernel/msgmni", "%d", &nr_msgqs);
 
+	nr_msgqs -= GET_USED_QUEUES();
+	if (nr_msgqs <= 0)
+		tst_brk(TCONF, "Max number of message queues already used, "
+			"cannot create more.");
 	/*
 	 * Since msgmni scales to the memory size, it may reach huge values
 	 * that are not necessary for this test.
 	 * That's why we define NR_MSGQUEUES as a high boundary for it.
 	 */
 	MSGMNI = min(nr_msgqs, NR_MSGQUEUES);
-}
 
-void cleanup(void)
-{
-	int status;
+	if (opt_nreps) {
+		nreps = SAFE_STRTOL(opt_nreps, 1, INT_MAX);
+		nreps = min(nreps, MAXNREPS);
+	} else {
+		nreps = MAXNREPS;
+	}
 
-#ifdef DEBUG
-	tst_resm(TINFO, "Removing the message queue");
-#endif
-	fflush(stdout);
-	(void)msgctl(tid, IPC_RMID, NULL);
-	if ((status = msgctl(tid, IPC_STAT, NULL)) != -1) {
-		(void)msgctl(tid, IPC_RMID, NULL);
-		tst_resm(TFAIL, "msgctl(tid, IPC_RMID) failed");
+	if (opt_nkids) {
+		nkids = SAFE_STRTOL(opt_nkids, 1, INT_MAX);
+		nkids = min(nkids, MAXNKIDS);
+	} else {
+		nkids = MAXNKIDS;
+	}
 
+	if (opt_nprocs) {
+		nprocs = SAFE_STRTOL(opt_nprocs, 1, INT_MAX);
+		nprocs = min(nprocs, MAXNPROCS);
+		nprocs = min(nprocs, MSGMNI);
+	} else {
+		nprocs = MSGMNI;
 	}
 
-	fflush(stdout);
-	tst_rmdir();
+	SAFE_SIGNAL(SIGTERM, SIG_IGN);
+	tst_res(TINFO, "Number of message queues is %d, process is %d, "
+		"iterations is %d, read/write pairs is %d",
+		MSGMNI, nprocs, nreps, nkids);
+}
+
+static void cleanup(void)
+{
+	if (tid >= 0)
+		SAFE_MSGCTL(tid, IPC_RMID, NULL);
 }
+
+static struct tst_test test = {
+	.needs_tmpdir = 1,
+	.options = options,
+	.setup = setup,
+	.cleanup = cleanup,
+	.forks_child = 1,
+	.test_all = verify_msgstress,
+};
diff --git a/testcases/kernel/syscalls/ipc/msgstress/msgstress03.c b/testcases/kernel/syscalls/ipc/msgstress/msgstress03.c
index 294b401b1..6f6e01853 100644
--- a/testcases/kernel/syscalls/ipc/msgstress/msgstress03.c
+++ b/testcases/kernel/syscalls/ipc/msgstress/msgstress03.c
@@ -1,27 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /*
  * Copyright (c) International Business Machines  Corp., 2002
- *
- * This program is free software;  you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY;  without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
- * the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program;  if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Copyright (c) 2020 FUJITSU LIMITED. All rights reserved.
  *
  * 06/30/2001   Port to Linux   nsharoff@us.ibm.com
  * 11/06/2002   Port to LTP     dbarrera@us.ibm.com
- */
-
-/*
+ * 10/09/2020   Convert to new api xuyang2018.jy@cn.fujitsu.com
+ *
  * Get and manipulate a message queue.
- * Same as msgstress01 but gets the actual msgmni value under procfs.
+ * Same as msgstress01 but gets the actual msgmni value under procf.
  */
 
 #define _XOPEN_SOURCE 500
@@ -32,101 +19,61 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <unistd.h>
-#include <values.h>
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <sys/stat.h>
 #include <sys/ipc.h>
 #include <sys/msg.h>
-#include "test.h"
-#include "ipcmsg.h"
-#include "libmsgctl.h"
+#include "tst_test.h"
+#include "libnewipc.h"
+#include "tst_safe_sysv_ipc.h"
+#include "msgstress_common.h"
 
-char *TCID = "msgstress03";
-int TST_TOTAL = 1;
-
-#define MAXNPROCS	10000	/*These should be sufficient */
-#define MAXNREPS	10000	/*Else they srewup the system un-necessarily */
+#define MAXNPROCS       1000
+#define MAXNREPS	1000
 
 static key_t keyarray[MAXNPROCS];
-static int pidarray[MAXNPROCS];
 static int tid;
 static int MSGMNI, nprocs, nreps;
-static int procstat;
-static int mykid;
-
-void setup(void);
-void cleanup(void);
-
-static int dotest(key_t key, int child_process);
-static void sig_handler(int signo);
-
 static char *opt_nprocs;
 static char *opt_nreps;
+static void cleanup(void);
 
-static option_t options[] = {
-	{"n:", NULL, &opt_nprocs},
-	{"l:", NULL, &opt_nreps},
-	{NULL, NULL, NULL},
+static struct tst_option options[] = {
+	{"n:", &opt_nprocs, "-n N     Number of processes"},
+	{"l:", &opt_nreps, "-l N     Number of iterations"},
+	{NULL, NULL, NULL}
 };
 
-static void usage(void)
-{
-	printf("  -n      Number of processes\n");
-	printf("  -l      Number of iterations\n");
-}
-
-int main(int argc, char **argv)
+static void dotest(key_t key, int child_process)
 {
-	int i, j, ok, pid;
-	int count, status;
-	struct sigaction act;
-
-	tst_parse_opts(argc, argv, options, usage);
-
-	setup();
+	int pid;
 
-	nreps = MAXNREPS;
-	nprocs = MSGMNI;
+	tid = SAFE_MSGGET(key, IPC_CREAT | S_IRUSR | S_IWUSR);
 
-	if (opt_nreps) {
-		nreps = atoi(opt_nreps);
-		if (nreps > MAXNREPS) {
-			tst_resm(TINFO,
-				 "Requested number of iterations too large, "
-				 "setting to Max. of %d", MAXNREPS);
-			nreps = MAXNREPS;
-		}
+	pid = SAFE_FORK();
+	if (pid == 0) {
+		do_reader(key, tid, 1, child_process, nreps);
+		exit(0);
 	}
 
-	if (opt_nprocs) {
-		nprocs = atoi(opt_nprocs);
-		if (nprocs > MSGMNI) {
-			tst_resm(TINFO,
-				 "Requested number of processes too large, "
-				 "setting to Max. of %d", MSGMNI);
-			nprocs = MSGMNI;
-		}
-	}
+	do_writer(key, tid, 1, child_process, nreps);
+	SAFE_WAIT(NULL);
+	SAFE_MSGCTL(tid, IPC_RMID, NULL);
+}
+
+static void verify_msgstress(void)
+{
+	int i, j, ok, pid;
+	int count;
 
 	srand(getpid());
 	tid = -1;
 
-	/* Setup signal handling routine */
-	memset(&act, 0, sizeof(act));
-	act.sa_handler = sig_handler;
-	sigemptyset(&act.sa_mask);
-	sigaddset(&act.sa_mask, SIGTERM);
-	if (sigaction(SIGTERM, &act, NULL) < 0) {
-		tst_brkm(TFAIL, NULL, "Sigset SIGTERM failed");
-	}
-	/* Set up array of unique keys for use in allocating message
-	 * queues
-	 */
+	/* Set up array of unique keys for use in allocating message queues */
 	for (i = 0; i < nprocs; i++) {
 		ok = 1;
 		do {
-			/* Get random key */
 			keyarray[i] = (key_t) rand();
 			/* Make sure key is unique and not private */
 			if (keyarray[i] == IPC_PRIVATE) {
@@ -143,148 +90,80 @@ int main(int argc, char **argv)
 		} while (ok == 0);
 	}
 
-	/* Fork a number of processes, each of which will
+	/*
+	 * Fork a number of processes, each of which will
 	 * create a message queue with one reader/writer
 	 * pair which will read and write a number (iterations)
 	 * of random length messages with specific values.
 	 */
-
 	for (i = 0; i < nprocs; i++) {
-		fflush(stdout);
-		if ((pid = FORK_OR_VFORK()) < 0) {
-			tst_brkm(TFAIL,
-				 NULL,
-				 "\tFork failed (may be OK if under stress)");
-		}
-		/* Child does this */
+		pid = SAFE_FORK();
 		if (pid == 0) {
-			procstat = 1;
-			exit(dotest(keyarray[i], i));
+			dotest(keyarray[i], i);
+			exit(0);
 		}
-		pidarray[i] = pid;
 	}
 
 	count = 0;
 	while (1) {
-		if ((wait(&status)) > 0) {
-			if (status >> 8 != 0) {
-				tst_brkm(TFAIL, NULL,
-					 "Child exit status = %d",
-					 status >> 8);
-			}
+		if (wait(NULL) > 0) {
 			count++;
 		} else {
-			if (errno != EINTR) {
+			if (errno != EINTR)
 				break;
-			}
-#ifdef DEBUG
-			tst_resm(TINFO, "Signal detected during wait");
-#endif
 		}
 	}
-	/* Make sure proper number of children exited */
-	if (count != nprocs) {
-		tst_brkm(TFAIL,
-			 NULL,
-			 "Wrong number of children exited, Saw %d, Expected %d",
-			 count, nprocs);
-	}
-
-	tst_resm(TPASS, "Test ran successfully!");
+	if (count != nprocs)
+		tst_brk(TFAIL, "Wrong number of children exited, Saw %d, Expected %d",
+			count, nprocs);
 
+	tst_res(TPASS, "Test ran successfully!");
 	cleanup();
-	tst_exit();
-}
-
-static int dotest(key_t key, int child_process)
-{
-	int id, pid;
-	int ret, status;
-
-	sighold(SIGTERM);
-	TEST(msgget(key, IPC_CREAT | S_IRUSR | S_IWUSR));
-	if (TEST_RETURN < 0) {
-		printf("msgget() error in child %d: %s\n",
-			child_process, strerror(TEST_ERRNO));
-		return FAIL;
-	}
-	tid = id = TEST_RETURN;
-	sigrelse(SIGTERM);
-
-	fflush(stdout);
-	if ((pid = FORK_OR_VFORK()) < 0) {
-		printf("Fork failed (may be OK if under stress)\n");
-		TEST(msgctl(tid, IPC_RMID, 0));
-		if (TEST_RETURN < 0) {
-			printf("msgctl() error in cleanup: %s\n",
-				strerror(TEST_ERRNO));
-		}
-		return FAIL;
-	}
-	if (pid == 0)
-		exit(doreader(key, id, 1, child_process, nreps));
-
-	mykid = pid;
-	procstat = 2;
-	ret = dowriter(key, id, 1, child_process, nreps);
-	wait(&status);
-
-	if (ret != PASS)
-		exit(FAIL);
-
-	if ((!WIFEXITED(status) || (WEXITSTATUS(status) != PASS)))
-		exit(FAIL);
-
-	TEST(msgctl(id, IPC_RMID, 0));
-	if (TEST_RETURN < 0) {
-		printf("msgctl() failed: %s\n",
-			strerror(TEST_ERRNO));
-		return FAIL;
-	}
-	return PASS;
-}
-
-static void sig_handler(int signo LTP_ATTRIBUTE_UNUSED)
-{
 }
 
-void setup(void)
+static void setup(void)
 {
 	int nr_msgqs;
 
-	tst_tmpdir();
-
-	tst_sig(FORK, DEF_HANDLER, cleanup);
-
-	TEST_PAUSE;
-
-	nr_msgqs = get_max_msgqueues();
-	if (nr_msgqs < 0)
-		cleanup();
+	SAFE_FILE_SCANF("/proc/sys/kernel/msgmni", "%d", &nr_msgqs);
 
-	MSGMNI = nr_msgqs - get_used_msgqueues();
+	MSGMNI = nr_msgqs - GET_USED_QUEUES();
 	if (MSGMNI > MAXNPROCS)
 		MSGMNI = MAXNPROCS;
-	if (MSGMNI <= 0) {
-		tst_resm(TBROK,
-			 "Max number of message queues already used, cannot create more.");
-		cleanup();
+	if (MSGMNI <= 0)
+		tst_brk(TCONF, "Max number of message queues already used, "
+			"cannot create more.");
+
+	if (opt_nreps) {
+		nreps = SAFE_STRTOL(opt_nreps, 1, INT_MAX);
+		nreps = min(nreps, MAXNREPS);
+	} else {
+		nreps = MAXNREPS;
+	}
+
+	if (opt_nprocs) {
+		nprocs = SAFE_STRTOL(opt_nprocs, 1, INT_MAX);
+		nprocs = min(nprocs, MSGMNI);
+	} else {
+		nprocs = MSGMNI;
 	}
+
+	SAFE_SIGNAL(SIGTERM, SIG_IGN);
+	tst_res(TINFO, "Number of message queues is %d, process is %d, "
+		"iterations is %d", MSGMNI, nprocs, nreps);
 }
 
 void cleanup(void)
 {
-	int status;
-
-#ifdef DEBUG
-	tst_resm(TINFO, "Removing the message queue");
-#endif
-	(void)msgctl(tid, IPC_RMID, NULL);
-	if ((status = msgctl(tid, IPC_STAT, NULL)) != -1) {
-		(void)msgctl(tid, IPC_RMID, NULL);
-		tst_resm(TFAIL, "msgctl(tid, IPC_RMID) failed");
-
-	}
-
-	tst_rmdir();
+	if (tid >= 0)
+		SAFE_MSGCTL(tid, IPC_RMID, NULL);
 }
+
+static struct tst_test test = {
+	.needs_tmpdir = 1,
+	.options = options,
+	.setup = setup,
+	.cleanup = cleanup,
+	.forks_child = 1,
+	.test_all = verify_msgstress,
+};
diff --git a/testcases/kernel/syscalls/ipc/msgstress/msgstress04.c b/testcases/kernel/syscalls/ipc/msgstress/msgstress04.c
index f1c124990..98acde7e6 100644
--- a/testcases/kernel/syscalls/ipc/msgstress/msgstress04.c
+++ b/testcases/kernel/syscalls/ipc/msgstress/msgstress04.c
@@ -1,25 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /*
  * Copyright (c) International Business Machines  Corp., 2002
  *
- * This program is free software;  you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY;  without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
- * the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program;  if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
  * 06/30/2001   Port to Linux   nsharoff@us.ibm.com
  * 11/11/2002   Port to LTP     dbarrera@us.ibm.com
- */
-
-/*
+ * 10/21/2020   Convert to new api xuyang2018.jy@cn.fujitsu.com
  * Get and manipulate a message queue.
  * Same as msgstress02 but gets the actual msgmni value under procfs.
  */
@@ -36,23 +21,15 @@
 #include <string.h>
 #include <stdlib.h>
 #include <unistd.h>
-#include "test.h"
-#include "ipcmsg.h"
-#include "libmsgctl.h"
-
-char *TCID = "msgstress04";
-int TST_TOTAL = 1;
+#include "tst_test.h"
+#include "libnewipc.h"
+#include "tst_safe_sysv_ipc.h"
+#include "msgstress_common.h"
 
 #define MAXNREPS	1000
-#ifndef CONFIG_COLDFIRE
 #define MAXNPROCS	 1000000	/* This value is set to an arbitrary high limit. */
-#else
-#define MAXNPROCS	 100000	/* Coldfire can't deal with 1000000 */
-#endif
 #define MAXNKIDS	10
-#define DEFNKIDS	2
 
-static int maxnkids = MAXNKIDS;	/* Used if pid_max is exceeded */
 static key_t keyarray[MAXNPROCS];
 static int pidarray[MAXNPROCS];
 static int rkidarray[MAXNKIDS];
@@ -60,88 +37,45 @@ static int wkidarray[MAXNKIDS];
 static int tid;
 static int nprocs, nreps, nkids, MSGMNI;
 static int maxnprocs;
-static int procstat;
+static void cleanup(void);
 
-void setup(void);
-void cleanup(void);
-
-static void term(int);
-static int dotest(key_t, int);
+static void dotest(key_t, int);
 static void dotest_iteration(int off);
-static void cleanup_msgqueue(int i, int tid);
 
 static char *opt_maxnprocs;
 static char *opt_nkids;
 static char *opt_nreps;
 
-static option_t options[] = {
-	{"n:", NULL, &opt_maxnprocs},
-	{"c:", NULL, &opt_nkids},
-	{"l:", NULL, &opt_nreps},
-	{NULL, NULL, NULL},
+static struct tst_option options[] = {
+	{"n:", &opt_maxnprocs, "-n N     Number of processes"},
+	{"c:", &opt_nkids, "-c -N    Number of read/write child pairs"},
+	{"l:", &opt_nreps, "-l N     Number of iterations"},
+	{NULL, NULL, NULL}
 };
 
-static void usage(void)
+static void cleanup_msgqueue(int i, int tid)
 {
-	printf("  -n      Number of processes\n");
-	printf("  -c      Number of read/write child pairs\n");
-	printf("  -l      Number of iterations\n");
+	/*
+	 * Decrease the value of i by 1 because it is getting incremented
+	 * even if the fork is failing.
+	 */
+	i--;
+	/* Kill all children & free message queue. */
+	for (; i >= 0; i--) {
+		(void)kill(rkidarray[i], SIGKILL);
+		(void)kill(wkidarray[i], SIGKILL);
+	}
+	SAFE_MSGCTL(tid, IPC_RMID, 0);
 }
 
-
-int main(int argc, char **argv)
+static void verify_msgstress(void)
 {
 	int i, j, ok;
 
-	tst_parse_opts(argc, argv, options, usage);
-
-	setup();
-
-	nreps = MAXNREPS;
-	nkids = MAXNKIDS;
-
-	if (opt_nreps) {
-		nreps = atoi(opt_nreps);
-		if (nreps > MAXNREPS) {
-			tst_resm(TINFO,
-				 "Requested number of iterations too large, "
-				 "setting to Max. of %d", MAXNREPS);
-			nreps = MAXNREPS;
-		}
-	}
-
-	if (opt_nkids) {
-		nkids = atoi(opt_nkids);
-		if (nkids > MAXNKIDS) {
-			tst_resm(TINFO,
-				 "Requested number of read/write pairs too "
-				 "large, setting to Max. of %d", MAXNKIDS);
-			nkids = MAXNKIDS;
-		}
-	}
-
-
-	if (opt_maxnprocs) {
-		if (atoi(opt_maxnprocs) > maxnprocs) {
-			tst_resm(TINFO,
-				 "Requested number of processes too large, "
-				 "setting to Max. of %d", MSGMNI);
-		} else {
-			maxnprocs = atoi(opt_maxnprocs);
-		}
-	}
-
-	procstat = 0;
 	srand48((unsigned)getpid() + (unsigned)(getppid() << 16));
 	tid = -1;
 
-	/* Setup signal handling routine */
-	if (sigset(SIGTERM, term) == SIG_ERR)
-		tst_brkm(TFAIL, cleanup, "Sigset SIGTERM failed");
-
-	/* Set up array of unique keys for use in allocating message
-	 * queues
-	 */
+	/* Set up array of unique keys for use in allocating message queues */
 	for (i = 0; i < MSGMNI; i++) {
 		ok = 1;
 		do {
@@ -183,268 +117,162 @@ int main(int argc, char **argv)
 		dotest_iteration(i * maxnprocs);
 	}
 
-	tst_resm(TPASS, "Test ran successfully!");
+	tst_res(TPASS, "Test ran successfully!");
 
 	cleanup();
-	tst_exit();
 }
 
 static void dotest_iteration(int off)
 {
 	key_t key;
-	int i, count, status;
+	int i, count;
 	pid_t pid;
 
 	memset(pidarray, 0, sizeof(pidarray));
 
 	for (i = 0; i < nprocs; i++) {
 		key = keyarray[off + i];
-
-		if ((pid = FORK_OR_VFORK()) < 0)
-			tst_brkm(TFAIL, cleanup,
-				 "Fork failed (may be OK if under stress)");
+		pid = SAFE_FORK();
 
 		/* Child does this */
 		if (pid == 0) {
-			procstat = 1;
-			exit(dotest(key, i));
+			dotest(key, i);
+			exit(0);
 		}
 		pidarray[i] = pid;
 	}
 
 	count = 0;
 	while (1) {
-		if ((wait(&status)) > 0) {
-			if (status >> 8 != PASS)
-				tst_brkm(TFAIL, cleanup,
-					"Child exit status = %d", status >> 8);
+		if (wait(NULL) > 0) {
 			count++;
 		} else {
-			if (errno != EINTR) {
+			if (errno != EINTR)
 				break;
-			}
-#ifdef DEBUG
-			tst_resm(TINFO, "Signal detected during wait");
-#endif
 		}
 	}
 	/* Make sure proper number of children exited */
 	if (count != nprocs)
-		tst_brkm(TFAIL, cleanup,
-			 "Wrong number of children exited, Saw %d, Expected %d",
-			 count, nprocs);
+		tst_brk(TFAIL, "Wrong number of children exited, Saw %d, Expected %d",
+				count, nprocs);
 }
 
-static void cleanup_msgqueue(int i, int tid)
-{
-	/*
-	 * Decrease the value of i by 1 because it
-	 * is getting incremented even if the fork
-	 * is failing.
-	 */
-
-	i--;
-	/*
-	 * Kill all children & free message queue.
-	 */
-	for (; i >= 0; i--) {
-		(void)kill(rkidarray[i], SIGKILL);
-		(void)kill(wkidarray[i], SIGKILL);
-	}
-
-	if (msgctl(tid, IPC_RMID, 0) < 0) {
-		printf("Msgctl error in cleanup_msgqueue %d\n", errno);
-		exit(FAIL);
-	}
-}
 
-static int dotest(key_t key, int child_process)
+static void dotest(key_t key, int child_process)
 {
 	int id, pid;
-	int i, count, status, exit_status;
+	int i, count;
 
-	sighold(SIGTERM);
-	if ((id = msgget(key, IPC_CREAT | S_IRUSR | S_IWUSR)) < 0) {
-		printf("msgget() error in child %d: %s\n",
-			child_process, strerror(errno));
-		return FAIL;
-	}
+	id = SAFE_MSGGET(key, IPC_CREAT | S_IRUSR | S_IWUSR);
 	tid = id;
-	sigrelse(SIGTERM);
-
-	exit_status = PASS;
-
 	for (i = 0; i < nkids; i++) {
-		if ((pid = FORK_OR_VFORK()) < 0) {
-			printf("Fork failure in the first child of child group %d\n",
+		pid = fork();
+		if (pid < 0) {
+			tst_res(TFAIL, "Fork failure in the first child of child group %d\n",
 				child_process);
 			cleanup_msgqueue(i, tid);
-			return FAIL;
+			return;
 		}
 		/* First child does this */
 		if (pid == 0) {
-			procstat = 2;
-			exit(doreader(key, tid, getpid(),
-					child_process, nreps));
+			do_reader(key, tid, getpid(), child_process, nreps);
+			exit(0);
 		}
 		rkidarray[i] = pid;
-		if ((pid = FORK_OR_VFORK()) < 0) {
-			printf("Fork failure in the second child of child group %d\n",
+		pid = fork();
+		if (pid < 0) {
+			tst_res(TFAIL, "Fork failure in the first child of child group %d\n",
 				child_process);
-			/*
-			 * Kill the reader child process
-			 */
-			(void)kill(rkidarray[i], SIGKILL);
-
 			cleanup_msgqueue(i, tid);
-			return FAIL;
+			return;
 		}
 		/* Second child does this */
 		if (pid == 0) {
-			procstat = 2;
-			exit(dowriter(key, tid, rkidarray[i],
-					child_process, nreps));
+			do_writer(key, tid, rkidarray[i], child_process, nreps);
+			exit(0);
 		}
 		wkidarray[i] = pid;
 	}
 	/* Parent does this */
 	count = 0;
 	while (1) {
-		if ((wait(&status)) > 0) {
-			if (status >> 8 != PASS) {
-				printf("Child exit status = %d from child group %d\n",
-					status >> 8, child_process);
-				for (i = 0; i < nkids; i++) {
-					kill(rkidarray[i], SIGTERM);
-					kill(wkidarray[i], SIGTERM);
-				}
-				if (msgctl(tid, IPC_RMID, 0) < 0) {
-					printf("msgctl() error: %s\n",
-						strerror(errno));
-				}
-				return FAIL;
-			}
+		if (wait(NULL) > 0) {
 			count++;
 		} else {
-			if (errno != EINTR) {
+			if (errno != EINTR)
 				break;
-			}
 		}
 	}
 	/* Make sure proper number of children exited */
 	if (count != (nkids * 2)) {
-		printf("Wrong number of children exited in child group %d, saw %d, expected %d\n",
+		tst_res(TFAIL, "Wrong number of children exited in child group %d, saw %d, expected %d\n",
 			child_process, count, (nkids * 2));
-		if (msgctl(tid, IPC_RMID, 0) < 0) {
-			printf("msgctl() error: %s\n", strerror(errno));
-		}
-		return FAIL;
-	}
-	if (msgctl(id, IPC_RMID, 0) < 0) {
-		printf("msgctl() failure in child group %d: %s\n",
-			child_process, strerror(errno));
-		return FAIL;
 	}
-	return exit_status;
+	SAFE_MSGCTL(id, IPC_RMID, NULL);
 }
 
-/* ARGSUSED */
-static void term(int sig LTP_ATTRIBUTE_UNUSED)
-{
-	int i;
-
-	if (procstat == 0) {
-#ifdef DEBUG
-		tst_resm(TINFO, "SIGTERM signal received, test killing kids");
-#endif
-		for (i = 0; i < nprocs; i++) {
-			if (pidarray[i] > 0) {
-				if (kill(pidarray[i], SIGTERM) < 0) {
-					tst_resm(TBROK,
-						 "Kill failed to kill child %d",
-						 i);
-					exit(FAIL);
-				}
-			}
-		}
-		return;
-	}
-
-	if (procstat == 2) {
-		exit(PASS);
-	}
-
-	if (tid == -1) {
-		exit(FAIL);
-	}
-	for (i = 0; i < nkids; i++) {
-		if (rkidarray[i] > 0)
-			kill(rkidarray[i], SIGTERM);
-		if (wkidarray[i] > 0)
-			kill(wkidarray[i], SIGTERM);
-	}
-}
-
-void setup(void)
+static void setup(void)
 {
 	int nr_msgqs, free_pids;
 
-	tst_tmpdir();
-	/* You will want to enable some signal handling so you can capture
-	 * unexpected signals like SIGSEGV.
-	 */
-	tst_sig(FORK, DEF_HANDLER, cleanup);
-
-	/* One cavet that hasn't been fixed yet.  TEST_PAUSE contains the code to
-	 * fork the test with the -c option.  You want to make sure you do this
-	 * before you create your temporary directory.
-	 */
-	TEST_PAUSE;
-
-	nr_msgqs = get_max_msgqueues();
-	if (nr_msgqs < 0)
-		tst_brkm(TBROK, cleanup, "get_max_msgqueues() failed");
+	tid = -1;
+	SAFE_FILE_SCANF("/proc/sys/kernel/msgmni", "%d", &nr_msgqs);
 
-	MSGMNI = nr_msgqs - get_used_msgqueues();
+	MSGMNI = nr_msgqs - GET_USED_QUEUES();
 	if (MSGMNI <= 0)
-		tst_brkm(TBROK, cleanup,
-			 "Max number of message queues already used, cannot create more.");
+		tst_brk(TCONF, "Max number of message queues already used, "
+			"cannot create more.");
 
-	tst_resm(TINFO, "Found %d available message queues", MSGMNI);
+	tst_res(TINFO, "Found %d available message queues", MSGMNI);
 
-	free_pids = tst_get_free_pids(cleanup);
+	free_pids = tst_get_free_pids();
 	if (free_pids < 0) {
-		tst_brkm(TBROK, cleanup, "Can't obtain free_pid count");
+		tst_brk(TBROK, "Can't obtain free_pid count");
 	} else if (!free_pids) {
-		tst_brkm(TBROK, cleanup, "No free pids");
+		tst_brk(TBROK, "No free pids");
+	}
+
+	if (opt_nreps) {
+		nreps = SAFE_STRTOL(opt_nreps, 1, INT_MAX);
+		nreps = min(nreps, MAXNREPS);
+	} else {
+		nreps = MAXNREPS;
+	}
+
+	if (opt_nkids) {
+		nkids = SAFE_STRTOL(opt_nkids, 1, INT_MAX);
+		nkids = min(nkids, MAXNKIDS);
+	} else {
+		nkids = MAXNKIDS;
 	}
 
+
 	/* We don't use more than a half of available pids.
 	 * For each child we fork up to 2*maxnkids grandchildren. */
-	maxnprocs = (free_pids / 2) / (1 + 2 * maxnkids);
+	maxnprocs = (free_pids / 2) / (1 + 2 * nkids);
 
 	if (!maxnprocs)
-		tst_brkm(TBROK, cleanup, "Not enough free pids");
+		tst_brk(TBROK, "Not enough free pids");
 
-	tst_resm(TINFO, "Using upto %d pids", free_pids / 2);
+	if (opt_maxnprocs)
+		maxnprocs = SAFE_STRTOL(opt_maxnprocs, 1, INT_MAX);
+
+	SAFE_SIGNAL(SIGTERM, SIG_IGN);
+	tst_res(TINFO, "Using upto %d pids, %d processes %d read/write pairs, %d repeats",
+		free_pids/2, maxnprocs, nkids, nreps);
 }
 
-void cleanup(void)
+static void cleanup(void)
 {
-	int status;
-
-	/*
-	 * Remove the message queue from the system
-	 */
-#ifdef DEBUG
-	tst_resm(TINFO, "Removing the message queue");
-#endif
-	(void)msgctl(tid, IPC_RMID, NULL);
-	if ((status = msgctl(tid, IPC_STAT, NULL)) != -1) {
-		(void)msgctl(tid, IPC_RMID, NULL);
-		tst_resm(TFAIL, "msgctl(tid, IPC_RMID) failed");
-
-	}
-
-	tst_rmdir();
+	if (tid >= 0)
+		SAFE_MSGCTL(tid, IPC_RMID, NULL);
 }
+
+static struct tst_test test = {
+	.needs_tmpdir = 1,
+	.options = options,
+	.setup = setup,
+	.cleanup = cleanup,
+	.forks_child = 1,
+	.test_all = verify_msgstress,
+};
-- 
2.23.0




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

* [LTP] [PATCH v3 3/4] libmsgctl: Remove it
  2020-10-21 12:57     ` [LTP] [PATCH v3 1/4] syscalls/msgstress: Add common file for msgstress Yang Xu
  2020-10-21 12:57       ` [LTP] [PATCH v3 2/4] syscalls/msgstress*: cleanup and convert into new api Yang Xu
@ 2020-10-21 12:57       ` Yang Xu
  2020-10-21 12:57       ` [LTP] [PATCH v3 4/4] lipipc: Remove useless get_max_msgqueues api Yang Xu
  2020-11-11 15:44       ` [LTP] [PATCH v3 1/4] syscalls/msgstress: Add common file for msgstress Cyril Hrubis
  3 siblings, 0 replies; 26+ messages in thread
From: Yang Xu @ 2020-10-21 12:57 UTC (permalink / raw)
  To: ltp

This lib code was only used by msgstress case and we have created a msgstress_common.c code
in msgstress directory, so it was useless and remove it.

Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
---
 include/libmsgctl.h        |  39 ----------
 libs/libltpipc/libmsgctl.c | 147 -------------------------------------
 2 files changed, 186 deletions(-)
 delete mode 100644 include/libmsgctl.h
 delete mode 100644 libs/libltpipc/libmsgctl.c

diff --git a/include/libmsgctl.h b/include/libmsgctl.h
deleted file mode 100644
index e1afeab5f..000000000
--- a/include/libmsgctl.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) International Business Machines  Corp., 2002
- * Copyright (c) 2013 Oracle and/or its affiliates. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it would be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write the Free Software Foundation,
- * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#ifndef __LIBMSGCTL_H__
-#define __LIBMSGCTL_H__
-
-#define FAIL	1
-#define PASS	0
-
-struct mbuffer {
-	long type;
-	struct {
-		char len;
-		char pbytes[99];
-	} data;
-};
-
-int doreader(long key, int tid, long type, int child, int nreps);
-int dowriter(long key, int tid, long type, int child, int nreps);
-int fill_buffer(char *buf, char val, int size);
-int verify(char *buf, char val, int size, int child);
-
-#endif /*__LIBMSGCTL_H__ */
diff --git a/libs/libltpipc/libmsgctl.c b/libs/libltpipc/libmsgctl.c
deleted file mode 100644
index ae459d480..000000000
--- a/libs/libltpipc/libmsgctl.c
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright (c) International Business Machines  Corp., 2002
- * Copyright (c) 2013 Oracle and/or its affiliates. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it would be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write the Free Software Foundation,
- * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/ipc.h>
-#include <sys/msg.h>
-#include "libmsgctl.h"
-
-int doreader(long key, int tid, long type, int child, int nreps)
-{
-	int i, size;
-	int id;
-	struct mbuffer buffer;
-
-	id = msgget(key, 0);
-	if (id < 0) {
-		printf("msgget() error in the reader of child group %d: %s\n",
-			child, strerror(errno));
-
-		return FAIL;
-	}
-	if (id != tid) {
-		printf("Message queue mismatch in the reader of child group %d for message queue id %d\n",
-			child, id);
-
-		return FAIL;
-	}
-	for (i = 0; i < nreps; i++) {
-		memset(&buffer, 0, sizeof(buffer));
-
-		size = msgrcv(id, &buffer, 100, type, 0);
-		if (size < 0) {
-			printf("msgrcv() error in child %d, read # = %d: %s\n",
-				child, (i + 1), strerror(errno));
-
-			return FAIL;
-		}
-		if (buffer.type != type) {
-			printf("Type mismatch in child %d, read #d = %d: ",
-				child, (i + 1));
-			printf("for message got %ld, expected - %ld\n",
-				buffer.type, type);
-
-			return FAIL;
-		}
-		if (buffer.data.len + 1 != size) {
-			printf("Size mismatch in child %d, read # = %d: ",
-				child, (i + 1));
-			printf("for message got %d, expected - %d\n",
-				buffer.data.len + 1, size);
-
-			return FAIL;
-		}
-		if (verify(buffer.data.pbytes, (key % 255), size - 1, child)) {
-			printf("Verify failed in child %d read # = %d, key = %lx\n",
-				child, (i + 1), key);
-
-			return FAIL;
-		}
-		key++;
-	}
-	return PASS;
-}
-
-int dowriter(long key, int tid, long type, int child, int nreps)
-{
-	int i, size;
-	int id;
-	struct mbuffer buffer;
-
-	id = msgget(key, 0);
-	if (id < 0) {
-		printf("msgget() error in the writer of child group %d: %s\n",
-			child, strerror(errno));
-
-		return FAIL;
-	}
-	if (id != tid) {
-		printf("Message queue mismatch in the reader of child group %d for message queue id %d\n",
-			child, id);
-
-		return FAIL;
-	}
-
-	for (i = 0; i < nreps; i++) {
-		memset(&buffer, 0, sizeof(buffer));
-
-		do {
-			size = (lrand48() % 99);
-		} while (size == 0);
-		fill_buffer(buffer.data.pbytes, (key % 255), size);
-		buffer.data.len = size;
-		buffer.type = type;
-		if (msgsnd(id, &buffer, size + 1, 0) < 0) {
-			printf("msgsnd() error in child %d, write # = %d, key = %lx: %s\n",
-				child, nreps, key, strerror(errno));
-
-			return FAIL;
-		}
-		key++;
-	}
-	return PASS;
-}
-
-int fill_buffer(char *buf, char val, int size)
-{
-	int i;
-
-	for (i = 0; i < size; i++)
-		buf[i] = val;
-	return 0;
-}
-
-/* Check a buffer for correct values */
-int verify(char *buf, char val, int size, int child)
-{
-	while (size-- > 0) {
-		if (*buf++ != val) {
-			printf("Verify error in child %d, *buf = %x, val = %x, size = %d\n",
-				child, *buf, val, size);
-
-			return FAIL;
-		}
-	}
-	return PASS;
-}
-- 
2.23.0




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

* [LTP] [PATCH v3 4/4] lipipc: Remove useless get_max_msgqueues api
  2020-10-21 12:57     ` [LTP] [PATCH v3 1/4] syscalls/msgstress: Add common file for msgstress Yang Xu
  2020-10-21 12:57       ` [LTP] [PATCH v3 2/4] syscalls/msgstress*: cleanup and convert into new api Yang Xu
  2020-10-21 12:57       ` [LTP] [PATCH v3 3/4] libmsgctl: Remove it Yang Xu
@ 2020-10-21 12:57       ` Yang Xu
  2020-11-11 15:44       ` [LTP] [PATCH v3 1/4] syscalls/msgstress: Add common file for msgstress Cyril Hrubis
  3 siblings, 0 replies; 26+ messages in thread
From: Yang Xu @ 2020-10-21 12:57 UTC (permalink / raw)
  To: ltp

Only old msgstress cases use this api and we have used
SAFE_FILE_SCANF("/proc/sys/kernel/msgmni", "%d", &nr_msgqs) to get the max msgqueues.
So remove this uesless api.

Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
---
 include/ipcmsg.h        |  1 -
 libs/libltpipc/libipc.c | 23 -----------------------
 2 files changed, 24 deletions(-)

diff --git a/include/ipcmsg.h b/include/ipcmsg.h
index d89894b72..21eb81b6b 100644
--- a/include/ipcmsg.h
+++ b/include/ipcmsg.h
@@ -62,7 +62,6 @@ void rm_queue(int);
 key_t getipckey();
 int getuserid(char *);
 
-int get_max_msgqueues(void);
 int get_used_msgqueues(void);
 
 #endif /* ipcmsg.h */
diff --git a/libs/libltpipc/libipc.c b/libs/libltpipc/libipc.c
index d94880f54..9c2da11b0 100644
--- a/libs/libltpipc/libipc.c
+++ b/libs/libltpipc/libipc.c
@@ -195,26 +195,3 @@ int get_used_msgqueues(void)
 	}
 	return used_queues;
 }
-
-/*
- * Get the max number of message queues allowed on system
- */
-int get_max_msgqueues(void)
-{
-	FILE *f;
-	char buff[BUFSIZE];
-
-	/* Get the max number of message queues allowed on system */
-	f = fopen("/proc/sys/kernel/msgmni", "r");
-	if (!f) {
-		tst_resm(TBROK, "Could not open /proc/sys/kernel/msgmni");
-		return -1;
-	}
-	if (!fgets(buff, BUFSIZE, f)) {
-		fclose(f);
-		tst_resm(TBROK, "Could not read /proc/sys/kernel/msgmni");
-		return -1;
-	}
-	fclose(f);
-	return atoi(buff);
-}
-- 
2.23.0




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

* [LTP] [PATCH v3 1/4] syscalls/msgstress: Add common file for msgstress
  2020-10-21 12:57     ` [LTP] [PATCH v3 1/4] syscalls/msgstress: Add common file for msgstress Yang Xu
                         ` (2 preceding siblings ...)
  2020-10-21 12:57       ` [LTP] [PATCH v3 4/4] lipipc: Remove useless get_max_msgqueues api Yang Xu
@ 2020-11-11 15:44       ` Cyril Hrubis
  2020-11-13  6:14         ` Yang Xu
  3 siblings, 1 reply; 26+ messages in thread
From: Cyril Hrubis @ 2020-11-11 15:44 UTC (permalink / raw)
  To: ltp

Hi!
> Copy old libmsgctl.c three functions(doreader,dowriter, fill_buffer, verify)
> into this common file. The reason for not putting it into lib directory because
> only msgstress cases use these functions. So raising them into lib level makes
> no sense.

Well if we add msg to the function names there would be no harm in
putting these functions into the ipc library, right? E.g. we would have
msg_do_reader() etc.

I would actually prefer that, since we would have avoided complexity in
the msgstress/Makefile that way.

> Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
> ---
>  .../kernel/syscalls/ipc/msgstress/Makefile    |  2 +-
>  .../syscalls/ipc/msgstress/msgstress_common.c | 95 +++++++++++++++++++
>  .../syscalls/ipc/msgstress/msgstress_common.h | 26 +++++
>  3 files changed, 122 insertions(+), 1 deletion(-)
>  create mode 100644 testcases/kernel/syscalls/ipc/msgstress/msgstress_common.c
>  create mode 100644 testcases/kernel/syscalls/ipc/msgstress/msgstress_common.h
> 
> diff --git a/testcases/kernel/syscalls/ipc/msgstress/Makefile b/testcases/kernel/syscalls/ipc/msgstress/Makefile
> index b821bda01..2c8fa8e5b 100644
> --- a/testcases/kernel/syscalls/ipc/msgstress/Makefile
> +++ b/testcases/kernel/syscalls/ipc/msgstress/Makefile
> @@ -6,7 +6,7 @@ top_srcdir              ?= ../../../../..
>  LTPLIBS = ltpipc
>  
>  include $(top_srcdir)/include/mk/testcases.mk
> -
> +FILTER_OUT_MAKE_TARGETS         := msgstress_common
>  LTPLDLIBS  += -lltpipc
>  
>  include $(top_srcdir)/include/mk/generic_leaf_target.mk
> diff --git a/testcases/kernel/syscalls/ipc/msgstress/msgstress_common.c b/testcases/kernel/syscalls/ipc/msgstress/msgstress_common.c
> new file mode 100644
> index 000000000..3431355f6
> --- /dev/null
> +++ b/testcases/kernel/syscalls/ipc/msgstress/msgstress_common.c
> @@ -0,0 +1,95 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (c) International Business Machines  Corp., 2002
> + * Copyright (c) 2013 Oracle and/or its affiliates. All Rights Reserved.
> + * Copyright (c) 2020 FUJITSU LIMITED. All rights reserved???
> + */
> +
> +#define TST_NO_DEFAULT_MAIN
> +#include "msgstress_common.h"
> +
> +int verify(char *buf, char val, int size, int child)
> +{
> +	while (size-- > 0) {
> +		if (*buf++ != val) {
> +			tst_res(TFAIL, "Verify error in child %d, *buf = %x, "
> +				"val = %x, size = %d\n", child, *buf, val,
> +				size);
> +			return 1;
> +		}
> +	}
> +	return 0;
> +}
> +
> +void do_reader(long key, int tid, long type, int child, int nreps)
> +{
> +	int i, size;
> +	int id;
> +	struct mbuffer buffer;
> +
> +	id = SAFE_MSGGET(key, 0);
> +	if (id != tid) {
> +		tst_res(TFAIL,
> +			"Message queue mismatch in the reader of child group"
> +			" %d for message queue id %d\n", child, id);
> +		return;
> +	}
> +	for (i = 0; i < nreps; i++) {
> +		memset(&buffer, 0, sizeof(buffer));
> +
> +		size = SAFE_MSGRCV(id, &buffer, 100, type, 0);
> +		if (buffer.type != type) {
> +			tst_res(TFAIL, "Type mismatch in child %d, read #%d, "
> +				"for message got %ld, exected %ld",
> +				child, (i + 1), buffer.type, type);
> +			return;
> +		}
> +		if (buffer.data.len + 1 != size) {
> +			tst_res(TFAIL, "Size mismatch in child %d, read #%d, "
> +				"for message got %d, expected %d",
> +				child, (i + 1), buffer.data.len + 1, size);
> +			return;
> +		}
> +		if (verify(buffer.data.pbytes, (key % 255), size - 1, child)) {
> +			tst_res(TFAIL, "Verify failed in child %d read # = %d, "
> +				"key = %lx\n", child, (i + 1), key);
> +			return;
> +		}
> +		key++;
> +	}
> +}
> +
> +void fill_buffer(char *buf, char val, int size)
> +{
> +	int i;
> +
> +	for (i = 0; i < size; i++)
> +		buf[i] = val;
> +}

This is open-coded memset() please use memset() instead.

> +void do_writer(long key, int tid, long type, int child, int nreps)
> +{
> +	int i, size;
> +	int id;
> +	struct mbuffer buffer;
> +
> +	id = SAFE_MSGGET(key, 0);
> +	if (id != tid) {
> +		tst_res(TFAIL, "Message queue mismatch in the reader of child"
> +			" group %d for message queue id %d\n", child, id);
> +		return;
> +	}
> +
> +	for (i = 0; i < nreps; i++) {
> +		memset(&buffer, 0, sizeof(buffer));
> +
> +		do {
> +			size = (lrand48() % 99);
> +		} while (size == 0);
> +		fill_buffer(buffer.data.pbytes, (key % 255), size);
> +		buffer.data.len = size;
> +		buffer.type = type;
> +		SAFE_MSGSND(id, &buffer, size + 1, 0);
> +		key++;
> +	}
> +}
> diff --git a/testcases/kernel/syscalls/ipc/msgstress/msgstress_common.h b/testcases/kernel/syscalls/ipc/msgstress/msgstress_common.h
> new file mode 100644
> index 000000000..81e2f288b
> --- /dev/null
> +++ b/testcases/kernel/syscalls/ipc/msgstress/msgstress_common.h
> @@ -0,0 +1,26 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (c) 2020 FUJITSU LIMITED. All rights reserved.
> + * Author: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
> + */
> +
> +#ifndef MSGSTRESS_COMMON_H
> +#define MSGSTRESS_COMMON_H
> +
> +#include <stdlib.h>
> +#include "tst_safe_sysv_ipc.h"
> +#include "tst_test.h"
> +
> +struct mbuffer {
> +	long type;
> +	struct {
> +		char len;
> +		char pbytes[99];
> +	} data;
> +};
> +
> +void do_reader(long key, int tid, long type, int child, int nreps);
> +void do_writer(long key, int tid, long type, int child, int nreps);
> +
> +#endif
> +
> -- 
> 2.23.0
> 
> 
> 

-- 
Cyril Hrubis
chrubis@suse.cz

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

* [LTP] [PATCH v3 2/4] syscalls/msgstress*: cleanup and convert into new api
  2020-10-21 12:57       ` [LTP] [PATCH v3 2/4] syscalls/msgstress*: cleanup and convert into new api Yang Xu
@ 2020-11-11 16:31         ` Cyril Hrubis
  2021-03-12 12:02           ` [LTP] [PATCH v4 1/5] libs/libltpnewipc/libnewipc.c: Add msg_do_reader/msg_do_writer function Yang Xu
  0 siblings, 1 reply; 26+ messages in thread
From: Cyril Hrubis @ 2020-11-11 16:31 UTC (permalink / raw)
  To: ltp

Hi!
> @@ -31,105 +18,61 @@
>  #include <stdlib.h>
>  #include <stdio.h>
>  #include <unistd.h>
> -#include <values.h>
>  #include <sys/types.h>
>  #include <sys/wait.h>
>  #include <sys/stat.h>
>  #include <sys/ipc.h>
>  #include <sys/msg.h>
> -#include "test.h"
> -#include "ipcmsg.h"
> -#include "libmsgctl.h"
> +#include "tst_test.h"
> +#include "libnewipc.h"
> +#include "tst_safe_sysv_ipc.h"
> +#include "msgstress_common.h"
>  
> -char *TCID = "msgstress01";
> -int TST_TOTAL = 1;
> -
> -#ifndef CONFIG_COLDFIRE
> -#define MAXNPROCS	1000000	/* This value is set to an arbitrary high limit. */
> -#else
> -#define MAXNPROCS	 100000	/* Coldfire can't deal with 1000000 */
> -#endif
> +#define MAXNPROCS       1000000
>  #define MAXNREPS	100000
>  
>  static key_t keyarray[MAXNPROCS];
> -static int pidarray[MAXNPROCS];
>  static int tid;
>  static int MSGMNI, nprocs, nreps;
> -static int procstat;
> -static int mykid;
> -
> -void setup(void);
> -void cleanup(void);
> -
> -static int dotest(key_t key, int child_process);
> -static void sig_handler();
> -
>  static char *opt_nprocs;
>  static char *opt_nreps;
> +static void cleanup(void);
>  
> -static option_t options[] = {
> -	{"n:", NULL, &opt_nprocs},
> -	{"l:", NULL, &opt_nreps},
> -	{NULL, NULL, NULL},
> +static struct tst_option options[] = {
> +	{"n:", &opt_nprocs, "-n N     Number of processes"},
> +	{"l:", &opt_nreps, "-l N     Number of iterations"},
> +	{NULL, NULL, NULL}
>  };
>  
> -static void usage(void)
> -{
> -	printf("  -n      Number of processes\n");
> -	printf("  -l      Number of iterations\n");
> -}
> -
> -int main(int argc, char **argv)
> +static void dotest(key_t key, int child_process)
>  {
> -	int i, j, ok, pid;
> -	int count, status;
> -	struct sigaction act;
> -
> -	tst_parse_opts(argc, argv, options, usage);
> -
> -	setup();
> +	int pid;
>  
> -	nreps = MAXNREPS;
> -	nprocs = MSGMNI;
> +	tid = SAFE_MSGGET(key, IPC_CREAT | S_IRUSR | S_IWUSR);
>  
> -	if (opt_nreps) {
> -		nreps = atoi(opt_nreps);
> -		if (nreps > MAXNREPS) {
> -			tst_resm(TINFO,
> -				 "Requested number of iterations too large, "
> -				 "setting to Max. of %d", MAXNREPS);
> -			nreps = MAXNREPS;
> -		}
> +	pid = SAFE_FORK();
> +	if (pid == 0) {
> +		do_reader(key, tid, 1, child_process, nreps);
> +		exit(0);
>  	}
>  
> -	if (opt_nprocs) {
> -		nprocs = atoi(opt_nprocs);
> -		if (nprocs > MSGMNI) {
> -			tst_resm(TINFO,
> -				 "Requested number of processes too large, "
> -				 "setting to Max. of %d", MSGMNI);
> -			nprocs = MSGMNI;
> -		}
> -	}
> +	do_writer(key, tid, 1, child_process, nreps);
> +	SAFE_WAIT(NULL);
> +	SAFE_MSGCTL(tid, IPC_RMID, NULL);
> +}
> +
> +static void verify_msgstress(void)
> +{
> +	int i, j, ok, pid;
> +	int count;
>  
>  	srand(getpid());
>  	tid = -1;
>  
> -	/* Setup signal handling routine */
> -	memset(&act, 0, sizeof(act));
> -	act.sa_handler = sig_handler;
> -	sigemptyset(&act.sa_mask);
> -	sigaddset(&act.sa_mask, SIGTERM);
> -	if (sigaction(SIGTERM, &act, NULL) < 0) {
> -		tst_brkm(TFAIL, NULL, "Sigset SIGTERM failed");
> -	}
> -	/* Set up array of unique keys for use in allocating message
> -	 * queues
> -	 */
> +	/* Set up array of unique keys for use in allocating message queues */
>  	for (i = 0; i < nprocs; i++) {

>  		ok = 1;
>  		do {
> -			/* Get random key */
>  			keyarray[i] = (key_t) rand();
>  			/* Make sure key is unique and not private */
>  			if (keyarray[i] == IPC_PRIVATE) {
> @@ -146,156 +89,83 @@ int main(int argc, char **argv)
>  		} while (ok == 0);
>  	}

The functions that setups the keys should go to the library as well.

> -	/* Fork a number of processes, each of which will
> +	/*
> +	 * Fork a number of processes, each of which will
>  	 * create a message queue with one reader/writer
>  	 * pair which will read and write a number (iterations)
>  	 * of random length messages with specific values.
>  	 */
> -
>  	for (i = 0; i < nprocs; i++) {
> -		fflush(stdout);
> -		if ((pid = FORK_OR_VFORK()) < 0) {
> -			tst_brkm(TFAIL,
> -				 NULL,
> -				 "\tFork failed (may be OK if under stress)");
> -		}
> -		/* Child does this */
> +		pid = SAFE_FORK();
>  		if (pid == 0) {
> -			procstat = 1;
> -			exit(dotest(keyarray[i], i));
> +			dotest(keyarray[i], i);
> +			exit(0);
>  		}
> -		pidarray[i] = pid;
>  	}
>  
>  	count = 0;
> +
>  	while (1) {
> -		if ((wait(&status)) > 0) {
> -			if (status >> 8 != 0) {
> -				tst_brkm(TFAIL, NULL,
> -					 "Child exit status = %d",
> -					 status >> 8);
> -			}
> +		if (wait(NULL) > 0) {
>  			count++;
>  		} else {
> -			if (errno != EINTR) {
> +			if (errno != EINTR)
>  				break;
> -			}
> -#ifdef DEBUG
> -			tst_resm(TINFO, "Signal detected during wait");
> -#endif
>  		}
>  	}
> -	/* Make sure proper number of children exited */
> -	if (count != nprocs) {
> -		tst_brkm(TFAIL,
> -			 NULL,
> -			 "Wrong number of children exited, Saw %d, Expected %d",
> -			 count, nprocs);
> -	}
>  
> -	tst_resm(TPASS, "Test ran successfully!");
> +	if (count != nprocs)
> +		tst_brk(TFAIL, "Wrong number of children exited, Saw %d, Expected %d",
> +			count, nprocs);
>  
> +	tst_res(TPASS, "Test ran successfully!");
>  	cleanup();

The cleanup will be called by the library, you must not call it here
yourself.

> -	tst_exit();
> -}
> -
> -static int dotest(key_t key, int child_process)
> -{
> -	int id, pid;
> -	int ret, status;
> -
> -	sighold(SIGTERM);
> -	TEST(msgget(key, IPC_CREAT | S_IRUSR | S_IWUSR));
> -	if (TEST_RETURN < 0) {
> -		printf("msgget() error in child %d: %s\n",
> -			child_process, strerror(TEST_ERRNO));
> -
> -		return FAIL;
> -	}
> -	tid = id = TEST_RETURN;
> -	sigrelse(SIGTERM);
> -
> -	fflush(stdout);
> -	if ((pid = FORK_OR_VFORK()) < 0) {
> -		printf("\tFork failed (may be OK if under stress)\n");
> -		TEST(msgctl(tid, IPC_RMID, 0));
> -		if (TEST_RETURN < 0) {
> -			printf("mscgtl() error in cleanup: %s\n",
> -				strerror(TEST_ERRNO));
> -		}
> -		return FAIL;
> -	}
> -	/* Child does this */
> -	if (pid == 0)
> -		exit(doreader(key, id, 1, child_process, nreps));
> -	/* Parent does this */
> -	mykid = pid;
> -	procstat = 2;
> -	ret = dowriter(key, id, 1, child_process, nreps);
> -	wait(&status);
> -
> -	if (ret != PASS)
> -		exit(FAIL);
> -
> -	if ((!WIFEXITED(status) || (WEXITSTATUS(status) != PASS)))
> -		exit(FAIL);
> -
> -	TEST(msgctl(id, IPC_RMID, 0));
> -	if (TEST_RETURN < 0) {
> -		printf("msgctl() errno %d: %s\n",
> -			TEST_ERRNO, strerror(TEST_ERRNO));
> -
> -		return FAIL;
> -	}
> -	return PASS;
>  }
>  
> -static void sig_handler(void)
> -{
> -}
> -
> -void setup(void)
> +static void setup(void)
>  {
>  	int nr_msgqs;
>  
> -	tst_tmpdir();
> +	SAFE_FILE_SCANF("/proc/sys/kernel/msgmni", "%d", &nr_msgqs);
>  
> -	tst_sig(FORK, DEF_HANDLER, cleanup);
> +	nr_msgqs -= GET_USED_QUEUES();
> +	if (nr_msgqs <= 0)
> +		tst_brk(TCONF, "Max number of message queues already used, "
> +			"cannot create more.");

LKML coding style prefers not to break strings even if they are over 80
chars.

> -	TEST_PAUSE;
> +	MSGMNI = min(nr_msgqs, NR_MSGQUEUES);

> -	nr_msgqs = get_max_msgqueues();
> -	if (nr_msgqs < 0)
> -		cleanup();
> +	if (opt_nreps) {
> +		nreps = SAFE_STRTOL(opt_nreps, 1, INT_MAX);
> +		nreps = min(nreps, MAXNREPS);
> +	} else {
> +		nreps = MAXNREPS;
> +	}
> -	nr_msgqs -= get_used_msgqueues();
> -	if (nr_msgqs <= 0) {
> -		tst_resm(TBROK,
> -			 "Max number of message queues already used, cannot create more.");
> -		cleanup();
> +	if (opt_nprocs) {
> +		nprocs = SAFE_STRTOL(opt_nprocs, 1, INT_MAX);
> +		nprocs = min(nprocs, MAXNPROCS);
> +		nprocs = min(nprocs, MSGMNI);
> +	} else {
> +		nprocs = MSGMNI;
>  	}

This looks completely wrong in this test we basically fork nproc
processes and each of them runs one message queue. There is no point in
setting anything else than nprocs and the nprocs is limited by the
number of possible message queues.

So all this setup should be something as:


static int nprocs = MAXNPROCS;
static int nreps = MAXNREPS;

...

	unsigned int avail_msg_queues = get_avail_msgqueues();

	if (opt_nprocs)
		nprocs = SAFE_STRTOL(opt_nprocs, 1, MAXNPROCS);

	if (nprocs > avail_msg_queues) {
		tst_res(TINFO, "Setting max processes to %u", avail_msg_queues);
		nprocs = avail_msg_queues;
	}

	if (opt_nreps)
		nreps = SAFE_STRTOL(opt_nreps, 1, MAXNREPS);

Where the get_avail_msgqueues() is a library function that returns the
max_queues - used_queues.


> -	/*
> -	 * Since msgmni scales to the memory size, it may reach huge values
> -	 * that are not necessary for this test.
> -	 * That's why we define NR_MSGQUEUES as a high boundary for it.
> -	 */
> -	MSGMNI = min(nr_msgqs, NR_MSGQUEUES);
> +	SAFE_SIGNAL(SIGTERM, SIG_IGN);
> +	tst_res(TINFO, "Number of message queues is %d, process is %d, "
> +		"iterations is %d", MSGMNI, nprocs, nreps);

The LKML coding style prefers not to break strings even if they are
longer than 80 chars.

>  }
>  
>  void cleanup(void)
>  {
> -	int status;
> -
> -#ifdef DEBUG
> -	tst_resm(TINFO, "Removing the message queue");
> -#endif
> -	(void)msgctl(tid, IPC_RMID, NULL);
> -	if ((status = msgctl(tid, IPC_STAT, NULL)) != -1) {
> -		(void)msgctl(tid, IPC_RMID, NULL);
> -		tst_resm(TFAIL, "msgctl(tid, IPC_RMID) failed");
> -
> -	}
> -
> -	tst_rmdir();
> +	if (tid >= 0)
> +		SAFE_MSGCTL(tid, IPC_RMID, NULL);
>  }
> +
> +static struct tst_test test = {
> +	.needs_tmpdir = 1,
> +	.options = options,
> +	.setup = setup,
> +	.cleanup = cleanup,
> +	.forks_child = 1,
> +	.test_all = verify_msgstress,
> +};

And I've run out of time for today, but I think that similar comments
would apply for the rest of the testcases as well.

It would also be easier if there was one patch per testcase, that would
make it easier to review as well.

-- 
Cyril Hrubis
chrubis@suse.cz

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

* [LTP] [PATCH v3 1/4] syscalls/msgstress: Add common file for msgstress
  2020-11-11 15:44       ` [LTP] [PATCH v3 1/4] syscalls/msgstress: Add common file for msgstress Cyril Hrubis
@ 2020-11-13  6:14         ` Yang Xu
  2020-11-13 15:26           ` Cyril Hrubis
  0 siblings, 1 reply; 26+ messages in thread
From: Yang Xu @ 2020-11-13  6:14 UTC (permalink / raw)
  To: ltp

Hi Cyril
> Hi!
>> Copy old libmsgctl.c three functions(doreader,dowriter, fill_buffer, verify)
>> into this common file. The reason for not putting it into lib directory because
>> only msgstress cases use these functions. So raising them into lib level makes
>> no sense.
>
> Well if we add msg to the function names there would be no harm in
> putting these functions into the ipc library, right? E.g. we would have
> msg_do_reader() etc.

Yes. it is no harm. But I don't see any other case using these api.

Also this patch looks has wrongly merged into ltp master.

>
> I would actually prefer that, since we would have avoided complexity in
> the msgstress/Makefile that way.
>
>> Signed-off-by: Yang Xu<xuyang2018.jy@cn.fujitsu.com>
>> ---
>>   .../kernel/syscalls/ipc/msgstress/Makefile    |  2 +-
>>   .../syscalls/ipc/msgstress/msgstress_common.c | 95 +++++++++++++++++++
>>   .../syscalls/ipc/msgstress/msgstress_common.h | 26 +++++
>>   3 files changed, 122 insertions(+), 1 deletion(-)
>>   create mode 100644 testcases/kernel/syscalls/ipc/msgstress/msgstress_common.c
>>   create mode 100644 testcases/kernel/syscalls/ipc/msgstress/msgstress_common.h
>>
>> diff --git a/testcases/kernel/syscalls/ipc/msgstress/Makefile b/testcases/kernel/syscalls/ipc/msgstress/Makefile
>> index b821bda01..2c8fa8e5b 100644
>> --- a/testcases/kernel/syscalls/ipc/msgstress/Makefile
>> +++ b/testcases/kernel/syscalls/ipc/msgstress/Makefile
>> @@ -6,7 +6,7 @@ top_srcdir              ?= ../../../../..
>>   LTPLIBS = ltpipc
>>
>>   include $(top_srcdir)/include/mk/testcases.mk
>> -
>> +FILTER_OUT_MAKE_TARGETS         := msgstress_common
>>   LTPLDLIBS  += -lltpipc
>>
>>   include $(top_srcdir)/include/mk/generic_leaf_target.mk
>> diff --git a/testcases/kernel/syscalls/ipc/msgstress/msgstress_common.c b/testcases/kernel/syscalls/ipc/msgstress/msgstress_common.c
>> new file mode 100644
>> index 000000000..3431355f6
>> --- /dev/null
>> +++ b/testcases/kernel/syscalls/ipc/msgstress/msgstress_common.c
>> @@ -0,0 +1,95 @@
>> +// SPDX-License-Identifier: GPL-2.0-or-later
>> +/*
>> + * Copyright (c) International Business Machines  Corp., 2002
>> + * Copyright (c) 2013 Oracle and/or its affiliates. All Rights Reserved.
>> + * Copyright (c) 2020 FUJITSU LIMITED. All rights reserved???
>> + */
>> +
>> +#define TST_NO_DEFAULT_MAIN
>> +#include "msgstress_common.h"
>> +
>> +int verify(char *buf, char val, int size, int child)
>> +{
>> +	while (size-->  0) {
>> +		if (*buf++ != val) {
>> +			tst_res(TFAIL, "Verify error in child %d, *buf = %x, "
>> +				"val = %x, size = %d\n", child, *buf, val,
>> +				size);
>> +			return 1;
>> +		}
>> +	}
>> +	return 0;
>> +}
>> +
>> +void do_reader(long key, int tid, long type, int child, int nreps)
>> +{
>> +	int i, size;
>> +	int id;
>> +	struct mbuffer buffer;
>> +
>> +	id = SAFE_MSGGET(key, 0);
>> +	if (id != tid) {
>> +		tst_res(TFAIL,
>> +			"Message queue mismatch in the reader of child group"
>> +			" %d for message queue id %d\n", child, id);
>> +		return;
>> +	}
>> +	for (i = 0; i<  nreps; i++) {
>> +		memset(&buffer, 0, sizeof(buffer));
>> +
>> +		size = SAFE_MSGRCV(id,&buffer, 100, type, 0);
>> +		if (buffer.type != type) {
>> +			tst_res(TFAIL, "Type mismatch in child %d, read #%d, "
>> +				"for message got %ld, exected %ld",
>> +				child, (i + 1), buffer.type, type);
>> +			return;
>> +		}
>> +		if (buffer.data.len + 1 != size) {
>> +			tst_res(TFAIL, "Size mismatch in child %d, read #%d, "
>> +				"for message got %d, expected %d",
>> +				child, (i + 1), buffer.data.len + 1, size);
>> +			return;
>> +		}
>> +		if (verify(buffer.data.pbytes, (key % 255), size - 1, child)) {
>> +			tst_res(TFAIL, "Verify failed in child %d read # = %d, "
>> +				"key = %lx\n", child, (i + 1), key);
>> +			return;
>> +		}
>> +		key++;
>> +	}
>> +}
>> +
>> +void fill_buffer(char *buf, char val, int size)
>> +{
>> +	int i;
>> +
>> +	for (i = 0; i<  size; i++)
>> +		buf[i] = val;
>> +}
>
> This is open-coded memset() please use memset() instead.
OK
>
>> +void do_writer(long key, int tid, long type, int child, int nreps)
>> +{
>> +	int i, size;
>> +	int id;
>> +	struct mbuffer buffer;
>> +
>> +	id = SAFE_MSGGET(key, 0);
>> +	if (id != tid) {
>> +		tst_res(TFAIL, "Message queue mismatch in the reader of child"
>> +			" group %d for message queue id %d\n", child, id);
>> +		return;
>> +	}
>> +
>> +	for (i = 0; i<  nreps; i++) {
>> +		memset(&buffer, 0, sizeof(buffer));
>> +
>> +		do {
>> +			size = (lrand48() % 99);
>> +		} while (size == 0);
>> +		fill_buffer(buffer.data.pbytes, (key % 255), size);
>> +		buffer.data.len = size;
>> +		buffer.type = type;
>> +		SAFE_MSGSND(id,&buffer, size + 1, 0);
>> +		key++;
>> +	}
>> +}
>> diff --git a/testcases/kernel/syscalls/ipc/msgstress/msgstress_common.h b/testcases/kernel/syscalls/ipc/msgstress/msgstress_common.h
>> new file mode 100644
>> index 000000000..81e2f288b
>> --- /dev/null
>> +++ b/testcases/kernel/syscalls/ipc/msgstress/msgstress_common.h
>> @@ -0,0 +1,26 @@
>> +// SPDX-License-Identifier: GPL-2.0-or-later
>> +/*
>> + * Copyright (c) 2020 FUJITSU LIMITED. All rights reserved.
>> + * Author: Yang Xu<xuyang2018.jy@cn.fujitsu.com>
>> + */
>> +
>> +#ifndef MSGSTRESS_COMMON_H
>> +#define MSGSTRESS_COMMON_H
>> +
>> +#include<stdlib.h>
>> +#include "tst_safe_sysv_ipc.h"
>> +#include "tst_test.h"
>> +
>> +struct mbuffer {
>> +	long type;
>> +	struct {
>> +		char len;
>> +		char pbytes[99];
>> +	} data;
>> +};
>> +
>> +void do_reader(long key, int tid, long type, int child, int nreps);
>> +void do_writer(long key, int tid, long type, int child, int nreps);
>> +
>> +#endif
>> +
>> --
>> 2.23.0
>>
>>
>>
>




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

* [LTP] [PATCH v3 1/4] syscalls/msgstress: Add common file for msgstress
  2020-11-13  6:14         ` Yang Xu
@ 2020-11-13 15:26           ` Cyril Hrubis
  0 siblings, 0 replies; 26+ messages in thread
From: Cyril Hrubis @ 2020-11-13 15:26 UTC (permalink / raw)
  To: ltp

Hi!
> > Well if we add msg to the function names there would be no harm in
> > putting these functions into the ipc library, right? E.g. we would have
> > msg_do_reader() etc.
> 
> Yes. it is no harm. But I don't see any other case using these api.

Well it makes it easier to maintain the build system since we do not end
up with hacks in random Makefiles.

> Also this patch looks has wrongly merged into ltp master.

Sorry I must have pushed that by accident yesterday, I've reverted it
now.

-- 
Cyril Hrubis
chrubis@suse.cz

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

* [LTP] [PATCH v4 1/5] libs/libltpnewipc/libnewipc.c: Add msg_do_reader/msg_do_writer function
  2020-11-11 16:31         ` Cyril Hrubis
@ 2021-03-12 12:02           ` Yang Xu
  2021-03-12 12:02             ` [LTP] [PATCH v4 2/5] syscalls/msgstress01: Convert into new api and merge msgstress03 into it Yang Xu
                               ` (5 more replies)
  0 siblings, 6 replies; 26+ messages in thread
From: Yang Xu @ 2021-03-12 12:02 UTC (permalink / raw)
  To: ltp

Copy old libmsgctl.c three functions(doreader,dowriter,verify) into libnewipc.c.
It is prepared for upcoming new api msgstress case. The reason for not using a new
c lib file(ie libnewmsgctl.c) is that current libnewipc is small(only has getipckey,
get_used_queues, probe_free_addr, get_ipc_timestamp function). So put them into libnewipc.c.
Also use tst_brk for failure because we don't want to print many info in stress test when
case fails.

Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
---
 include/libnewipc.h           | 11 +++++
 libs/libltpnewipc/libnewipc.c | 75 +++++++++++++++++++++++++++++++++++
 2 files changed, 86 insertions(+)

diff --git a/include/libnewipc.h b/include/libnewipc.h
index 075364f85..0f099c939 100644
--- a/include/libnewipc.h
+++ b/include/libnewipc.h
@@ -45,6 +45,14 @@
 #define INT_SIZE	4
 #define MODE_MASK	0x01FF
 
+struct mbuffer {
+	long type;
+	struct {
+		char len;
+		char pbytes[99];
+	} data;
+};
+
 key_t getipckey(const char *file, const int lineno);
 #define GETIPCKEY() \
 	getipckey(__FILE__, __LINE__)
@@ -59,4 +67,7 @@ void *probe_free_addr(const char *file, const int lineno);
 
 time_t get_ipc_timestamp(void);
 
+void msg_do_reader(long key, int tid, long type, int child, int nreps);
+
+void msg_do_writer(long key, int tid, long type, int child, int nreps);
 #endif /* newlibipc.h */
diff --git a/libs/libltpnewipc/libnewipc.c b/libs/libltpnewipc/libnewipc.c
index d0974bbe0..09871b421 100644
--- a/libs/libltpnewipc/libnewipc.c
+++ b/libs/libltpnewipc/libnewipc.c
@@ -99,3 +99,78 @@ time_t get_ipc_timestamp(void)
 
 	return ts.tv_sec;
 }
+
+static int verify(char *buf, char val, int size, int child)
+{
+	while (size-- > 0) {
+		if (*buf++ != val) {
+			tst_res(TFAIL,
+				"Verify error in child %d, *buf = %x, val = %x, size = %d",
+				child, *buf, val, size);
+			return 1;
+		}
+	}
+	return 0;
+}
+
+void msg_do_reader(long key, int tid, long type, int child, int nreps)
+{
+	int i, size;
+	int id;
+	struct mbuffer buffer;
+
+	id = SAFE_MSGGET(key, 0);
+	if (id != tid) {
+		tst_brk(TFAIL,
+			"Message queue mismatch in the reader of child group %d for message queue id %d ",
+			child, id);
+	}
+	for (i = 0; i < nreps; i++) {
+		memset(&buffer, 0, sizeof(buffer));
+
+		size = SAFE_MSGRCV(id, &buffer, 100, type, 0);
+		if (buffer.type != type) {
+			tst_brk(TFAIL,
+				"Type mismatch in child %d, read #%d, for message got %ld, exected %ld",
+				child, (i + 1), buffer.type, type);
+		}
+		if (buffer.data.len + 1 != size) {
+			tst_brk(TFAIL,
+				"Size mismatch in child %d, read #%d, for message got %d, expected %d",
+				child, (i + 1), buffer.data.len + 1, size);
+		}
+		if (verify(buffer.data.pbytes, (key % 255), size - 1, child)) {
+			tst_brk(TFAIL,
+				"Verify failed in child %d read # = %d, key = %lx",
+				child, (i + 1), key);
+		}
+		key++;
+	}
+}
+
+void msg_do_writer(long key, int tid, long type, int child, int nreps)
+{
+	int i, size;
+	int id;
+	struct mbuffer buffer;
+
+	id = SAFE_MSGGET(key, 0);
+	if (id != tid) {
+		tst_brk(TFAIL,
+			"Message queue mismatch in the writer of child group %d for message queue id %d",
+			child, id);
+	}
+
+	for (i = 0; i < nreps; i++) {
+		memset(&buffer, 0, sizeof(buffer));
+
+		do {
+			size = (lrand48() % 99);
+		} while (size == 0);
+		memset(buffer.data.pbytes, (key % 255), size);
+		buffer.data.len = size;
+		buffer.type = type;
+		SAFE_MSGSND(id, &buffer, size + 1, 0);
+		key++;
+	}
+}
-- 
2.23.0




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

* [LTP] [PATCH v4 2/5] syscalls/msgstress01: Convert into new api and merge msgstress03 into it
  2021-03-12 12:02           ` [LTP] [PATCH v4 1/5] libs/libltpnewipc/libnewipc.c: Add msg_do_reader/msg_do_writer function Yang Xu
@ 2021-03-12 12:02             ` Yang Xu
  2021-07-21 15:07               ` Cyril Hrubis
  2021-03-12 12:02             ` [LTP] [PATCH v4 3/5] syscalls/msgstress02: Convert into new api Yang Xu
                               ` (4 subsequent siblings)
  5 siblings, 1 reply; 26+ messages in thread
From: Yang Xu @ 2021-03-12 12:02 UTC (permalink / raw)
  To: ltp

Since msgstress01 and msgstress03 has the small difference(whether use procfs value,
msgstress01 uses 16 procs 100000 reps as default and msgstress03 uses 10000 procs
10000 reps as default).

We can merge the two cases directly by using proper process and rep value in runtest.
In here, I use 1000/100000 value as default in msgstress01 tag instead of original
16/10000 value because 16 procs is so small and 1000 procs make more sense(It also
 not exceed the maximum process limit). After this change, excuting msgstress01 doesn't
take a lot of time than before. msgstress03 tag uses "msgstress01 -n 10000 -l 10000" to
replace.

We will use the bigger process num when we add process num check according into
available memory in the future. Of course, we can add it into smoke-test at that time
since it may take a lot of time.

Some changes since old api:
1) cleanup is useless since tid value is always -1 because we assign value in child but
use it in parent. Use a tid array instead and put the position of getting msgget id into
parent process.

2)Ignore SIGTERM instead of empty signhanlder and sighold/sigrelease

3)Add get_avail_queues and setup_msg_key_array in new ipc library

4)Add timeout=-1 since it maybe a smoke test when using bigger proc num or reps num

Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
---
 include/libnewipc.h                           |  11 +
 libs/libltpnewipc/libnewipc.c                 |  39 +++
 runtest/syscalls                              |   2 +-
 runtest/syscalls-ipc                          |   2 +-
 .../kernel/syscalls/ipc/msgstress/.gitignore  |   1 -
 .../kernel/syscalls/ipc/msgstress/Makefile    |   5 +-
 .../syscalls/ipc/msgstress/msgstress01.c      | 314 +++++-------------
 .../syscalls/ipc/msgstress/msgstress03.c      | 290 ----------------
 8 files changed, 131 insertions(+), 533 deletions(-)
 delete mode 100644 testcases/kernel/syscalls/ipc/msgstress/msgstress03.c

diff --git a/include/libnewipc.h b/include/libnewipc.h
index 0f099c939..c1fa45ec3 100644
--- a/include/libnewipc.h
+++ b/include/libnewipc.h
@@ -44,6 +44,11 @@
 #define SHM_SIZE	2048
 #define INT_SIZE	4
 #define MODE_MASK	0x01FF
+#define MAXNPROCS	1000000
+#define MAXNREPS	100000
+
+key_t keyarray[MAXNPROCS];
+int pidarray[MAXNPROCS];
 
 struct mbuffer {
 	long type;
@@ -65,9 +70,15 @@ void *probe_free_addr(const char *file, const int lineno);
 #define PROBE_FREE_ADDR() \
 	probe_free_addr(__FILE__, __LINE__)
 
+int get_avail_queues(const char *file, const int lineno);
+#define GET_AVAIL_QUEUES() \
+	get_avail_queues(__FILE__, __LINE__)
+
 time_t get_ipc_timestamp(void);
 
 void msg_do_reader(long key, int tid, long type, int child, int nreps);
 
 void msg_do_writer(long key, int tid, long type, int child, int nreps);
+
+void setup_msg_key_array(int nprocs);
 #endif /* newlibipc.h */
diff --git a/libs/libltpnewipc/libnewipc.c b/libs/libltpnewipc/libnewipc.c
index 09871b421..cb885da13 100644
--- a/libs/libltpnewipc/libnewipc.c
+++ b/libs/libltpnewipc/libnewipc.c
@@ -69,6 +69,19 @@ int get_used_queues(const char *file, const int lineno)
 	return used_queues;
 }
 
+int get_avail_queues(const char *file, const int lineno)
+{
+	int used_queues = -1;
+	int max_queues = -1;
+	int avail_queues = -1;
+
+	safe_file_scanf(file, lineno, NULL, "/proc/sys/kernel/msgmni", "%d", &max_queues);
+	used_queues = get_used_queues(file, lineno);
+	avail_queues = max_queues - used_queues;
+
+	return avail_queues;
+}
+
 void *probe_free_addr(const char *file, const int lineno)
 {
 	void *addr;
@@ -174,3 +187,29 @@ void msg_do_writer(long key, int tid, long type, int child, int nreps)
 		key++;
 	}
 }
+
+void setup_msg_key_array(int nprocs)
+{
+	int i, j, ok;
+
+	srand(getpid());
+	/* Set up array of unique keys for use in allocating message queues */
+	for (i = 0; i < nprocs; i++) {
+		ok = 1;
+		do {
+			keyarray[i] = (key_t) rand();
+			/* Make sure key is unique and not private */
+			if (keyarray[i] == IPC_PRIVATE) {
+				ok = 0;
+				continue;
+			}
+			for (j = 0; j < i; j++) {
+				if (keyarray[j] == keyarray[i]) {
+					ok = 0;
+					break;
+				}
+				ok = 1;
+			}
+		} while (ok == 0);
+	}
+}
diff --git a/runtest/syscalls b/runtest/syscalls
index fe22ae5b6..68feb9390 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -815,7 +815,7 @@ msgctl05 msgctl05
 msgctl06 msgctl06
 msgstress01 msgstress01
 msgstress02 msgstress02
-msgstress03 msgstress03
+msgstress03 msgstress01 -n 10000 -l 10000
 msgstress04 msgstress04
 msgctl12 msgctl12
 
diff --git a/runtest/syscalls-ipc b/runtest/syscalls-ipc
index 68fff4038..8adb686c1 100644
--- a/runtest/syscalls-ipc
+++ b/runtest/syscalls-ipc
@@ -6,7 +6,7 @@ msgctl05 msgctl05
 msgctl06 msgctl06
 msgstress01 msgstress01
 msgstress02 msgstress02
-msgstress03 msgstress03
+msgstress03 msgstress01 -n 10000 -l 10000
 msgstress04 msgstress04
 msgctl12 msgctl12
 
diff --git a/testcases/kernel/syscalls/ipc/msgstress/.gitignore b/testcases/kernel/syscalls/ipc/msgstress/.gitignore
index a8f675399..e1df4cda8 100644
--- a/testcases/kernel/syscalls/ipc/msgstress/.gitignore
+++ b/testcases/kernel/syscalls/ipc/msgstress/.gitignore
@@ -1,4 +1,3 @@
 /msgstress01
 /msgstress02
-/msgstress03
 /msgstress04
diff --git a/testcases/kernel/syscalls/ipc/msgstress/Makefile b/testcases/kernel/syscalls/ipc/msgstress/Makefile
index b821bda01..27caffb35 100644
--- a/testcases/kernel/syscalls/ipc/msgstress/Makefile
+++ b/testcases/kernel/syscalls/ipc/msgstress/Makefile
@@ -3,10 +3,11 @@
 
 top_srcdir              ?= ../../../../..
 
-LTPLIBS = ltpipc
+LTPLIBS = ltpipc ltpnewipc
 
 include $(top_srcdir)/include/mk/testcases.mk
 
-LTPLDLIBS  += -lltpipc
+msgstress01: LTPLDLIBS = -lltpnewipc
+msgstress02 msgstress04: LTPLDLIBS = -lltpipc
 
 include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/syscalls/ipc/msgstress/msgstress01.c b/testcases/kernel/syscalls/ipc/msgstress/msgstress01.c
index 0a660c042..d1954616f 100644
--- a/testcases/kernel/syscalls/ipc/msgstress/msgstress01.c
+++ b/testcases/kernel/syscalls/ipc/msgstress/msgstress01.c
@@ -1,29 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /*
  * Copyright (c) International Business Machines  Corp., 2002
- *
- * This program is free software;  you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY;  without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
- * the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program;  if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Copyright (c) 2021 FUJITSU LIMITED. All rights reserved.
  *
  * 06/30/2001   Port to Linux   nsharoff@us.ibm.com
  * 11/06/2002   Port to LTP     dbarrera@us.ibm.com
+ * 03/10/2021   Convert to new api xuyang2018.jy@cn.fujitsu.com
  */
 
-/*
+/*\
+ * [DESCRIPTION]
+ *
  * Get and manipulate a message queue.
- */
+ * Fork a number of processes, each of which will create a message queue
+ * with one reader/writer pair which will read and write a number (iterations)
+ * of random length messages with specific values.
+\*/
 
-#define _XOPEN_SOURCE 500
 #include <signal.h>
 #include <errno.h>
 #include <string.h>
@@ -31,271 +24,116 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <unistd.h>
-#include <values.h>
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <sys/stat.h>
 #include <sys/ipc.h>
 #include <sys/msg.h>
-#include "test.h"
-#include "ipcmsg.h"
-#include "libmsgctl.h"
-
-char *TCID = "msgstress01";
-int TST_TOTAL = 1;
-
-#ifndef CONFIG_COLDFIRE
-#define MAXNPROCS	1000000	/* This value is set to an arbitrary high limit. */
-#else
-#define MAXNPROCS	 100000	/* Coldfire can't deal with 1000000 */
-#endif
-#define MAXNREPS	100000
-
-static key_t keyarray[MAXNPROCS];
-static int pidarray[MAXNPROCS];
-static int tid;
-static int MSGMNI, nprocs, nreps;
-static int procstat;
-static int mykid;
-
-void setup(void);
-void cleanup(void);
-
-static int dotest(key_t key, int child_process);
-static void sig_handler();
+#include "tst_test.h"
+#include "libnewipc.h"
+#include "tst_safe_sysv_ipc.h"
 
+static int nprocs = 1000;
+static int nreps = MAXNREPS;
 static char *opt_nprocs;
+static int tid[MAXNPROCS];
 static char *opt_nreps;
 
-static option_t options[] = {
-	{"n:", NULL, &opt_nprocs},
-	{"l:", NULL, &opt_nreps},
-	{NULL, NULL, NULL},
+static struct tst_option options[] = {
+	{"n:", &opt_nprocs, "-n N     Number of processes"},
+	{"l:", &opt_nreps, "-l N     Number of iterations"},
+	{NULL, NULL, NULL}
 };
 
-static void usage(void)
-{
-	printf("  -n      Number of processes\n");
-	printf("  -l      Number of iterations\n");
-}
-
-int main(int argc, char **argv)
+static void dotest(key_t key, int id, int child_process)
 {
-	int i, j, ok, pid;
-	int count, status;
-	struct sigaction act;
+	int pid;
 
-	tst_parse_opts(argc, argv, options, usage);
-
-	setup();
-
-	nreps = MAXNREPS;
-	nprocs = MSGMNI;
-
-	if (opt_nreps) {
-		nreps = atoi(opt_nreps);
-		if (nreps > MAXNREPS) {
-			tst_resm(TINFO,
-				 "Requested number of iterations too large, "
-				 "setting to Max. of %d", MAXNREPS);
-			nreps = MAXNREPS;
-		}
-	}
-
-	if (opt_nprocs) {
-		nprocs = atoi(opt_nprocs);
-		if (nprocs > MSGMNI) {
-			tst_resm(TINFO,
-				 "Requested number of processes too large, "
-				 "setting to Max. of %d", MSGMNI);
-			nprocs = MSGMNI;
-		}
+	pid = SAFE_FORK();
+	if (pid == 0) {
+		msg_do_reader(key, id, 1, child_process, nreps);
+		exit(0);
 	}
+	msg_do_writer(key, id, 1, child_process, nreps);
+	SAFE_WAIT(NULL);
+	SAFE_MSGCTL(id, IPC_RMID, NULL);
+}
 
-	srand(getpid());
-	tid = -1;
-
-	/* Setup signal handling routine */
-	memset(&act, 0, sizeof(act));
-	act.sa_handler = sig_handler;
-	sigemptyset(&act.sa_mask);
-	sigaddset(&act.sa_mask, SIGTERM);
-	if (sigaction(SIGTERM, &act, NULL) < 0) {
-		tst_brkm(TFAIL, NULL, "Sigset SIGTERM failed");
-	}
-	/* Set up array of unique keys for use in allocating message
-	 * queues
-	 */
-	for (i = 0; i < nprocs; i++) {
-		ok = 1;
-		do {
-			/* Get random key */
-			keyarray[i] = (key_t) rand();
-			/* Make sure key is unique and not private */
-			if (keyarray[i] == IPC_PRIVATE) {
-				ok = 0;
-				continue;
-			}
-			for (j = 0; j < i; j++) {
-				if (keyarray[j] == keyarray[i]) {
-					ok = 0;
-					break;
-				}
-				ok = 1;
-			}
-		} while (ok == 0);
-	}
+static void verify_msgstress(void)
+{
+	int i, pid;
+	int count;
 
-	/* Fork a number of processes, each of which will
-	 * create a message queue with one reader/writer
-	 * pair which will read and write a number (iterations)
-	 * of random length messages with specific values.
+	/*
+	 * Set up array of unique keys for use in allocating message
+	 * queues.
 	 */
+	setup_msg_key_array(nprocs);
 
 	for (i = 0; i < nprocs; i++) {
-		fflush(stdout);
-		if ((pid = FORK_OR_VFORK()) < 0) {
-			tst_brkm(TFAIL,
-				 NULL,
-				 "\tFork failed (may be OK if under stress)");
-		}
-		/* Child does this */
+		tid[i] = SAFE_MSGGET(keyarray[i], IPC_CREAT | S_IRUSR | S_IWUSR);
+		pid = SAFE_FORK();
 		if (pid == 0) {
-			procstat = 1;
-			exit(dotest(keyarray[i], i));
+			dotest(keyarray[i], tid[i], i);
+			exit(0);
 		}
-		pidarray[i] = pid;
 	}
 
 	count = 0;
+
 	while (1) {
-		if ((wait(&status)) > 0) {
-			if (status >> 8 != 0) {
-				tst_brkm(TFAIL, NULL,
-					 "Child exit status = %d",
-					 status >> 8);
-			}
+		if (wait(NULL) > 0) {
 			count++;
 		} else {
-			if (errno != EINTR) {
+			if (errno != EINTR)
 				break;
-			}
-#ifdef DEBUG
-			tst_resm(TINFO, "Signal detected during wait");
-#endif
 		}
 	}
-	/* Make sure proper number of children exited */
-	if (count != nprocs) {
-		tst_brkm(TFAIL,
-			 NULL,
-			 "Wrong number of children exited, Saw %d, Expected %d",
-			 count, nprocs);
-	}
 
-	tst_resm(TPASS, "Test ran successfully!");
+	if (count != nprocs)
+		tst_brk(TFAIL, "Wrong number of children exited, Saw %d, Expected %d",
+			count, nprocs);
 
-	cleanup();
-	tst_exit();
+	tst_res(TPASS, "Test ran successfully!");
 }
 
-static int dotest(key_t key, int child_process)
+static void setup(void)
 {
-	int id, pid;
-	int ret, status;
-
-	sighold(SIGTERM);
-	TEST(msgget(key, IPC_CREAT | S_IRUSR | S_IWUSR));
-	if (TEST_RETURN < 0) {
-		printf("msgget() error in child %d: %s\n",
-			child_process, strerror(TEST_ERRNO));
-
-		return FAIL;
-	}
-	tid = id = TEST_RETURN;
-	sigrelse(SIGTERM);
+	int avail_msg_queues;
 
-	fflush(stdout);
-	if ((pid = FORK_OR_VFORK()) < 0) {
-		printf("\tFork failed (may be OK if under stress)\n");
-		TEST(msgctl(tid, IPC_RMID, 0));
-		if (TEST_RETURN < 0) {
-			printf("mscgtl() error in cleanup: %s\n",
-				strerror(TEST_ERRNO));
-		}
-		return FAIL;
-	}
-	/* Child does this */
-	if (pid == 0)
-		exit(doreader(key, id, 1, child_process, nreps));
-	/* Parent does this */
-	mykid = pid;
-	procstat = 2;
-	ret = dowriter(key, id, 1, child_process, nreps);
-	wait(&status);
+	avail_msg_queues = GET_AVAIL_QUEUES();
+	if (avail_msg_queues <= 0)
+		tst_brk(TCONF, "Max message queues is used, cannot create more.");
 
-	if (ret != PASS)
-		exit(FAIL);
+	if (opt_nreps)
+		nreps = SAFE_STRTOL(opt_nreps, 1, MAXNREPS);
 
-	if ((!WIFEXITED(status) || (WEXITSTATUS(status) != PASS)))
-		exit(FAIL);
+	if (opt_nprocs)
+		nprocs = SAFE_STRTOL(opt_nprocs, 1, MAXNPROCS);
 
-	TEST(msgctl(id, IPC_RMID, 0));
-	if (TEST_RETURN < 0) {
-		printf("msgctl() errno %d: %s\n",
-			TEST_ERRNO, strerror(TEST_ERRNO));
-
-		return FAIL;
+	if (nprocs > avail_msg_queues) {
+		tst_res(TINFO, "Setting max processes to %u", avail_msg_queues);
+		nprocs = avail_msg_queues;
 	}
-	return PASS;
-}
 
-static void sig_handler(void)
-{
+	SAFE_SIGNAL(SIGTERM, SIG_IGN);
+	tst_res(TINFO, "process is %d, iterations is %d", nprocs, nreps);
 }
 
-void setup(void)
+static void cleanup(void)
 {
-	int nr_msgqs;
-
-	tst_tmpdir();
-
-	tst_sig(FORK, DEF_HANDLER, cleanup);
+	int i = 0;
 
-	TEST_PAUSE;
-
-	nr_msgqs = get_max_msgqueues();
-	if (nr_msgqs < 0)
-		cleanup();
-
-	nr_msgqs -= get_used_msgqueues();
-	if (nr_msgqs <= 0) {
-		tst_resm(TBROK,
-			 "Max number of message queues already used, cannot create more.");
-		cleanup();
-	}
-
-	/*
-	 * Since msgmni scales to the memory size, it may reach huge values
-	 * that are not necessary for this test.
-	 * That's why we define NR_MSGQUEUES as a high boundary for it.
-	 */
-	MSGMNI = min(nr_msgqs, NR_MSGQUEUES);
+	for (i = 0; i < nprocs; i++)
+		msgctl(tid[i], IPC_RMID, NULL);
 }
 
-void cleanup(void)
-{
-	int status;
-
-#ifdef DEBUG
-	tst_resm(TINFO, "Removing the message queue");
-#endif
-	(void)msgctl(tid, IPC_RMID, NULL);
-	if ((status = msgctl(tid, IPC_STAT, NULL)) != -1) {
-		(void)msgctl(tid, IPC_RMID, NULL);
-		tst_resm(TFAIL, "msgctl(tid, IPC_RMID) failed");
-
-	}
-
-	tst_rmdir();
-}
+static struct tst_test test = {
+	.timeout = -1,
+	.needs_tmpdir = 1,
+	.options = options,
+	.setup = setup,
+	.cleanup = cleanup,
+	.forks_child = 1,
+	.test_all = verify_msgstress,
+};
diff --git a/testcases/kernel/syscalls/ipc/msgstress/msgstress03.c b/testcases/kernel/syscalls/ipc/msgstress/msgstress03.c
deleted file mode 100644
index 294b401b1..000000000
--- a/testcases/kernel/syscalls/ipc/msgstress/msgstress03.c
+++ /dev/null
@@ -1,290 +0,0 @@
-/*
- * Copyright (c) International Business Machines  Corp., 2002
- *
- * This program is free software;  you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY;  without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
- * the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program;  if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * 06/30/2001   Port to Linux   nsharoff@us.ibm.com
- * 11/06/2002   Port to LTP     dbarrera@us.ibm.com
- */
-
-/*
- * Get and manipulate a message queue.
- * Same as msgstress01 but gets the actual msgmni value under procfs.
- */
-
-#define _XOPEN_SOURCE 500
-#include <signal.h>
-#include <errno.h>
-#include <string.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <values.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <sys/stat.h>
-#include <sys/ipc.h>
-#include <sys/msg.h>
-#include "test.h"
-#include "ipcmsg.h"
-#include "libmsgctl.h"
-
-char *TCID = "msgstress03";
-int TST_TOTAL = 1;
-
-#define MAXNPROCS	10000	/*These should be sufficient */
-#define MAXNREPS	10000	/*Else they srewup the system un-necessarily */
-
-static key_t keyarray[MAXNPROCS];
-static int pidarray[MAXNPROCS];
-static int tid;
-static int MSGMNI, nprocs, nreps;
-static int procstat;
-static int mykid;
-
-void setup(void);
-void cleanup(void);
-
-static int dotest(key_t key, int child_process);
-static void sig_handler(int signo);
-
-static char *opt_nprocs;
-static char *opt_nreps;
-
-static option_t options[] = {
-	{"n:", NULL, &opt_nprocs},
-	{"l:", NULL, &opt_nreps},
-	{NULL, NULL, NULL},
-};
-
-static void usage(void)
-{
-	printf("  -n      Number of processes\n");
-	printf("  -l      Number of iterations\n");
-}
-
-int main(int argc, char **argv)
-{
-	int i, j, ok, pid;
-	int count, status;
-	struct sigaction act;
-
-	tst_parse_opts(argc, argv, options, usage);
-
-	setup();
-
-	nreps = MAXNREPS;
-	nprocs = MSGMNI;
-
-	if (opt_nreps) {
-		nreps = atoi(opt_nreps);
-		if (nreps > MAXNREPS) {
-			tst_resm(TINFO,
-				 "Requested number of iterations too large, "
-				 "setting to Max. of %d", MAXNREPS);
-			nreps = MAXNREPS;
-		}
-	}
-
-	if (opt_nprocs) {
-		nprocs = atoi(opt_nprocs);
-		if (nprocs > MSGMNI) {
-			tst_resm(TINFO,
-				 "Requested number of processes too large, "
-				 "setting to Max. of %d", MSGMNI);
-			nprocs = MSGMNI;
-		}
-	}
-
-	srand(getpid());
-	tid = -1;
-
-	/* Setup signal handling routine */
-	memset(&act, 0, sizeof(act));
-	act.sa_handler = sig_handler;
-	sigemptyset(&act.sa_mask);
-	sigaddset(&act.sa_mask, SIGTERM);
-	if (sigaction(SIGTERM, &act, NULL) < 0) {
-		tst_brkm(TFAIL, NULL, "Sigset SIGTERM failed");
-	}
-	/* Set up array of unique keys for use in allocating message
-	 * queues
-	 */
-	for (i = 0; i < nprocs; i++) {
-		ok = 1;
-		do {
-			/* Get random key */
-			keyarray[i] = (key_t) rand();
-			/* Make sure key is unique and not private */
-			if (keyarray[i] == IPC_PRIVATE) {
-				ok = 0;
-				continue;
-			}
-			for (j = 0; j < i; j++) {
-				if (keyarray[j] == keyarray[i]) {
-					ok = 0;
-					break;
-				}
-				ok = 1;
-			}
-		} while (ok == 0);
-	}
-
-	/* Fork a number of processes, each of which will
-	 * create a message queue with one reader/writer
-	 * pair which will read and write a number (iterations)
-	 * of random length messages with specific values.
-	 */
-
-	for (i = 0; i < nprocs; i++) {
-		fflush(stdout);
-		if ((pid = FORK_OR_VFORK()) < 0) {
-			tst_brkm(TFAIL,
-				 NULL,
-				 "\tFork failed (may be OK if under stress)");
-		}
-		/* Child does this */
-		if (pid == 0) {
-			procstat = 1;
-			exit(dotest(keyarray[i], i));
-		}
-		pidarray[i] = pid;
-	}
-
-	count = 0;
-	while (1) {
-		if ((wait(&status)) > 0) {
-			if (status >> 8 != 0) {
-				tst_brkm(TFAIL, NULL,
-					 "Child exit status = %d",
-					 status >> 8);
-			}
-			count++;
-		} else {
-			if (errno != EINTR) {
-				break;
-			}
-#ifdef DEBUG
-			tst_resm(TINFO, "Signal detected during wait");
-#endif
-		}
-	}
-	/* Make sure proper number of children exited */
-	if (count != nprocs) {
-		tst_brkm(TFAIL,
-			 NULL,
-			 "Wrong number of children exited, Saw %d, Expected %d",
-			 count, nprocs);
-	}
-
-	tst_resm(TPASS, "Test ran successfully!");
-
-	cleanup();
-	tst_exit();
-}
-
-static int dotest(key_t key, int child_process)
-{
-	int id, pid;
-	int ret, status;
-
-	sighold(SIGTERM);
-	TEST(msgget(key, IPC_CREAT | S_IRUSR | S_IWUSR));
-	if (TEST_RETURN < 0) {
-		printf("msgget() error in child %d: %s\n",
-			child_process, strerror(TEST_ERRNO));
-		return FAIL;
-	}
-	tid = id = TEST_RETURN;
-	sigrelse(SIGTERM);
-
-	fflush(stdout);
-	if ((pid = FORK_OR_VFORK()) < 0) {
-		printf("Fork failed (may be OK if under stress)\n");
-		TEST(msgctl(tid, IPC_RMID, 0));
-		if (TEST_RETURN < 0) {
-			printf("msgctl() error in cleanup: %s\n",
-				strerror(TEST_ERRNO));
-		}
-		return FAIL;
-	}
-	if (pid == 0)
-		exit(doreader(key, id, 1, child_process, nreps));
-
-	mykid = pid;
-	procstat = 2;
-	ret = dowriter(key, id, 1, child_process, nreps);
-	wait(&status);
-
-	if (ret != PASS)
-		exit(FAIL);
-
-	if ((!WIFEXITED(status) || (WEXITSTATUS(status) != PASS)))
-		exit(FAIL);
-
-	TEST(msgctl(id, IPC_RMID, 0));
-	if (TEST_RETURN < 0) {
-		printf("msgctl() failed: %s\n",
-			strerror(TEST_ERRNO));
-		return FAIL;
-	}
-	return PASS;
-}
-
-static void sig_handler(int signo LTP_ATTRIBUTE_UNUSED)
-{
-}
-
-void setup(void)
-{
-	int nr_msgqs;
-
-	tst_tmpdir();
-
-	tst_sig(FORK, DEF_HANDLER, cleanup);
-
-	TEST_PAUSE;
-
-	nr_msgqs = get_max_msgqueues();
-	if (nr_msgqs < 0)
-		cleanup();
-
-	MSGMNI = nr_msgqs - get_used_msgqueues();
-	if (MSGMNI > MAXNPROCS)
-		MSGMNI = MAXNPROCS;
-	if (MSGMNI <= 0) {
-		tst_resm(TBROK,
-			 "Max number of message queues already used, cannot create more.");
-		cleanup();
-	}
-}
-
-void cleanup(void)
-{
-	int status;
-
-#ifdef DEBUG
-	tst_resm(TINFO, "Removing the message queue");
-#endif
-	(void)msgctl(tid, IPC_RMID, NULL);
-	if ((status = msgctl(tid, IPC_STAT, NULL)) != -1) {
-		(void)msgctl(tid, IPC_RMID, NULL);
-		tst_resm(TFAIL, "msgctl(tid, IPC_RMID) failed");
-
-	}
-
-	tst_rmdir();
-}
-- 
2.23.0




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

* [LTP] [PATCH v4 3/5] syscalls/msgstress02: Convert into new api
  2021-03-12 12:02           ` [LTP] [PATCH v4 1/5] libs/libltpnewipc/libnewipc.c: Add msg_do_reader/msg_do_writer function Yang Xu
  2021-03-12 12:02             ` [LTP] [PATCH v4 2/5] syscalls/msgstress01: Convert into new api and merge msgstress03 into it Yang Xu
@ 2021-03-12 12:02             ` Yang Xu
  2021-07-21 15:33               ` Cyril Hrubis
  2021-03-12 12:02             ` [LTP] [PATCH v4 4/5] sycalls/msgstress04: " Yang Xu
                               ` (3 subsequent siblings)
  5 siblings, 1 reply; 26+ messages in thread
From: Yang Xu @ 2021-03-12 12:02 UTC (permalink / raw)
  To: ltp

1)Remove SIGTERM signal handler and ignore it
2)use fork because SAFE_FORK not clean the another writer or
reader proceess

It also missed process num limit check and we will add it in the future.

Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
---
 .../kernel/syscalls/ipc/msgstress/Makefile    |   4 +-
 .../syscalls/ipc/msgstress/msgstress02.c      | 429 +++++-------------
 2 files changed, 116 insertions(+), 317 deletions(-)

diff --git a/testcases/kernel/syscalls/ipc/msgstress/Makefile b/testcases/kernel/syscalls/ipc/msgstress/Makefile
index 27caffb35..d80d0bf98 100644
--- a/testcases/kernel/syscalls/ipc/msgstress/Makefile
+++ b/testcases/kernel/syscalls/ipc/msgstress/Makefile
@@ -7,7 +7,7 @@ LTPLIBS = ltpipc ltpnewipc
 
 include $(top_srcdir)/include/mk/testcases.mk
 
-msgstress01: LTPLDLIBS = -lltpnewipc
-msgstress02 msgstress04: LTPLDLIBS = -lltpipc
+msgstress01 msgstress02: LTPLDLIBS = -lltpnewipc
+msgstress04: LTPLDLIBS = -lltpipc
 
 include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/syscalls/ipc/msgstress/msgstress02.c b/testcases/kernel/syscalls/ipc/msgstress/msgstress02.c
index e15131043..672f79e24 100644
--- a/testcases/kernel/syscalls/ipc/msgstress/msgstress02.c
+++ b/testcases/kernel/syscalls/ipc/msgstress/msgstress02.c
@@ -1,29 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /*
  * Copyright (c) International Business Machines  Corp., 2002
- *
- * This program is free software;  you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY;  without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
- * the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program;  if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Copyright (c) 2021 FUJITSU LIMITED. All rights reserved.
  *
  * 06/30/2001   Port to Linux   nsharoff@us.ibm.com
  * 11/11/2002   Port to LTP     dbarrera@us.ibm.com
+ * 03/12/2021   Convert to new api xuyang2018.jy@cn.fujitsu.com
  */
 
-/*
+/*\
+ * [DESCRIPTION]
+ *
  * Get and manipulate a message queue.
- */
+ * Fork a number of processes (nprocs), each of which will create a message
+ * queue with several (nkids) reader/writer pairs which will read and write
+ * a number (iterations) of random length messages with specific values (keys).
+\*/
 
-#define _XOPEN_SOURCE 500
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/ipc.h>
@@ -35,270 +28,82 @@
 #include <string.h>
 #include <stdlib.h>
 #include <unistd.h>
-#include "test.h"
-#include "ipcmsg.h"
-#include "libmsgctl.h"
-
-char *TCID = "msgstress02";
-int TST_TOTAL = 1;
+#include "tst_test.h"
+#include "libnewipc.h"
+#include "tst_safe_sysv_ipc.h"
 
-#define MAXNREPS	1000
-#ifndef CONFIG_COLDFIRE
-#define MAXNPROCS	 1000000	/* This value is set to an arbitrary high limit. */
-#else
-#define MAXNPROCS	 100000	/* Coldfire can't deal with 1000000 */
-#endif
 #define MAXNKIDS	10
 
-static key_t keyarray[MAXNPROCS];
-static int pidarray[MAXNPROCS];
 static int rkidarray[MAXNKIDS];
 static int wkidarray[MAXNKIDS];
-static int tid;
-static int nprocs, nreps, nkids, MSGMNI;
-static int procstat;
-
-void setup(void);
-void cleanup(void);
-
-static void term(int);
-static int dotest(key_t, int);
-static void cleanup_msgqueue(int i, int tid);
-
+static int tid[MAXNPROCS];
+static int nprocs = 1000;
+static int nreps = 1000;
+static int nkids = MAXNKIDS;
 static char *opt_nprocs;
 static char *opt_nkids;
 static char *opt_nreps;
 
-static option_t options[] = {
-	{"n:", NULL, &opt_nprocs},
-	{"c:", NULL, &opt_nkids},
-	{"l:", NULL, &opt_nreps},
-	{NULL, NULL, NULL},
+static struct tst_option options[] = {
+	{"n:", &opt_nprocs, "-n N     Number of processes"},
+	{"c:", &opt_nkids, "-c -N    Number of read/write child pairs"},
+	{"l:", &opt_nreps, "-l N     Number of iterations"},
+	{NULL, NULL, NULL}
 };
 
-static void usage(void)
-{
-	printf("  -n      Number of processes\n");
-	printf("  -c      Number of read/write child pairs\n");
-	printf("  -l      Number of iterations\n");
-}
-
-int main(int argc, char **argv)
-{
-	int i, j, ok, pid;
-	int count, status;
-
-	tst_parse_opts(argc, argv, options, usage);
-
-	setup();
-
-	nreps = MAXNREPS;
-	nprocs = MSGMNI;
-	nkids = MAXNKIDS;
-
-	if (opt_nreps) {
-		nreps = atoi(opt_nreps);
-		if (nreps > MAXNREPS) {
-			tst_resm(TINFO,
-				 "Requested number of iterations too large, "
-				 "setting to Max. of %d", MAXNREPS);
-			nreps = MAXNREPS;
-		}
-	}
-
-	if (opt_nprocs) {
-		nprocs = atoi(opt_nprocs);
-		if (nprocs > MSGMNI) {
-			tst_resm(TINFO,
-				 "Requested number of processes too large, "
-				 "setting to Max. of %d", MSGMNI);
-			nprocs = MSGMNI;
-		}
-	}
-
-	if (opt_nkids) {
-		nkids = atoi(opt_nkids);
-		if (nkids > MAXNKIDS) {
-			tst_resm(TINFO,
-				 "Requested number of read/write pairs too "
-				 "large, setting to Max. of %d", MAXNKIDS);
-			nkids = MAXNKIDS;
-		}
-	}
-
-	procstat = 0;
-	srand48((unsigned)getpid() + (unsigned)(getppid() << 16));
-	tid = -1;
-
-	/* Setup signal handleing routine */
-	if (sigset(SIGTERM, term) == SIG_ERR) {
-		tst_brkm(TFAIL, NULL, "Sigset SIGTERM failed");
-	}
-	/* Set up array of unique keys for use in allocating message
-	 * queues
-	 */
-	for (i = 0; i < nprocs; i++) {
-		ok = 1;
-		do {
-			/* Get random key */
-			keyarray[i] = (key_t) lrand48();
-			/* Make sure key is unique and not private */
-			if (keyarray[i] == IPC_PRIVATE) {
-				ok = 0;
-				continue;
-			}
-			for (j = 0; j < i; j++) {
-				if (keyarray[j] == keyarray[i]) {
-					ok = 0;
-					break;
-				}
-				ok = 1;
-			}
-		} while (ok == 0);
-	}
-	/* Fork a number of processes (nprocs), each of which will
-	 * create a message queue with several (nkids) reader/writer
-	 * pairs which will read and write a number (iterations)
-	 * of random length messages with specific values (keys).
-	 */
-
-	for (i = 0; i < nprocs; i++) {
-		fflush(stdout);
-		if ((pid = FORK_OR_VFORK()) < 0) {
-			tst_brkm(TFAIL,
-				 NULL,
-				 "\tFork failed (may be OK if under stress)");
-		}
-		/* Child does this */
-		if (pid == 0) {
-			procstat = 1;
-			exit(dotest(keyarray[i], i));
-		}
-		pidarray[i] = pid;
-	}
-
-	count = 0;
-	while (1) {
-		if ((wait(&status)) > 0) {
-			if (status >> 8 != PASS) {
-				tst_brkm(TFAIL, NULL,
-					 "Child exit status = %d",
-					 status >> 8);
-			}
-			count++;
-		} else {
-			if (errno != EINTR) {
-				break;
-			}
-#ifdef DEBUG
-			tst_resm(TINFO, "Signal detected during wait");
-#endif
-		}
-	}
-	/* Make sure proper number of children exited */
-	if (count != nprocs) {
-		tst_brkm(TFAIL,
-			 NULL,
-			 "Wrong number of children exited, Saw %d, Expected %d",
-			 count, nprocs);
-	}
-
-	tst_resm(TPASS, "Test ran successfully!");
-
-	cleanup();
-	tst_exit();
-}
-
-static void cleanup_msgqueue(int i, int tid)
+static void cleanup_msgqueue(int i, int id)
 {
 	/*
-	 * Decrease the value of i by 1 because it
-	 * is getting incremented even if the fork
-	 * is failing.
+	 * Decrease the value of i by 1 because it is getting incremented
+	 * even if the fork is failing.
 	 */
-
 	i--;
-	/*
-	 * Kill all children & free message queue.
-	 */
+
+	 /* Kill all children & free message queue. */
 	for (; i >= 0; i--) {
 		(void)kill(rkidarray[i], SIGKILL);
 		(void)kill(wkidarray[i], SIGKILL);
 	}
-
-	if (msgctl(tid, IPC_RMID, 0) < 0) {
-		tst_brkm(TFAIL | TERRNO, NULL, "Msgctl error in cleanup");
-	}
+	SAFE_MSGCTL(id, IPC_RMID, 0);
 }
 
-static int dotest(key_t key, int child_process)
+static void dotest(key_t key, int child_process, int id)
 {
-	int id, pid;
-	int i, count, status, exit_status;
-
-	sighold(SIGTERM);
-	if ((id = msgget(key, IPC_CREAT | S_IRUSR | S_IWUSR)) < 0) {
-		printf("msgget() error in child %d: %s\n",
-			child_process, strerror(errno));
-		return FAIL;
-	}
-	tid = id;
-	sigrelse(SIGTERM);
-
-	exit_status = PASS;
+	int pid, i, count;
 
 	for (i = 0; i < nkids; i++) {
-		fflush(stdout);
-		if ((pid = FORK_OR_VFORK()) < 0) {
-			printf("Fork failure in the first child of child group %d\n",
+		pid = fork();
+		if (pid < 0) {
+			tst_res(TFAIL, "Fork failure in the first child of child group %d\n",
 				child_process);
-			cleanup_msgqueue(i, tid);
-			return FAIL;
+			cleanup_msgqueue(i, id);
+			return;
 		}
 		/* First child does this */
 		if (pid == 0) {
-			procstat = 2;
-			exit(doreader(key, tid, getpid(),
-					child_process, nreps));
+			msg_do_reader(key, id, getpid(), child_process, nreps);
+			exit(0);
 		}
 		rkidarray[i] = pid;
-		fflush(stdout);
-		if ((pid = FORK_OR_VFORK()) < 0) {
-			printf("Fork failure in the second child of child group %d\n",
-				child_process);
-			/*
-			 * Kill the reader child process
-			 */
-			(void)kill(rkidarray[i], SIGKILL);
 
-			cleanup_msgqueue(i, tid);
-			return FAIL;
+		pid = fork();
+		if (pid < 0) {
+			tst_res(TFAIL, "Fork failure in the second child of child group %d\n",
+				child_process);
+			cleanup_msgqueue(i, id);
+			return;
 		}
 		/* Second child does this */
 		if (pid == 0) {
-			procstat = 2;
-			exit(dowriter(key, tid, rkidarray[i],
-					child_process, nreps));
+			msg_do_writer(key, id, rkidarray[i], child_process, nreps);
+			exit(0);
 		}
 		wkidarray[i] = pid;
 	}
 	/* Parent does this */
 	count = 0;
 	while (1) {
-		if ((wait(&status)) > 0) {
-			if (status >> 8 != PASS) {
-				printf("Child exit status = %d from child group %d\n",
-					status >> 8, child_process);
-				for (i = 0; i < nkids; i++) {
-					kill(rkidarray[i], SIGTERM);
-					kill(wkidarray[i], SIGTERM);
-				}
-				if (msgctl(tid, IPC_RMID, 0) < 0) {
-					printf("msgctl() error: %s\n",
-						strerror(errno));
-				}
-				return FAIL;
-			}
+		if (wait(NULL) > 0) {
 			count++;
 		} else {
 			if (errno != EINTR) {
@@ -307,102 +112,96 @@ static int dotest(key_t key, int child_process)
 		}
 	}
 	/* Make sure proper number of children exited */
-	if (count != (nkids * 2)) {
-		printf("Wrong number of children exited in child group %d, saw %d, expected %d\n",
+	if (count != (nkids * 2))
+		tst_res(TFAIL,
+			"Wrong number of children exited in child group %d, saw %d, expected %d\n",
 			child_process, count, (nkids * 2));
-		if (msgctl(tid, IPC_RMID, 0) < 0) {
-			printf("msgctl() error: %s\n", strerror(errno));
-		}
-		return FAIL;
-	}
-	if (msgctl(id, IPC_RMID, 0) < 0) {
-		printf("msgctl() failure in child group %d: %s\n",
-			child_process, strerror(errno));
-		return FAIL;
-	}
-	return exit_status;
+
+	SAFE_MSGCTL(id, IPC_RMID, NULL);
 }
 
-static void term(int sig LTP_ATTRIBUTE_UNUSED)
+static void verify_msgstress(void)
 {
-	int i;
+	int i, pid;
+	int count;
 
-	if (procstat == 0) {
-#ifdef DEBUG
-		tst_resm(TINFO, "SIGTERM signal received, test killing kids");
-#endif
-		for (i = 0; i < nprocs; i++) {
-			if (pidarray[i] > 0) {
-				if (kill(pidarray[i], SIGTERM) < 0) {
-					printf("Kill failed to kill child %d",
-						i);
-					exit(FAIL);
-				}
-			}
+	/*
+	 * Set up array of unique keys for use in allocating message
+	 * queues
+	 */
+	setup_msg_key_array(nprocs);
+
+	for (i = 0; i < nprocs; i++) {
+		tid[i] = SAFE_MSGGET(keyarray[i], IPC_CREAT | S_IRUSR | S_IWUSR);
+		pid = SAFE_FORK();
+		if (pid == 0) {
+			dotest(keyarray[i], i, tid[i]);
+			exit(0);
 		}
-		return;
+		pidarray[i] = pid;
 	}
 
-	if (procstat == 2) {
-		fflush(stdout);
-		exit(PASS);
-	}
+	count = 0;
+	while (1) {
+		if ((wait(NULL)) > 0) {
+			count++;
 
-	if (tid == -1) {
-		exit(FAIL);
+		} else {
+			if (errno != EINTR)
+				break;
+		}
 	}
-	for (i = 0; i < nkids; i++) {
-		if (rkidarray[i] > 0)
-			kill(rkidarray[i], SIGTERM);
-		if (wkidarray[i] > 0)
-			kill(wkidarray[i], SIGTERM);
+	/* Make sure proper number of children exited */
+	if (count != nprocs) {
+		tst_brk(TFAIL,
+			"Wrong number of children exited, Saw %d, Expected %d",
+			count, nprocs);
+		return;
 	}
+
+	tst_res(TPASS, "Test ran successfully!");
 }
 
-void setup(void)
+static void setup(void)
 {
-	int nr_msgqs;
+	int avail_msg_queues;
 
-	tst_tmpdir();
+	avail_msg_queues = GET_AVAIL_QUEUES();
+	if (avail_msg_queues <= 0)
+		tst_brk(TCONF, "Max message queues is used, cannot create more.");
 
-	tst_sig(FORK, DEF_HANDLER, cleanup);
+	if (opt_nreps)
+		nreps = SAFE_STRTOL(opt_nreps, 1, MAXNREPS);
 
-	TEST_PAUSE;
+	if (opt_nprocs)
+		nprocs = SAFE_STRTOL(opt_nprocs, 1, MAXNPROCS);
 
-	nr_msgqs = get_max_msgqueues();
-	if (nr_msgqs < 0)
-		cleanup();
-
-	nr_msgqs -= get_used_msgqueues();
-	if (nr_msgqs <= 0) {
-		tst_resm(TBROK,
-			 "Max number of message queues already used, cannot create more.");
-		cleanup();
+	if (nprocs > avail_msg_queues) {
+		tst_res(TINFO, "Setting max processes to %u", avail_msg_queues);
+		nprocs = avail_msg_queues;
 	}
 
-	/*
-	 * Since msgmni scales to the memory size, it may reach huge values
-	 * that are not necessary for this test.
-	 * That's why we define NR_MSGQUEUES as a high boundary for it.
-	 */
-	MSGMNI = min(nr_msgqs, NR_MSGQUEUES);
+	if (opt_nkids)
+		nkids = SAFE_STRTOL(opt_nkids, 1, MAXNKIDS);
+
+	SAFE_SIGNAL(SIGTERM, SIG_IGN);
+	tst_res(TINFO, "process is %d, iterations is %d, read/write pairs is %d",
+			nprocs, nreps, nkids);
 }
 
-void cleanup(void)
+static void cleanup(void)
 {
-	int status;
-
-#ifdef DEBUG
-	tst_resm(TINFO, "Removing the message queue");
-#endif
-	fflush(stdout);
-	(void)msgctl(tid, IPC_RMID, NULL);
-	if ((status = msgctl(tid, IPC_STAT, NULL)) != -1) {
-		(void)msgctl(tid, IPC_RMID, NULL);
-		tst_resm(TFAIL, "msgctl(tid, IPC_RMID) failed");
-
-	}
+	int i = 0;
 
-	fflush(stdout);
-	tst_rmdir();
+	for (i = 0; i < nprocs; i++)
+		msgctl(tid[i], IPC_RMID, NULL);
 }
+
+static struct tst_test test = {
+	.needs_tmpdir = 1,
+	.options = options,
+	.setup = setup,
+	.cleanup = cleanup,
+	.forks_child = 1,
+	.test_all = verify_msgstress,
+};
-- 
2.23.0




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

* [LTP] [PATCH v4 4/5] sycalls/msgstress04: Convert into new api
  2021-03-12 12:02           ` [LTP] [PATCH v4 1/5] libs/libltpnewipc/libnewipc.c: Add msg_do_reader/msg_do_writer function Yang Xu
  2021-03-12 12:02             ` [LTP] [PATCH v4 2/5] syscalls/msgstress01: Convert into new api and merge msgstress03 into it Yang Xu
  2021-03-12 12:02             ` [LTP] [PATCH v4 3/5] syscalls/msgstress02: Convert into new api Yang Xu
@ 2021-03-12 12:02             ` Yang Xu
  2021-07-21 15:35               ` Cyril Hrubis
  2021-03-12 12:02             ` [LTP] [PATCH v4 5/5] libs/libltpipc: Remove useless function and c file Yang Xu
                               ` (2 subsequent siblings)
  5 siblings, 1 reply; 26+ messages in thread
From: Yang Xu @ 2021-03-12 12:02 UTC (permalink / raw)
  To: ltp

It also missed process num check according to available memory.

Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
---
 .../kernel/syscalls/ipc/msgstress/Makefile    |   5 +-
 .../syscalls/ipc/msgstress/msgstress04.c      | 489 +++++-------------
 2 files changed, 142 insertions(+), 352 deletions(-)

diff --git a/testcases/kernel/syscalls/ipc/msgstress/Makefile b/testcases/kernel/syscalls/ipc/msgstress/Makefile
index d80d0bf98..b1201281d 100644
--- a/testcases/kernel/syscalls/ipc/msgstress/Makefile
+++ b/testcases/kernel/syscalls/ipc/msgstress/Makefile
@@ -3,11 +3,10 @@
 
 top_srcdir              ?= ../../../../..
 
-LTPLIBS = ltpipc ltpnewipc
+LTPLIBS = ltpnewipc
 
 include $(top_srcdir)/include/mk/testcases.mk
 
-msgstress01 msgstress02: LTPLDLIBS = -lltpnewipc
-msgstress04: LTPLDLIBS = -lltpipc
+LTPLDLIBS = -lltpnewipc
 
 include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/syscalls/ipc/msgstress/msgstress04.c b/testcases/kernel/syscalls/ipc/msgstress/msgstress04.c
index f1c124990..b6536e349 100644
--- a/testcases/kernel/syscalls/ipc/msgstress/msgstress04.c
+++ b/testcases/kernel/syscalls/ipc/msgstress/msgstress04.c
@@ -1,30 +1,23 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /*
  * Copyright (c) International Business Machines  Corp., 2002
  *
- * This program is free software;  you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY;  without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
- * the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program;  if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
  * 06/30/2001   Port to Linux   nsharoff@us.ibm.com
  * 11/11/2002   Port to LTP     dbarrera@us.ibm.com
+ * 03/12/2021   Convert to new api xuyang2018.jy@cn.fujitsu.com
  */
 
-/*
+/*\
+ * [DESCRIPTION]
+ *
  * Get and manipulate a message queue.
- * Same as msgstress02 but gets the actual msgmni value under procfs.
- */
+ * Fork a number of processes, each of which will create a message queue
+ * with several (nkids) reader/writer pairs which will read and write a
+ * number (iterations) of random length messages with specific values (keys).
+ * We do not fork more than maxnprocs at a time and we fork until all the
+ * message queues get used.
+\*/
 
-#define _XOPEN_SOURCE 500
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/ipc.h>
@@ -36,415 +29,213 @@
 #include <string.h>
 #include <stdlib.h>
 #include <unistd.h>
-#include "test.h"
-#include "ipcmsg.h"
-#include "libmsgctl.h"
-
-char *TCID = "msgstress04";
-int TST_TOTAL = 1;
+#include "tst_test.h"
+#include "libnewipc.h"
+#include "tst_safe_sysv_ipc.h"
 
-#define MAXNREPS	1000
-#ifndef CONFIG_COLDFIRE
-#define MAXNPROCS	 1000000	/* This value is set to an arbitrary high limit. */
-#else
-#define MAXNPROCS	 100000	/* Coldfire can't deal with 1000000 */
-#endif
 #define MAXNKIDS	10
-#define DEFNKIDS	2
 
-static int maxnkids = MAXNKIDS;	/* Used if pid_max is exceeded */
-static key_t keyarray[MAXNPROCS];
-static int pidarray[MAXNPROCS];
 static int rkidarray[MAXNKIDS];
 static int wkidarray[MAXNKIDS];
-static int tid;
-static int nprocs, nreps, nkids, MSGMNI;
-static int maxnprocs;
-static int procstat;
-
-void setup(void);
-void cleanup(void);
-
-static void term(int);
-static int dotest(key_t, int);
-static void dotest_iteration(int off);
-static void cleanup_msgqueue(int i, int tid);
-
+static int tid[MAXNPROCS];
+static int maxnprocs = MAXNPROCS;
+static int nreps = 1000;
+static int nkids = MAXNKIDS;
+static int MSGMNI, nprocs;
 static char *opt_maxnprocs;
 static char *opt_nkids;
 static char *opt_nreps;
 
-static option_t options[] = {
-	{"n:", NULL, &opt_maxnprocs},
-	{"c:", NULL, &opt_nkids},
-	{"l:", NULL, &opt_nreps},
-	{NULL, NULL, NULL},
+static struct tst_option options[] = {
+	{"n:", &opt_maxnprocs, "-n N     Number of processes"},
+	{"c:", &opt_nkids, "-c -N    Number of read/write child pairs"},
+	{"l:", &opt_nreps, "-l N     Number of iterations"},
+	{NULL, NULL, NULL}
 };
 
-static void usage(void)
-{
-	printf("  -n      Number of processes\n");
-	printf("  -c      Number of read/write child pairs\n");
-	printf("  -l      Number of iterations\n");
-}
-
-
-int main(int argc, char **argv)
-{
-	int i, j, ok;
-
-	tst_parse_opts(argc, argv, options, usage);
-
-	setup();
-
-	nreps = MAXNREPS;
-	nkids = MAXNKIDS;
-
-	if (opt_nreps) {
-		nreps = atoi(opt_nreps);
-		if (nreps > MAXNREPS) {
-			tst_resm(TINFO,
-				 "Requested number of iterations too large, "
-				 "setting to Max. of %d", MAXNREPS);
-			nreps = MAXNREPS;
-		}
-	}
-
-	if (opt_nkids) {
-		nkids = atoi(opt_nkids);
-		if (nkids > MAXNKIDS) {
-			tst_resm(TINFO,
-				 "Requested number of read/write pairs too "
-				 "large, setting to Max. of %d", MAXNKIDS);
-			nkids = MAXNKIDS;
-		}
-	}
-
-
-	if (opt_maxnprocs) {
-		if (atoi(opt_maxnprocs) > maxnprocs) {
-			tst_resm(TINFO,
-				 "Requested number of processes too large, "
-				 "setting to Max. of %d", MSGMNI);
-		} else {
-			maxnprocs = atoi(opt_maxnprocs);
-		}
-	}
-
-	procstat = 0;
-	srand48((unsigned)getpid() + (unsigned)(getppid() << 16));
-	tid = -1;
-
-	/* Setup signal handling routine */
-	if (sigset(SIGTERM, term) == SIG_ERR)
-		tst_brkm(TFAIL, cleanup, "Sigset SIGTERM failed");
-
-	/* Set up array of unique keys for use in allocating message
-	 * queues
-	 */
-	for (i = 0; i < MSGMNI; i++) {
-		ok = 1;
-		do {
-			/* Get random key */
-			keyarray[i] = (key_t) lrand48();
-			/* Make sure key is unique and not private */
-			if (keyarray[i] == IPC_PRIVATE) {
-				ok = 0;
-				continue;
-			}
-			for (j = 0; j < i; j++) {
-				if (keyarray[j] == keyarray[i]) {
-					ok = 0;
-					break;
-				}
-				ok = 1;
-			}
-		} while (ok == 0);
-	}
-	/* Fork a number of processes, each of which will
-	 * create a message queue with several (nkids) reader/writer
-	 * pairs which will read and write a number (iterations)
-	 * of random length messages with specific values (keys).
-	 *
-	 * We do not fork more than maxnprocs@a time and
-	 * we fork until all the message queues get used.
-	 */
-
-	if (MSGMNI <= maxnprocs) {
-		nprocs = MSGMNI;
-		dotest_iteration(0);
-	} else {
-		for (i = 0; i < (MSGMNI / maxnprocs); i++) {
-			nprocs = maxnprocs;
-			dotest_iteration(i * maxnprocs);
-		}
-
-		nprocs = MSGMNI % maxnprocs;
-		dotest_iteration(i * maxnprocs);
-	}
-
-	tst_resm(TPASS, "Test ran successfully!");
-
-	cleanup();
-	tst_exit();
-}
-
-static void dotest_iteration(int off)
-{
-	key_t key;
-	int i, count, status;
-	pid_t pid;
-
-	memset(pidarray, 0, sizeof(pidarray));
-
-	for (i = 0; i < nprocs; i++) {
-		key = keyarray[off + i];
-
-		if ((pid = FORK_OR_VFORK()) < 0)
-			tst_brkm(TFAIL, cleanup,
-				 "Fork failed (may be OK if under stress)");
-
-		/* Child does this */
-		if (pid == 0) {
-			procstat = 1;
-			exit(dotest(key, i));
-		}
-		pidarray[i] = pid;
-	}
-
-	count = 0;
-	while (1) {
-		if ((wait(&status)) > 0) {
-			if (status >> 8 != PASS)
-				tst_brkm(TFAIL, cleanup,
-					"Child exit status = %d", status >> 8);
-			count++;
-		} else {
-			if (errno != EINTR) {
-				break;
-			}
-#ifdef DEBUG
-			tst_resm(TINFO, "Signal detected during wait");
-#endif
-		}
-	}
-	/* Make sure proper number of children exited */
-	if (count != nprocs)
-		tst_brkm(TFAIL, cleanup,
-			 "Wrong number of children exited, Saw %d, Expected %d",
-			 count, nprocs);
-}
-
-static void cleanup_msgqueue(int i, int tid)
+static void cleanup_msgqueue(int i, int id)
 {
 	/*
-	 * Decrease the value of i by 1 because it
-	 * is getting incremented even if the fork
-	 * is failing.
+	 * Decrease the value of i by 1 because it is getting incremented
+	 * even if the fork is failing.
 	 */
-
 	i--;
-	/*
-	 * Kill all children & free message queue.
-	 */
+	/* Kill all children & free message queue. */
 	for (; i >= 0; i--) {
 		(void)kill(rkidarray[i], SIGKILL);
 		(void)kill(wkidarray[i], SIGKILL);
 	}
-
-	if (msgctl(tid, IPC_RMID, 0) < 0) {
-		printf("Msgctl error in cleanup_msgqueue %d\n", errno);
-		exit(FAIL);
-	}
+	SAFE_MSGCTL(id, IPC_RMID, 0);
 }
 
-static int dotest(key_t key, int child_process)
+static void dotest(key_t key, int child_process, int id)
 {
-	int id, pid;
-	int i, count, status, exit_status;
-
-	sighold(SIGTERM);
-	if ((id = msgget(key, IPC_CREAT | S_IRUSR | S_IWUSR)) < 0) {
-		printf("msgget() error in child %d: %s\n",
-			child_process, strerror(errno));
-		return FAIL;
-	}
-	tid = id;
-	sigrelse(SIGTERM);
-
-	exit_status = PASS;
+	int pid;
+	int i, count;
 
 	for (i = 0; i < nkids; i++) {
-		if ((pid = FORK_OR_VFORK()) < 0) {
-			printf("Fork failure in the first child of child group %d\n",
+		pid = fork();
+		if (pid < 0) {
+			tst_res(TFAIL,
+				"Fork failure in the first child of child group %d\n",
 				child_process);
-			cleanup_msgqueue(i, tid);
-			return FAIL;
+			cleanup_msgqueue(i, id);
+			return;
 		}
 		/* First child does this */
 		if (pid == 0) {
-			procstat = 2;
-			exit(doreader(key, tid, getpid(),
-					child_process, nreps));
+			msg_do_reader(key, id, getpid(), child_process, nreps);
+			exit(0);
 		}
 		rkidarray[i] = pid;
-		if ((pid = FORK_OR_VFORK()) < 0) {
-			printf("Fork failure in the second child of child group %d\n",
+		pid = fork();
+		if (pid < 0) {
+			tst_res(TFAIL,
+				"Fork failure in the first child of child group %d\n",
 				child_process);
-			/*
-			 * Kill the reader child process
-			 */
-			(void)kill(rkidarray[i], SIGKILL);
-
-			cleanup_msgqueue(i, tid);
-			return FAIL;
+			cleanup_msgqueue(i, id);
+			return;
 		}
 		/* Second child does this */
 		if (pid == 0) {
-			procstat = 2;
-			exit(dowriter(key, tid, rkidarray[i],
-					child_process, nreps));
+			msg_do_writer(key, id, rkidarray[i], child_process, nreps);
+			exit(0);
 		}
 		wkidarray[i] = pid;
 	}
 	/* Parent does this */
 	count = 0;
 	while (1) {
-		if ((wait(&status)) > 0) {
-			if (status >> 8 != PASS) {
-				printf("Child exit status = %d from child group %d\n",
-					status >> 8, child_process);
-				for (i = 0; i < nkids; i++) {
-					kill(rkidarray[i], SIGTERM);
-					kill(wkidarray[i], SIGTERM);
-				}
-				if (msgctl(tid, IPC_RMID, 0) < 0) {
-					printf("msgctl() error: %s\n",
-						strerror(errno));
-				}
-				return FAIL;
-			}
+		if (wait(NULL) > 0) {
 			count++;
 		} else {
-			if (errno != EINTR) {
+			if (errno != EINTR)
 				break;
-			}
 		}
 	}
 	/* Make sure proper number of children exited */
 	if (count != (nkids * 2)) {
-		printf("Wrong number of children exited in child group %d, saw %d, expected %d\n",
+		tst_res(TFAIL,
+			"Wrong number of children exited in child group %d, saw %d, expected %d\n",
 			child_process, count, (nkids * 2));
-		if (msgctl(tid, IPC_RMID, 0) < 0) {
-			printf("msgctl() error: %s\n", strerror(errno));
-		}
-		return FAIL;
 	}
-	if (msgctl(id, IPC_RMID, 0) < 0) {
-		printf("msgctl() failure in child group %d: %s\n",
-			child_process, strerror(errno));
-		return FAIL;
-	}
-	return exit_status;
+	SAFE_MSGCTL(id, IPC_RMID, NULL);
 }
 
-/* ARGSUSED */
-static void term(int sig LTP_ATTRIBUTE_UNUSED)
+static void dotest_iteration(int off)
 {
-	int i;
+	key_t key;
+	int i, count;
+	pid_t pid;
 
-	if (procstat == 0) {
-#ifdef DEBUG
-		tst_resm(TINFO, "SIGTERM signal received, test killing kids");
-#endif
-		for (i = 0; i < nprocs; i++) {
-			if (pidarray[i] > 0) {
-				if (kill(pidarray[i], SIGTERM) < 0) {
-					tst_resm(TBROK,
-						 "Kill failed to kill child %d",
-						 i);
-					exit(FAIL);
-				}
-			}
-		}
-		return;
-	}
+	memset(pidarray, 0, sizeof(pidarray));
+
+	for (i = 0; i < nprocs; i++) {
+		key = keyarray[off + i];
+		tid[i] = SAFE_MSGGET(key, IPC_CREAT | S_IRUSR | S_IWUSR);
+		pid = SAFE_FORK();
 
-	if (procstat == 2) {
-		exit(PASS);
+		/* Child does this */
+		if (pid == 0) {
+			dotest(key, i, tid[i]);
+			exit(0);
+		}
+		pidarray[i] = pid;
 	}
 
-	if (tid == -1) {
-		exit(FAIL);
+	count = 0;
+	while (1) {
+		if (wait(NULL) > 0) {
+			count++;
+		} else {
+			if (errno != EINTR)
+				break;
+		}
 	}
-	for (i = 0; i < nkids; i++) {
-		if (rkidarray[i] > 0)
-			kill(rkidarray[i], SIGTERM);
-		if (wkidarray[i] > 0)
-			kill(wkidarray[i], SIGTERM);
+	/* Make sure proper number of children exited */
+	if (count != nprocs) {
+		tst_brk(TFAIL,
+			"Wrong number of children exited, Saw %d, Expected %d",
+			count, nprocs);
 	}
 }
 
-void setup(void)
+static void verify_msgstress(void)
 {
-	int nr_msgqs, free_pids;
+	int i;
 
-	tst_tmpdir();
-	/* You will want to enable some signal handling so you can capture
-	 * unexpected signals like SIGSEGV.
+	/*
+	 * Set up array of unique keys for use in allocating message
+	 * queues.
 	 */
-	tst_sig(FORK, DEF_HANDLER, cleanup);
+	setup_msg_key_array(MSGMNI);
 
-	/* One cavet that hasn't been fixed yet.  TEST_PAUSE contains the code to
-	 * fork the test with the -c option.  You want to make sure you do this
-	 * before you create your temporary directory.
-	 */
-	TEST_PAUSE;
+	if (MSGMNI <= maxnprocs) {
+		nprocs = MSGMNI;
+		dotest_iteration(0);
+	} else {
+		for (i = 0; i < (MSGMNI / maxnprocs); i++) {
+			nprocs = maxnprocs;
+			dotest_iteration(i * maxnprocs);
+		}
 
-	nr_msgqs = get_max_msgqueues();
-	if (nr_msgqs < 0)
-		tst_brkm(TBROK, cleanup, "get_max_msgqueues() failed");
+		nprocs = MSGMNI % maxnprocs;
+		dotest_iteration(i * maxnprocs);
+	}
 
-	MSGMNI = nr_msgqs - get_used_msgqueues();
-	if (MSGMNI <= 0)
-		tst_brkm(TBROK, cleanup,
-			 "Max number of message queues already used, cannot create more.");
+	tst_res(TPASS, "Test ran successfully!");
+}
 
-	tst_resm(TINFO, "Found %d available message queues", MSGMNI);
+static void setup(void)
+{
+	int free_pids;
 
-	free_pids = tst_get_free_pids(cleanup);
+	MSGMNI = GET_AVAIL_QUEUES();
+	if (MSGMNI <= 0)
+		tst_brk(TCONF, "Max message queues is used, cannot create more.");
+	tst_res(TINFO, "Found %d available message queues", MSGMNI);
+
+	free_pids = tst_get_free_pids();
 	if (free_pids < 0) {
-		tst_brkm(TBROK, cleanup, "Can't obtain free_pid count");
+		tst_brk(TBROK, "Can't obtain free_pid count");
 	} else if (!free_pids) {
-		tst_brkm(TBROK, cleanup, "No free pids");
+		tst_brk(TBROK, "No free pids");
 	}
 
+	if (opt_nreps)
+		nreps = SAFE_STRTOL(opt_nreps, 1, MAXNREPS);
+
+	if (opt_nkids)
+		nkids = SAFE_STRTOL(opt_nkids, 1, MAXNKIDS);
+
+	if (opt_maxnprocs)
+		maxnprocs = SAFE_STRTOL(opt_maxnprocs, 1, MAXNPROCS);
+
 	/* We don't use more than a half of available pids.
 	 * For each child we fork up to 2*maxnkids grandchildren. */
-	maxnprocs = (free_pids / 2) / (1 + 2 * maxnkids);
-
+	maxnprocs = (free_pids / 2) / (1 + 2 * nkids);
 	if (!maxnprocs)
-		tst_brkm(TBROK, cleanup, "Not enough free pids");
+		tst_brk(TBROK, "Not enough free pids");
 
-	tst_resm(TINFO, "Using upto %d pids", free_pids / 2);
+	SAFE_SIGNAL(SIGTERM, SIG_IGN);
+	tst_res(TINFO,
+		"Using upto %d pids, total %d processes, per %d processs %d read/write pairs, %d repeats ",
+		free_pids/2, MSGMNI, maxnprocs, nkids, nreps);
 }
 
-void cleanup(void)
+static void cleanup(void)
 {
-	int status;
-
-	/*
-	 * Remove the message queue from the system
-	 */
-#ifdef DEBUG
-	tst_resm(TINFO, "Removing the message queue");
-#endif
-	(void)msgctl(tid, IPC_RMID, NULL);
-	if ((status = msgctl(tid, IPC_STAT, NULL)) != -1) {
-		(void)msgctl(tid, IPC_RMID, NULL);
-		tst_resm(TFAIL, "msgctl(tid, IPC_RMID) failed");
+	int i = 0;
 
-	}
-
-	tst_rmdir();
+	for (i = 0; i < nprocs; i++)
+		msgctl(tid[i], IPC_RMID, NULL);
 }
+
+static struct tst_test test = {
+	.needs_tmpdir = 1,
+	.options = options,
+	.setup = setup,
+	.cleanup = cleanup,
+	.forks_child = 1,
+	.test_all = verify_msgstress,
+};
-- 
2.23.0




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

* [LTP] [PATCH v4 5/5] libs/libltpipc: Remove useless function and c file
  2021-03-12 12:02           ` [LTP] [PATCH v4 1/5] libs/libltpnewipc/libnewipc.c: Add msg_do_reader/msg_do_writer function Yang Xu
                               ` (2 preceding siblings ...)
  2021-03-12 12:02             ` [LTP] [PATCH v4 4/5] sycalls/msgstress04: " Yang Xu
@ 2021-03-12 12:02             ` Yang Xu
  2021-07-21 14:27             ` [LTP] [PATCH v4 1/5] libs/libltpnewipc/libnewipc.c: Add msg_do_reader/msg_do_writer function Cyril Hrubis
  2021-07-21 15:29             ` Cyril Hrubis
  5 siblings, 0 replies; 26+ messages in thread
From: Yang Xu @ 2021-03-12 12:02 UTC (permalink / raw)
  To: ltp

Only old msgstress* case use these apis, so we can remove them

Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
---
 include/libmsgctl.h        |  39 ----------
 libs/libltpipc/libipc.c    |  46 ------------
 libs/libltpipc/libmsgctl.c | 147 -------------------------------------
 3 files changed, 232 deletions(-)
 delete mode 100644 include/libmsgctl.h
 delete mode 100644 libs/libltpipc/libmsgctl.c

diff --git a/include/libmsgctl.h b/include/libmsgctl.h
deleted file mode 100644
index e1afeab5f..000000000
--- a/include/libmsgctl.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) International Business Machines  Corp., 2002
- * Copyright (c) 2013 Oracle and/or its affiliates. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it would be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write the Free Software Foundation,
- * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#ifndef __LIBMSGCTL_H__
-#define __LIBMSGCTL_H__
-
-#define FAIL	1
-#define PASS	0
-
-struct mbuffer {
-	long type;
-	struct {
-		char len;
-		char pbytes[99];
-	} data;
-};
-
-int doreader(long key, int tid, long type, int child, int nreps);
-int dowriter(long key, int tid, long type, int child, int nreps);
-int fill_buffer(char *buf, char val, int size);
-int verify(char *buf, char val, int size, int child);
-
-#endif /*__LIBMSGCTL_H__ */
diff --git a/libs/libltpipc/libipc.c b/libs/libltpipc/libipc.c
index d94880f54..aeefaa9f4 100644
--- a/libs/libltpipc/libipc.c
+++ b/libs/libltpipc/libipc.c
@@ -172,49 +172,3 @@ void rm_shm(int shm_id)
 }
 
 #define BUFSIZE 512
-
-/*
- * Get the number of message queues already in use
- */
-int get_used_msgqueues(void)
-{
-	FILE *f;
-	int used_queues;
-	char buff[BUFSIZE];
-
-	f = popen("ipcs -q", "r");
-	if (!f) {
-		tst_brkm(TBROK | TERRNO, NULL, "pipe failed");
-	}
-	/* FIXME: Start at -4 because ipcs prints four lines of header */
-	for (used_queues = -4; fgets(buff, BUFSIZE, f); used_queues++) ;
-	pclose(f);
-	if (used_queues < 0) {
-		tst_brkm(TBROK, NULL, "Could not read output of 'ipcs' to "
-			 "calculate used message queues");
-	}
-	return used_queues;
-}
-
-/*
- * Get the max number of message queues allowed on system
- */
-int get_max_msgqueues(void)
-{
-	FILE *f;
-	char buff[BUFSIZE];
-
-	/* Get the max number of message queues allowed on system */
-	f = fopen("/proc/sys/kernel/msgmni", "r");
-	if (!f) {
-		tst_resm(TBROK, "Could not open /proc/sys/kernel/msgmni");
-		return -1;
-	}
-	if (!fgets(buff, BUFSIZE, f)) {
-		fclose(f);
-		tst_resm(TBROK, "Could not read /proc/sys/kernel/msgmni");
-		return -1;
-	}
-	fclose(f);
-	return atoi(buff);
-}
diff --git a/libs/libltpipc/libmsgctl.c b/libs/libltpipc/libmsgctl.c
deleted file mode 100644
index ae459d480..000000000
--- a/libs/libltpipc/libmsgctl.c
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright (c) International Business Machines  Corp., 2002
- * Copyright (c) 2013 Oracle and/or its affiliates. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it would be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write the Free Software Foundation,
- * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/ipc.h>
-#include <sys/msg.h>
-#include "libmsgctl.h"
-
-int doreader(long key, int tid, long type, int child, int nreps)
-{
-	int i, size;
-	int id;
-	struct mbuffer buffer;
-
-	id = msgget(key, 0);
-	if (id < 0) {
-		printf("msgget() error in the reader of child group %d: %s\n",
-			child, strerror(errno));
-
-		return FAIL;
-	}
-	if (id != tid) {
-		printf("Message queue mismatch in the reader of child group %d for message queue id %d\n",
-			child, id);
-
-		return FAIL;
-	}
-	for (i = 0; i < nreps; i++) {
-		memset(&buffer, 0, sizeof(buffer));
-
-		size = msgrcv(id, &buffer, 100, type, 0);
-		if (size < 0) {
-			printf("msgrcv() error in child %d, read # = %d: %s\n",
-				child, (i + 1), strerror(errno));
-
-			return FAIL;
-		}
-		if (buffer.type != type) {
-			printf("Type mismatch in child %d, read #d = %d: ",
-				child, (i + 1));
-			printf("for message got %ld, expected - %ld\n",
-				buffer.type, type);
-
-			return FAIL;
-		}
-		if (buffer.data.len + 1 != size) {
-			printf("Size mismatch in child %d, read # = %d: ",
-				child, (i + 1));
-			printf("for message got %d, expected - %d\n",
-				buffer.data.len + 1, size);
-
-			return FAIL;
-		}
-		if (verify(buffer.data.pbytes, (key % 255), size - 1, child)) {
-			printf("Verify failed in child %d read # = %d, key = %lx\n",
-				child, (i + 1), key);
-
-			return FAIL;
-		}
-		key++;
-	}
-	return PASS;
-}
-
-int dowriter(long key, int tid, long type, int child, int nreps)
-{
-	int i, size;
-	int id;
-	struct mbuffer buffer;
-
-	id = msgget(key, 0);
-	if (id < 0) {
-		printf("msgget() error in the writer of child group %d: %s\n",
-			child, strerror(errno));
-
-		return FAIL;
-	}
-	if (id != tid) {
-		printf("Message queue mismatch in the reader of child group %d for message queue id %d\n",
-			child, id);
-
-		return FAIL;
-	}
-
-	for (i = 0; i < nreps; i++) {
-		memset(&buffer, 0, sizeof(buffer));
-
-		do {
-			size = (lrand48() % 99);
-		} while (size == 0);
-		fill_buffer(buffer.data.pbytes, (key % 255), size);
-		buffer.data.len = size;
-		buffer.type = type;
-		if (msgsnd(id, &buffer, size + 1, 0) < 0) {
-			printf("msgsnd() error in child %d, write # = %d, key = %lx: %s\n",
-				child, nreps, key, strerror(errno));
-
-			return FAIL;
-		}
-		key++;
-	}
-	return PASS;
-}
-
-int fill_buffer(char *buf, char val, int size)
-{
-	int i;
-
-	for (i = 0; i < size; i++)
-		buf[i] = val;
-	return 0;
-}
-
-/* Check a buffer for correct values */
-int verify(char *buf, char val, int size, int child)
-{
-	while (size-- > 0) {
-		if (*buf++ != val) {
-			printf("Verify error in child %d, *buf = %x, val = %x, size = %d\n",
-				child, *buf, val, size);
-
-			return FAIL;
-		}
-	}
-	return PASS;
-}
-- 
2.23.0




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

* [LTP] [PATCH v4 1/5] libs/libltpnewipc/libnewipc.c: Add msg_do_reader/msg_do_writer function
  2021-03-12 12:02           ` [LTP] [PATCH v4 1/5] libs/libltpnewipc/libnewipc.c: Add msg_do_reader/msg_do_writer function Yang Xu
                               ` (3 preceding siblings ...)
  2021-03-12 12:02             ` [LTP] [PATCH v4 5/5] libs/libltpipc: Remove useless function and c file Yang Xu
@ 2021-07-21 14:27             ` Cyril Hrubis
  2021-07-21 15:29             ` Cyril Hrubis
  5 siblings, 0 replies; 26+ messages in thread
From: Cyril Hrubis @ 2021-07-21 14:27 UTC (permalink / raw)
  To: ltp

Hi!
First of all sorry for the long delay.

> Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
> ---
>  include/libnewipc.h           | 11 +++++
>  libs/libltpnewipc/libnewipc.c | 75 +++++++++++++++++++++++++++++++++++
>  2 files changed, 86 insertions(+)
> 
> diff --git a/include/libnewipc.h b/include/libnewipc.h
> index 075364f85..0f099c939 100644
> --- a/include/libnewipc.h
> +++ b/include/libnewipc.h
> @@ -45,6 +45,14 @@
>  #define INT_SIZE	4
>  #define MODE_MASK	0x01FF
>  
> +struct mbuffer {
> +	long type;
> +	struct {
> +		char len;
> +		char pbytes[99];
> +	} data;
> +};
> +
>  key_t getipckey(const char *file, const int lineno);
>  #define GETIPCKEY() \
>  	getipckey(__FILE__, __LINE__)
> @@ -59,4 +67,7 @@ void *probe_free_addr(const char *file, const int lineno);
>  
>  time_t get_ipc_timestamp(void);
>  
> +void msg_do_reader(long key, int tid, long type, int child, int nreps);
> +
> +void msg_do_writer(long key, int tid, long type, int child, int nreps);
>  #endif /* newlibipc.h */
> diff --git a/libs/libltpnewipc/libnewipc.c b/libs/libltpnewipc/libnewipc.c
> index d0974bbe0..09871b421 100644
> --- a/libs/libltpnewipc/libnewipc.c
> +++ b/libs/libltpnewipc/libnewipc.c
> @@ -99,3 +99,78 @@ time_t get_ipc_timestamp(void)
>  
>  	return ts.tv_sec;
>  }
> +
> +static int verify(char *buf, char val, int size, int child)
> +{
> +	while (size-- > 0) {
> +		if (*buf++ != val) {
> +			tst_res(TFAIL,
> +				"Verify error in child %d, *buf = %x, val = %x, size = %d",
> +				child, *buf, val, size);

Actually this piece of code had a bug in the original version as well,
as we do *buf++ we end up one byte after the position we wanted to
print if we ever got wrong byte, possibly out of the buffer as well.

So I guess that this will be much better and easier to read with usuall
for loop and array subscript:

	for (i = 0; i < size; i++) {
		if (buf[i] != val)  {
		...

Also we report failure in the msg_do_reader() so I guess that it would
be slightly better to report TINFO with the details here and let the
msg_do_reader() report the failure.

> +			return 1;
> +		}
> +	}
> +	return 0;
> +}
> +
> +void msg_do_reader(long key, int tid, long type, int child, int nreps)
> +{
> +	int i, size;
> +	int id;
> +	struct mbuffer buffer;
> +
> +	id = SAFE_MSGGET(key, 0);
> +	if (id != tid) {
> +		tst_brk(TFAIL,
> +			"Message queue mismatch in the reader of child group %d for message queue id %d ",
> +			child, id);
> +	}
> +	for (i = 0; i < nreps; i++) {
> +		memset(&buffer, 0, sizeof(buffer));
> +
> +		size = SAFE_MSGRCV(id, &buffer, 100, type, 0);
> +		if (buffer.type != type) {
> +			tst_brk(TFAIL,
> +				"Type mismatch in child %d, read #%d, for message got %ld, exected %ld",
> +				child, (i + 1), buffer.type, type);
> +		}
> +		if (buffer.data.len + 1 != size) {
> +			tst_brk(TFAIL,
> +				"Size mismatch in child %d, read #%d, for message got %d, expected %d",
> +				child, (i + 1), buffer.data.len + 1, size);
> +		}
> +		if (verify(buffer.data.pbytes, (key % 255), size - 1, child)) {
> +			tst_brk(TFAIL,
> +				"Verify failed in child %d read # = %d, key = %lx",
> +				child, (i + 1), key);
> +		}
> +		key++;
> +	}
> +}
> +
> +void msg_do_writer(long key, int tid, long type, int child, int nreps)
> +{
> +	int i, size;
> +	int id;
> +	struct mbuffer buffer;
> +
> +	id = SAFE_MSGGET(key, 0);
> +	if (id != tid) {
> +		tst_brk(TFAIL,
> +			"Message queue mismatch in the writer of child group %d for message queue id %d",
> +			child, id);
> +	}
> +
> +	for (i = 0; i < nreps; i++) {
> +		memset(&buffer, 0, sizeof(buffer));

We set the relevant part of the buffer with (key % 255), do we really
have to clear it here?

> +		do {
> +			size = (lrand48() % 99);
> +		} while (size == 0);
> +		memset(buffer.data.pbytes, (key % 255), size);
> +		buffer.data.len = size;
> +		buffer.type = type;
> +		SAFE_MSGSND(id, &buffer, size + 1, 0);
> +		key++;
> +	}
> +}

-- 
Cyril Hrubis
chrubis@suse.cz

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

* [LTP] [PATCH v4 2/5] syscalls/msgstress01: Convert into new api and merge msgstress03 into it
  2021-03-12 12:02             ` [LTP] [PATCH v4 2/5] syscalls/msgstress01: Convert into new api and merge msgstress03 into it Yang Xu
@ 2021-07-21 15:07               ` Cyril Hrubis
  0 siblings, 0 replies; 26+ messages in thread
From: Cyril Hrubis @ 2021-07-21 15:07 UTC (permalink / raw)
  To: ltp

Hi!
The code looks much better there are just two minor things.

> 2)Ignore SIGTERM instead of empty signhanlder and sighold/sigrelease

I wonder why do we ingore SIGTERM in the first place?

>  msgctl06 msgctl06
>  msgstress01 msgstress01
>  msgstress02 msgstress02
> -msgstress03 msgstress03
> +msgstress03 msgstress01 -n 10000 -l 10000
>  msgstress04 msgstress04
>  msgctl12 msgctl12
>  
> diff --git a/runtest/syscalls-ipc b/runtest/syscalls-ipc
> index 68fff4038..8adb686c1 100644
> --- a/runtest/syscalls-ipc
> +++ b/runtest/syscalls-ipc
> @@ -6,7 +6,7 @@ msgctl05 msgctl05
>  msgctl06 msgctl06
>  msgstress01 msgstress01
>  msgstress02 msgstress02
> -msgstress03 msgstress03
> +msgstress03 msgstress01 -n 10000 -l 10000

I'm also not sure if we should call it msgstress03, maybe it would be
cleaner if we named these two tests with msgstress01 with some suffix.

-- 
Cyril Hrubis
chrubis@suse.cz

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

* [LTP] [PATCH v4 1/5] libs/libltpnewipc/libnewipc.c: Add msg_do_reader/msg_do_writer function
  2021-03-12 12:02           ` [LTP] [PATCH v4 1/5] libs/libltpnewipc/libnewipc.c: Add msg_do_reader/msg_do_writer function Yang Xu
                               ` (4 preceding siblings ...)
  2021-07-21 14:27             ` [LTP] [PATCH v4 1/5] libs/libltpnewipc/libnewipc.c: Add msg_do_reader/msg_do_writer function Cyril Hrubis
@ 2021-07-21 15:29             ` Cyril Hrubis
  5 siblings, 0 replies; 26+ messages in thread
From: Cyril Hrubis @ 2021-07-21 15:29 UTC (permalink / raw)
  To: ltp

Hi!
> +void msg_do_reader(long key, int tid, long type, int child, int nreps)
> +{
> +	int i, size;
> +	int id;
> +	struct mbuffer buffer;
> +
> +	id = SAFE_MSGGET(key, 0);
> +	if (id != tid) {
> +		tst_brk(TFAIL,
> +			"Message queue mismatch in the reader of child group %d for message queue id %d ",
> +			child, id);
> +	}

Also looking at how these functions are used, we fork a child that calls
this function then wait it and ignore the exit value it does not make
sense to use tst_brk() here at all.

The tst_brk() is supposed to exit the whole test, including all
suprocesses but that does not work if we throw away the child return
value. This piece of code looks like we exit the whole test here, which
isn't simply true.

So either we should do tst_res(TFAIL, ...) followed by an exit(0) here,
or we should handle the return value in the parent. I.e. stop the test
if one of the children reported a failure.

> +	for (i = 0; i < nreps; i++) {
> +		memset(&buffer, 0, sizeof(buffer));
> +
> +		size = SAFE_MSGRCV(id, &buffer, 100, type, 0);
> +		if (buffer.type != type) {
> +			tst_brk(TFAIL,
> +				"Type mismatch in child %d, read #%d, for message got %ld, exected %ld",
> +				child, (i + 1), buffer.type, type);
> +		}
> +		if (buffer.data.len + 1 != size) {
> +			tst_brk(TFAIL,
> +				"Size mismatch in child %d, read #%d, for message got %d, expected %d",
> +				child, (i + 1), buffer.data.len + 1, size);
> +		}
> +		if (verify(buffer.data.pbytes, (key % 255), size - 1, child)) {
> +			tst_brk(TFAIL,
> +				"Verify failed in child %d read # = %d, key = %lx",
> +				child, (i + 1), key);
> +		}
> +		key++;
> +	}

It would also make sense to do exit(0); here so that we do not have to
repeat that in each test.

> +}
> +
> +void msg_do_writer(long key, int tid, long type, int child, int nreps)
> +{
> +	int i, size;
> +	int id;
> +	struct mbuffer buffer;
> +
> +	id = SAFE_MSGGET(key, 0);
> +	if (id != tid) {
> +		tst_brk(TFAIL,
> +			"Message queue mismatch in the writer of child group %d for message queue id %d",
> +			child, id);
> +	}
> +
> +	for (i = 0; i < nreps; i++) {
> +		memset(&buffer, 0, sizeof(buffer));
> +
> +		do {
> +			size = (lrand48() % 99);
> +		} while (size == 0);
> +		memset(buffer.data.pbytes, (key % 255), size);
> +		buffer.data.len = size;
> +		buffer.type = type;
> +		SAFE_MSGSND(id, &buffer, size + 1, 0);
> +		key++;
> +	}
> +}

And same here.

-- 
Cyril Hrubis
chrubis@suse.cz

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

* [LTP] [PATCH v4 3/5] syscalls/msgstress02: Convert into new api
  2021-03-12 12:02             ` [LTP] [PATCH v4 3/5] syscalls/msgstress02: Convert into new api Yang Xu
@ 2021-07-21 15:33               ` Cyril Hrubis
  0 siblings, 0 replies; 26+ messages in thread
From: Cyril Hrubis @ 2021-07-21 15:33 UTC (permalink / raw)
  To: ltp

Hi!
Generally looks much better, comments inline.

> -static int dotest(key_t key, int child_process)
> +static void dotest(key_t key, int child_process, int id)
>  {
> -	int id, pid;
> -	int i, count, status, exit_status;
> -
> -	sighold(SIGTERM);
> -	if ((id = msgget(key, IPC_CREAT | S_IRUSR | S_IWUSR)) < 0) {
> -		printf("msgget() error in child %d: %s\n",
> -			child_process, strerror(errno));
> -		return FAIL;
> -	}
> -	tid = id;
> -	sigrelse(SIGTERM);
> -
> -	exit_status = PASS;
> +	int pid, i, count;
>  
>  	for (i = 0; i < nkids; i++) {
> -		fflush(stdout);
> -		if ((pid = FORK_OR_VFORK()) < 0) {
> -			printf("Fork failure in the first child of child group %d\n",
> +		pid = fork();

Why don't we use SAFE_FORK() here as well?

I guess that the main point is to make sure that we cleanup the message
queueus that would otherwise stayed on the system.

...

> +	SAFE_SIGNAL(SIGTERM, SIG_IGN);

And here as well, I do not get why we ignore SIGTERM at all.

-- 
Cyril Hrubis
chrubis@suse.cz

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

* [LTP] [PATCH v4 4/5] sycalls/msgstress04: Convert into new api
  2021-03-12 12:02             ` [LTP] [PATCH v4 4/5] sycalls/msgstress04: " Yang Xu
@ 2021-07-21 15:35               ` Cyril Hrubis
  0 siblings, 0 replies; 26+ messages in thread
From: Cyril Hrubis @ 2021-07-21 15:35 UTC (permalink / raw)
  To: ltp

Hi!
Isn't this mostly the same as msgstress02.c? Can we merge these two as
well?


-- 
Cyril Hrubis
chrubis@suse.cz

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

end of thread, other threads:[~2021-07-21 15:35 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-06-18  9:41 [LTP] [PATCH v2 1/2] libs/libltpnewipc: Add libnewmsgctl.c Yang Xu
2020-06-18  9:41 ` [LTP] [PATCH v2 2/2] syscalls/msgstress: scale number of processes accodingly to available RAM Yang Xu
2020-07-22 15:45   ` Cyril Hrubis
2020-07-23  6:34     ` Yang Xu
2020-10-21 12:57     ` [LTP] [PATCH v3 1/4] syscalls/msgstress: Add common file for msgstress Yang Xu
2020-10-21 12:57       ` [LTP] [PATCH v3 2/4] syscalls/msgstress*: cleanup and convert into new api Yang Xu
2020-11-11 16:31         ` Cyril Hrubis
2021-03-12 12:02           ` [LTP] [PATCH v4 1/5] libs/libltpnewipc/libnewipc.c: Add msg_do_reader/msg_do_writer function Yang Xu
2021-03-12 12:02             ` [LTP] [PATCH v4 2/5] syscalls/msgstress01: Convert into new api and merge msgstress03 into it Yang Xu
2021-07-21 15:07               ` Cyril Hrubis
2021-03-12 12:02             ` [LTP] [PATCH v4 3/5] syscalls/msgstress02: Convert into new api Yang Xu
2021-07-21 15:33               ` Cyril Hrubis
2021-03-12 12:02             ` [LTP] [PATCH v4 4/5] sycalls/msgstress04: " Yang Xu
2021-07-21 15:35               ` Cyril Hrubis
2021-03-12 12:02             ` [LTP] [PATCH v4 5/5] libs/libltpipc: Remove useless function and c file Yang Xu
2021-07-21 14:27             ` [LTP] [PATCH v4 1/5] libs/libltpnewipc/libnewipc.c: Add msg_do_reader/msg_do_writer function Cyril Hrubis
2021-07-21 15:29             ` Cyril Hrubis
2020-10-21 12:57       ` [LTP] [PATCH v3 3/4] libmsgctl: Remove it Yang Xu
2020-10-21 12:57       ` [LTP] [PATCH v3 4/4] lipipc: Remove useless get_max_msgqueues api Yang Xu
2020-11-11 15:44       ` [LTP] [PATCH v3 1/4] syscalls/msgstress: Add common file for msgstress Cyril Hrubis
2020-11-13  6:14         ` Yang Xu
2020-11-13 15:26           ` Cyril Hrubis
2020-06-24  5:04 ` [LTP] [PATCH v2 1/2] libs/libltpnewipc: Add libnewmsgctl.c Yang Xu
2020-07-16  1:07   ` Yang Xu
2020-07-22 15:01 ` Cyril Hrubis
2020-07-23  6:29   ` Yang Xu

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.