[LTP] [PATCH v1] Refactor fork12 using new LTP API

Andrea Cervesato andrea.cervesato@suse.de
Wed Sep 6 10:09:50 CEST 2023


From: Andrea Cervesato <andrea.cervesato@suse.com>

Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
 testcases/kernel/syscalls/fork/fork12.c | 177 +++++++++---------------
 1 file changed, 62 insertions(+), 115 deletions(-)

diff --git a/testcases/kernel/syscalls/fork/fork12.c b/testcases/kernel/syscalls/fork/fork12.c
index 1c55c0c30..d8767859f 100644
--- a/testcases/kernel/syscalls/fork/fork12.c
+++ b/testcases/kernel/syscalls/fork/fork12.c
@@ -1,137 +1,84 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /*
- *   Copyright (c) International Business Machines  Corp., 2001
- *
- *   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
- *
- *
- * NAME
- *	fork12.c
- *
- * DESCRIPTION
- *	Check that all children inherit parent's file descriptor
- *
- * ALGORITHM
- *	Parent forks processes until -1 is returned.$
- *
- * USAGE
- *	fork12
- *	** CAUTION ** Can hang your machine, esp prior to 2.4.19
- *
- * HISTORY
- *	07/2001 Ported by Wayne Boyer
- *	07/2002 Split from fork07 as a test case to exhaust available pids.
+ * Copyright (c) International Business Machines  Corp., 2001
+ *     07/2001 Ported by Wayne Boyer
+ * Copyright (C) 2023 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+/*\
+ *[Description]
  *
- * RESTRICTIONS
- *	Should be run as root to avoid resource limits.$
- *	Should not be run with other test programs because it tries to
- *	  use all available pids.
+ * This test spawns multiple processes inside a child, until fork() returns -1.
+ * Then we check if EAGAIN is raised.
  */
 
-#include <stdio.h>
+#include <stdlib.h>
 #include <sys/wait.h>
-#include <errno.h>
-#include <string.h>
-#include "test.h"
-#include "safe_macros.h"
-
-char *TCID = "fork12";
-int TST_TOTAL = 1;
+#include "tst_test.h"
 
-static void setup(void);
-static void cleanup(void);
-static void fork12_sigs(int signum);
+static pid_t child_pid;
 
-int main(int ac, char **av)
+static void start_forking(void)
 {
-	int forks, pid1, fork_errno, waitstatus;
-	int ret, status;
-	int lc;
-
-	tst_parse_opts(ac, av, NULL, NULL);
-
-	setup();
-
-	for (lc = 0; TEST_LOOPING(lc); lc++) {
-		tst_count = 0;
-
-		tst_resm(TINFO, "Forking as many kids as possible");
-		forks = 0;
-		while ((pid1 = fork()) != -1) {
-			if (pid1 == 0) {	/* child */
-				/*
-				 * Taunt the OOM killer so that it doesn't
-				 * kill system processes
-				 */
-				SAFE_FILE_PRINTF(NULL,
-					"/proc/self/oom_score_adj", "500");
-				pause();
-				exit(0);
-			}
-			forks++;
-			ret = SAFE_WAITPID(cleanup, -1, &status, WNOHANG);
-			if (ret > 0) {
-				/* a child may be killed by OOM killer */
-				if (WTERMSIG(status) == SIGKILL)
-					break;
-				tst_brkm(TBROK, cleanup,
-					 "child exit with error code %d or signal %d",
-					 WEXITSTATUS(status), WTERMSIG(status));
-			}
+	pid_t pid;
+	int status;
+	int forks = 1;
+
+	tst_res(TINFO, "Forking as many children as possible");
+
+	while (1) {
+		TEST(fork());
+		pid = TST_RET;
+
+		if (pid == -1)
+			break;
+
+		if (!pid) {
+			/*
+			 * Taunt the OOM killer so that it doesn't
+			 * kill system processes
+			 */
+			SAFE_FILE_PRINTF("/proc/self/oom_score_adj", "500");
+			pause();
+			exit(0);
 		}
-		fork_errno = errno;
-
-		/* parent */
-		tst_resm(TINFO, "Number of processes forked is %d", forks);
-		tst_resm(TPASS, "fork() eventually failed with %d: %s",
-			 fork_errno, strerror(fork_errno));
-		/* collect our kids */
-		/*
-		 * Introducing a sleep(3) to make sure all children are
-		 * at pause() when SIGQUIT is sent to them
-		 */
-		sleep(3);
-		kill(0, SIGQUIT);
-		while (wait(&waitstatus) > 0) ;
 
+		forks++;
+
+		if (SAFE_WAITPID(-1, &status, WNOHANG) > 0) {
+			tst_brk(TBROK, "child exit with error code %d or signal %d",
+					WEXITSTATUS(status),
+					WTERMSIG(status));
+		}
 	}
 
-	cleanup();
-	tst_exit();
+	tst_res(TINFO, "Number of processes forked is %d", forks);
+	TST_EXP_EXPR(TST_ERR == EAGAIN, "last fork() failed with EAGAIN");
 }
 
-static void setup(void)
+static void run(void)
 {
-	tst_sig(FORK, fork12_sigs, cleanup);
-	TEST_PAUSE;
+	int status;
+
+	child_pid = SAFE_FORK();
+	if (!child_pid) {
+		start_forking();
+		return;
+	}
+
+	SAFE_WAIT(&status);
 }
 
 static void cleanup(void)
 {
-	int waitstatus;
+	kill(child_pid, 0);
 
-	/* collect our kids */
-	kill(0, SIGQUIT);
-	while (wait(&waitstatus) > 0) ;
+	if (errno != ESRCH)
+		SAFE_KILL(child_pid, SIGKILL);
 }
 
-static void fork12_sigs(int signum)
-{
-	if (signum == SIGQUIT) {
-		/* Children will continue, parent will ignore */
-	} else {
-		tst_brkm(TBROK, cleanup,
-			 "Unexpected signal %d received.", signum);
-	}
-}
+static struct tst_test test = {
+	.test_all = run,
+	.cleanup = cleanup,
+	.forks_child = 1,
+	.max_runtime = 600,
+};
-- 
2.35.3



More information about the ltp mailing list