ltp.lists.linux.it archive mirror
 help / color / mirror / Atom feed
* [LTP] [PATCH v4 1/5] syscalls/clone02: Convert to new API
@ 2021-10-14  1:25 zhanglianjie
  2021-10-14  1:25 ` [LTP] [PATCH v4 2/5] syscalls/clone03: " zhanglianjie
                   ` (5 more replies)
  0 siblings, 6 replies; 12+ messages in thread
From: zhanglianjie @ 2021-10-14  1:25 UTC (permalink / raw)
  To: ltp

Signed-off-by: zhanglianjie <zhanglianjie@uniontech.com>

diff --git a/testcases/kernel/syscalls/clone/clone02.c b/testcases/kernel/syscalls/clone/clone02.c
index 42eea135a..cb973fdc8 100644
--- a/testcases/kernel/syscalls/clone/clone02.c
+++ b/testcases/kernel/syscalls/clone/clone02.c
@@ -1,468 +1,227 @@
+// SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) Wipro Technologies Ltd, 2002.  All Rights Reserved.
  * Copyright (c) 2012 Wanlong Gao <gaowanlong@cn.fujitsu.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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.
- *
- * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
  */
-/*
- *	 TEST1
- *	 -----
- *		Call clone() with all resources shared.
- *
- *		CHILD:
- *			modify the shared resources
- *			return 1 on success
- *		PARENT:
- *			wait for child to finish
- *			verify that the shared resourses are modified
- *			return 1 on success
- *		If parent & child returns successfully
- *			test passed
- *		else
- *			test failed
+
+/*\
+ * [Description]
+ *   TEST1
+ * - call clone() with all resources shared.
+ * - child modify the shared resources.
+ * - parent wait for child to finish.
+ * - verify that the shared resourses are modified.
+ * - if the parent shared resource is modified, then pass.
  *
  *	 TEST2
- *	 -----
- *		Call clone() with no resources shared.
- *
- *		CHILD:
- *			modify the resources in child's address space
- *			return 1 on success
- *		PARENT:
- *			wait for child to finish
- *			verify that the parent's resourses are not modified
- *			return 1 on success
- *		If parent & child returns successfully
- *			test passed
- *		else
- *			test failed
+ * - call clone() with no resources shared.
+ * - modify the resources in child's address space.
+ * - parent wait for child to finish.
+ * - verify that the parent's resourses are not modified.
+ * - if the parent shared resource are modified, then pass.
  */

-#if defined UCLINUX && !__THROW
-/* workaround for libc bug */
-#define __THROW
-#endif
-
 #define _GNU_SOURCE

-#include <errno.h>
-#include <fcntl.h>
-#include <sys/wait.h>
-#include <sys/types.h>
-#include <sys/syscall.h>
 #include <sched.h>
-#include "test.h"
-#include "safe_macros.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "tst_test.h"
+#include "lapi/syscalls.h"
+#include "clone_platform.h"

+#define TESTFILE "testfile"
+#define TESTDIR "testdir"
 #define FLAG_ALL (CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|SIGCHLD)
 #define FLAG_NONE SIGCHLD
 #define PARENT_VALUE 1
 #define CHILD_VALUE 2
-#define TRUE 1
-#define FALSE 0
-
-#include "clone_platform.h"
-
-static void setup(void);
-static int test_setup(void);
-static void cleanup(void);
-static void test_cleanup(void);
-static int child_fn();
-static int parent_test1(void);
-static int parent_test2(void);
-static int test_VM(void);
-static int test_FS(void);
-static int test_FILES(void);
-static int test_SIG(void);
-static int modified_VM(void);
-static int modified_FS(void);
-static int modified_FILES(void);
-static int modified_SIG(void);
-static void sig_child_defined_handler(int);
-static void sig_default_handler();

 static int fd_parent;
-static char file_name[25];
 static int parent_variable;
-static char cwd_parent[FILENAME_MAX];
+static char *cwd_parent;
 static int parent_got_signal, child_pid;
-
-char *TCID = "clone02";
-
-struct test_case_t {
-	int flags;
-	int (*parent_fn) ();
-} test_cases[] = {
-	{
-	FLAG_ALL, parent_test1}, {
-	FLAG_NONE, parent_test2}
+static void *child_stack;
+static char cwd_child[FILENAME_MAX];
+
+static char *res_name[] = {
+	[1] = "CLONE_VM",
+	[2] = "CLONE_FS",
+	[4] = "CLONE_FILES",
+	[8] = "CLONE_SIGHAND",
 };

-int TST_TOTAL = sizeof(test_cases) / sizeof(test_cases[0]);
-
-int main(int ac, char **av)
-{
-
-	int lc;
-	void *child_stack;
-	int status, i;
-
-	tst_parse_opts(ac, av, NULL, NULL);
-
-	setup();
-
-	child_stack = malloc(CHILD_STACK_SIZE);
-	if (child_stack == NULL)
-		tst_brkm(TBROK, cleanup, "Cannot allocate stack for child");
-
-	for (lc = 0; TEST_LOOPING(lc); lc++) {
-		tst_count = 0;
-
-		for (i = 0; i < TST_TOTAL; ++i) {
-			if (test_setup() != 0) {
-				tst_resm(TWARN, "test_setup() failed, skipping this test case");
-				continue;
-			}
-
-			/* Test the system call */
-			TEST(ltp_clone(test_cases[i].flags, child_fn, NULL,
-				       CHILD_STACK_SIZE, child_stack));
-
-			/* check return code */
-			if (TEST_RETURN == -1) {
-				tst_resm(TFAIL | TTERRNO, "clone() failed");
-				/* Cleanup & continue with next test case */
-				test_cleanup();
-				continue;
-			}
-
-			/* Wait for child to finish */
-			if ((wait(&status)) == -1) {
-				tst_resm(TWARN | TERRNO,
-					 "wait failed; skipping testcase");
-				/* Cleanup & continue with next test case */
-				test_cleanup();
-				continue;
-			}
-
-			if (WTERMSIG(status))
-				tst_resm(TWARN, "child exitied with signal %d",
-					 WTERMSIG(status));
-
-			/*
-			 * Check the return value from child function and
-			 * parent function. If both functions returned
-			 * successfully, test passed, else failed
-			 */
-			if (WIFEXITED(status) && WEXITSTATUS(status) == 0 &&
-			    test_cases[i].parent_fn())
-				tst_resm(TPASS, "Test Passed");
-			else
-				tst_resm(TFAIL, "Test Failed");
-
-			/* Do test specific cleanup */
-			test_cleanup();
-		}
-	}
-
-	free(child_stack);
-
-	cleanup();
-	tst_exit();
-}
-
-static void setup(void)
+static void sig_child_defined_handler(int pid LTP_ATTRIBUTE_UNUSED)
 {
-	tst_sig(FORK, DEF_HANDLER, cleanup);
-	TEST_PAUSE;
-	tst_tmpdir();
-
-	/* Get unique file name for each child process */
-	if ((sprintf(file_name, "parent_file_%ld", syscall(__NR_gettid))) <= 0)
-		tst_brkm(TBROK | TERRNO, cleanup, "sprintf() failed");
+	TEST(tst_syscall(__NR_gettid));
+	if (TST_RET == child_pid)
+		tst_res(TWARN, "Child got SIGUSR2 signal");
+	else
+		parent_got_signal = 1;
 }

-static void cleanup(void)
+static void modify_resources(void)
 {
-	if (unlink(file_name) == -1)
-		tst_resm(TWARN | TERRNO, "unlink(%s) failed", file_name);
-	tst_rmdir();
-}
+	struct sigaction new_act;

-static int test_setup(void)
-{
+	parent_variable = CHILD_VALUE;

-	struct sigaction def_act;
+	close(fd_parent);

-	/* Save current working directory of parent */
-	if (getcwd(cwd_parent, sizeof(cwd_parent)) == NULL) {
-		tst_resm(TWARN | TERRNO, "getcwd() failed in test_setup()");
-		return -1;
-	}
+	SAFE_CHDIR(cwd_child);

-	/*
-	 * Set value for parent_variable in parent, which will be
-	 * changed by child in test_VM(), for testing CLONE_VM flag
-	 */
-	parent_variable = PARENT_VALUE;
+	new_act.sa_handler = sig_child_defined_handler;
+	new_act.sa_flags = SA_RESTART;
+	SAFE_SIGEMPTYSET(&new_act.sa_mask);

-	/*
-	 * Open file from parent, which will be closed by
-	 * child in test_FILES(), used for testing CLONE_FILES flag
-	 */
-	fd_parent = open(file_name, O_CREAT | O_RDWR, 0777);
-	if (fd_parent == -1) {
-		tst_resm(TWARN | TERRNO, "open() failed in test_setup()");
-		return -1;
-	}
+	SAFE_SIGACTION(SIGUSR2, &new_act, NULL);
+	SAFE_KILL(getppid(), SIGUSR2);
+}

-	/*
-	 * set parent_got_signal to FALSE, used for testing
-	 * CLONE_SIGHAND flag
-	 */
-	parent_got_signal = FALSE;
+static int verify_resources(void)
+{
+	char buff[20];
+	char cwd[FILENAME_MAX];

-	/* Setup signal handler for SIGUSR2 */
-	def_act.sa_handler = sig_default_handler;
-	def_act.sa_flags = SA_RESTART;
-	sigemptyset(&def_act.sa_mask);
+	unsigned int changed = 0;

-	if (sigaction(SIGUSR2, &def_act, NULL) == -1) {
-		tst_resm(TWARN | TERRNO, "sigaction() failed in test_setup()");
-		return -1;
-	}
+	if (parent_variable == CHILD_VALUE)
+		changed |= CLONE_VM;

-	return 0;
-}
+	if (((read(fd_parent, buff, sizeof(buff))) == -1) && (errno == EBADF))
+		changed |= CLONE_FS;
+	else
+		SAFE_CLOSE(fd_parent);

-static void test_cleanup(void)
-{
+	SAFE_GETCWD(cwd, sizeof(cwd));
+	if (strcmp(cwd, cwd_parent))
+		changed |= CLONE_FILES;

-	/* Restore parent's working directory */
-	SAFE_CHDIR(cleanup, cwd_parent);
+	if (parent_got_signal)
+		changed |= CLONE_SIGHAND;

+	return changed;
 }

-static int child_fn(void)
+static void sig_parent_default_handler(int pid LTP_ATTRIBUTE_UNUSED)
 {

-	/* save child pid */
-	child_pid = syscall(__NR_gettid);
-
-	if (test_VM() == 0 && test_FILES() == 0 && test_FS() == 0 &&
-	    test_SIG() == 0)
-		_exit(0);
-	_exit(1);
 }

-static int parent_test1(void)
+static int child_fn(void *arg LTP_ATTRIBUTE_UNUSED)
 {
+	TEST(tst_syscall(__NR_gettid));
+	child_pid = TST_RET;

-	/*
-	 * For first test case (with all flags set), all resources are
-	 * shared between parent and child. So whatever changes made by
-	 * child should get reflected in parent also. modified_*()
-	 * functions check this. All of them should return 1 for
-	 * parent_test1() to return 1
-	 */
-
-	if (modified_VM() && modified_FILES() && modified_FS() &&
-	    modified_SIG())
-		return 0;
-	return -1;
+	modify_resources();
+	_exit(0);
 }

-static int parent_test2(void)
+static void reset_resources(void)
 {
+	struct sigaction def_act;

-	/*
-	 * For second test case (with no resouce shared), all of the
-	 * modified_*() functions should return 0 for parent_test2()
-	 * to return 1
-	 */
-	if (modified_VM() || modified_FILES() || modified_FS() ||
-	    modified_SIG())
-		return 0;
+	parent_variable = PARENT_VALUE;
+	fd_parent = SAFE_OPEN(TESTFILE, O_CREAT | O_RDWR, 0777);
+	parent_got_signal = 0;
+	SAFE_CHDIR(cwd_parent);

-	return -1;
+	def_act.sa_handler = sig_parent_default_handler;
+	def_act.sa_flags = SA_RESTART;
+	SAFE_SIGEMPTYSET(&def_act.sa_mask);
+	SAFE_SIGACTION(SIGUSR2, &def_act, NULL);
 }

-/*
- * test_VM() - function to change parent_variable from child's
- *	       address space. If CLONE_VM flag is set, child shares
- *	       the memory space with parent so this will be visible
- *	       to parent also.
- */
-
-static int test_VM(void)
-{
-	parent_variable = CHILD_VALUE;
-	return 0;
-}
+struct tcase {
+	unsigned long flags;
+	char *desc;
+} tcases[] = {
+	{FLAG_ALL, "clone() with all resources shared"},
+	{FLAG_NONE, "clone() with all no resources shared"}
+};

-/*
- * test_FILES() - This function closes a file descriptor opened by
- *		  parent. If CLONE_FILES flag is set, the parent and
- *		  the child process share the same file descriptor
- *		  table. so this affects the parent also
- */
-static int test_FILES(void)
+static void verify_clone(unsigned int tc)
 {
-	if (close(fd_parent) == -1) {
-		tst_resm(TWARN | TERRNO, "close failed in test_FILES");
-		return -1;
-	}
-	return 0;
-}
+	unsigned int flag;
+	unsigned int i;

-/*
- * test_FS() -  This function changes the current working directory
- *		of the child process. If CLONE_FS flag is set, this
- *		will be visible to parent also.
- */
-static int test_FS(void)
-{
-	char *test_tmpdir;
-	int rval;
-
-	test_tmpdir = tst_get_tmpdir();
-	if (test_tmpdir == NULL) {
-		tst_resm(TWARN | TERRNO, "tst_get_tmpdir failed");
-		rval = -1;
-	} else if (chdir(test_tmpdir) == -1) {
-		tst_resm(TWARN | TERRNO, "chdir failed in test_FS");
-		rval = -1;
-	} else {
-		rval = 0;
-	}
+	tst_res(TINFO, "%s", tcases[tc].desc);

-	free(test_tmpdir);
-	return rval;
-}
+	reset_resources();

-/*
- * test_SIG() - This function changes the signal handler for SIGUSR2
- *		signal for child. If CLONE_SIGHAND flag is set, this
- *		affects parent also.
- */
-static int test_SIG(void)
-{
+	TST_EXP_PID_SILENT(ltp_clone(tcases[tc].flags, child_fn, NULL,
+				CHILD_STACK_SIZE, child_stack));

-	struct sigaction new_act;
+	if (!TST_PASS)
+		return;

-	new_act.sa_handler = sig_child_defined_handler;
-	new_act.sa_flags = SA_RESTART;
-	sigemptyset(&new_act.sa_mask);
+	tst_reap_children();

-	/* Set signal handler to sig_child_defined_handler */
-	if (sigaction(SIGUSR2, &new_act, NULL) == -1) {
-		tst_resm(TWARN | TERRNO, "signal failed in test_SIG");
-		return -1;
-	}
+	flag = verify_resources();

-	/* Send SIGUSR2 signal to parent */
-	if (kill(getppid(), SIGUSR2) == -1) {
-		tst_resm(TWARN | TERRNO, "kill failed in test_SIG");
-		return -1;
+	for (i = CLONE_VM; i <= CLONE_SIGHAND; i <<= 1) {
+		if (tcases[tc].flags == FLAG_ALL) {
+			if (flag & i)
+				tst_res(TPASS, "The resource %s of the parent process has changed", res_name[i >> 8]);
+			else
+				tst_res(TFAIL, "The resource %s of the parent process has not changed", res_name[i >> 8]);
+		} else {
+			if (flag & i)
+				tst_res(TFAIL, "The resource %s of the parent process has changed", res_name[i >> 8]);
+			else
+				tst_res(TPASS, "The resource %s of the parent process has not changed", res_name[i >> 8]);
+		}
 	}
-
-	return 0;
-}
-
-/*
- * modified_VM() - This function is called by parent process to check
- *		   whether child's modification to parent_variable
- *		   is visible to parent
- */
-
-static int modified_VM(void)
-{
-
-	if (parent_variable == CHILD_VALUE)
-		/* child has modified parent_variable */
-		return 1;
-
-	return 0;
 }

-/*
- * modified_FILES() - This function checks for file descriptor table
- *		      modifications done by child
- */
-static int modified_FILES(void)
+static void cleanup(void)
 {
-	char buff[20];
-
-	if (((read(fd_parent, buff, sizeof(buff))) == -1) && (errno == EBADF))
-		/* Child has closed this file descriptor */
-		return 1;
-
-	/* close fd_parent */
-	if ((close(fd_parent)) == -1)
-		tst_resm(TWARN | TERRNO, "close() failed in modified_FILES()");
-
-	return 0;
+	SAFE_CHDIR(cwd_parent);
+	SAFE_UNLINK(TESTFILE);
+	free(cwd_parent);
 }

-/*
- * modified_FS() - This function checks parent's current working directory
- *		   to see whether its modified by child or not.
- */
-static int modified_FS(void)
+static void setup(void)
 {
-	char cwd[FILENAME_MAX];
-
-	if ((getcwd(cwd, sizeof(cwd))) == NULL)
-		tst_resm(TWARN | TERRNO, "getcwd() failed");
-
-	if (!(strcmp(cwd, cwd_parent)))
-		/* cwd hasn't changed */
-		return 0;
-
-	return 1;
-}
+	struct sigaction def_act;

-/*
- * modified_SIG() - This function checks whether child has changed
- *		    parent's signal handler for signal, SIGUSR2
- */
-static int modified_SIG(void)
-{
+	/* Save current working directory of parent */
+	cwd_parent = tst_get_tmpdir();

-	if (parent_got_signal)
-		/*
-		 * parent came through sig_child_defined_handler()
-		 * this means child has changed parent's handler
-		 */
-		return 1;
+	/*
+	 * Set value for parent_variable in parent, which will be
+	 * changed by child for testing CLONE_VM flag
+	 */
+	parent_variable = PARENT_VALUE;

-	return 0;
-}
+	/*
+	 * Open file from parent, which will be closed by
+	 * child, used for testing CLONE_FILES flag
+	 */
+	fd_parent = SAFE_OPEN(TESTFILE, O_CREAT | O_RDWR, 0777);

-/*
- * sig_child_defined_handler()  - Signal handler installed by child
- */
-static void sig_child_defined_handler(int pid)
-{
-	if ((syscall(__NR_gettid)) == child_pid)
-		/* Child got signal, give warning */
-		tst_resm(TWARN, "Child got SIGUSR2 signal");
-	else
-		parent_got_signal = TRUE;
-}
+	/*
+	 * set parent_got_signal to 0, used for testing
+	 * CLONE_SIGHAND flag
+	 */
+	parent_got_signal = 0;

-/* sig_default_handler() - Default handler for parent */
-static void sig_default_handler(void)
-{
-}
+	def_act.sa_handler = sig_parent_default_handler;
+	def_act.sa_flags = SA_RESTART;
+	SAFE_SIGEMPTYSET(&def_act.sa_mask);
+	SAFE_SIGACTION(SIGUSR2, &def_act, NULL);
+
+	SAFE_MKDIR(TESTDIR, 0777);
+	sprintf(cwd_child, "%s/%s", cwd_parent, TESTDIR);
+}
+
+static struct tst_test test = {
+	.setup = setup,
+	.cleanup = cleanup,
+	.tcnt = ARRAY_SIZE(tcases),
+	.test = verify_clone,
+	.bufs = (struct tst_buffers []) {
+		{&child_stack, .size = CHILD_STACK_SIZE},
+	},
+	.needs_tmpdir = 1,
+};
--
2.20.1




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

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

* [LTP] [PATCH v4 2/5] syscalls/clone03: Convert to new API
  2021-10-14  1:25 [LTP] [PATCH v4 1/5] syscalls/clone02: Convert to new API zhanglianjie
@ 2021-10-14  1:25 ` zhanglianjie
  2021-10-27 12:32   ` Cyril Hrubis
  2021-10-14  1:25 ` [LTP] [PATCH v4 3/5] syscalls/clone05: " zhanglianjie
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 12+ messages in thread
From: zhanglianjie @ 2021-10-14  1:25 UTC (permalink / raw)
  To: ltp

Signed-off-by: zhanglianjie <zhanglianjie@uniontech.com>

diff --git a/testcases/kernel/syscalls/clone/clone03.c b/testcases/kernel/syscalls/clone/clone03.c
index f4216ead8..70c37d495 100644
--- a/testcases/kernel/syscalls/clone/clone03.c
+++ b/testcases/kernel/syscalls/clone/clone03.c
@@ -1,147 +1,59 @@
+// SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) Wipro Technologies Ltd, 2002.  All Rights Reserved.
  * Copyright (c) 2012 Wanlong Gao <gaowanlong@cn.fujitsu.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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.
- *
- * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
  */
-/*
+
+/*\
+ * [Description]
  *	Check for equality of pid of child & return value of clone(2)
- *	Test:
- *	 Open a pipe.
- *	 Loop if the proper options are given.
- *	  Call clone(2) called without SIGCHLD
- *
- *	  CHILD:
- *		writes the pid to pipe
- *	  PARENT:
- *		reads child'd pid from pipe
- *		if child's pid == return value from clone(2)
- *			Test passed
- *		else
- *			test failed
  */
-
-#if defined UCLINUX && !__THROW
-/* workaround for libc bug */
-#define __THROW
-#endif
-
-#include <errno.h>
-#include <sched.h>
-#include <sys/wait.h>
-#include "test.h"
-
+#include <stdio.h>
+#include <stdlib.h>
+#include "tst_test.h"
 #include "clone_platform.h"

-static void setup(void);
-static void cleanup(void);
-static int child_fn();
-
-static int pfd[2];
-
-char *TCID = "clone03";
-int TST_TOTAL = 1;
+static void *child_stack;
+static int *child_pid;

-int main(int ac, char **av)
+static int child_fn(void *arg LTP_ATTRIBUTE_UNUSED)
 {
+	*child_pid = getpid();
+	exit(0);
+}

-	int lc;
-	void *child_stack;
-	char buff[10];
-	int child_pid, status;
-
-	tst_parse_opts(ac, av, NULL, NULL);
-
-	setup();
-
-	/* Allocate stack for child */
-	child_stack = malloc(CHILD_STACK_SIZE);
-	if (child_stack == NULL)
-		tst_brkm(TBROK, cleanup, "Cannot allocate stack for child");
-
-	for (lc = 0; TEST_LOOPING(lc); lc++) {
-		tst_count = 0;
-
-		if ((pipe(pfd)) == -1)
-			tst_brkm(TBROK | TERRNO, cleanup, "pipe failed");
-
-		TEST(ltp_clone(SIGCHLD, child_fn, NULL, CHILD_STACK_SIZE,
-			       child_stack));
-
-		if (TEST_RETURN == -1)
-			tst_brkm(TFAIL | TTERRNO, cleanup, "clone() failed");
-
-		/* close write end from parent */
-		if ((close(pfd[1])) == -1)
-			tst_brkm(TBROK | TERRNO, cleanup,
-				 "close(pfd[1]) failed");
-
-		/* Read pid from read end */
-		if ((read(pfd[0], buff, sizeof(buff))) == -1)
-			tst_brkm(TBROK | TERRNO, cleanup,
-				 "read from pipe failed");
-
-		/* Close read end from parent */
-		if ((close(pfd[0])) == -1)
-			tst_resm(TWARN | TERRNO, "close(pfd[0]) failed");
-
-		/* Get child's pid from pid string */
-		child_pid = atoi(buff);
+static void verify_clone(void)
+{

-		if (TEST_RETURN == child_pid)
-			tst_resm(TPASS, "Test passed");
-		else
-			tst_resm(TFAIL, "Test failed");
+	TST_EXP_PID_SILENT(ltp_clone(SIGCHLD, child_fn, NULL, CHILD_STACK_SIZE,
+				child_stack));

-		if ((wait(&status)) == -1)
-			tst_brkm(TBROK | TERRNO, cleanup,
-				 "wait failed, status: %d", status);
-	}
+	if (!TST_PASS)
+		return;

-	free(child_stack);
+	tst_reap_children();

-	cleanup();
-	tst_exit();
+	TST_EXP_VAL(TST_RET, *child_pid, "pid(%d)", *child_pid);
 }

 static void setup(void)
 {
-	tst_sig(FORK, DEF_HANDLER, cleanup);
-	TEST_PAUSE;
+	child_pid = SAFE_MMAP(NULL, sizeof(*child_pid), PROT_READ | PROT_WRITE,
+				MAP_SHARED | MAP_ANONYMOUS, -1, 0);
 }

 static void cleanup(void)
 {
+	if (child_pid)
+		SAFE_MUNMAP(child_pid, sizeof(*child_pid));
 }

-static int child_fn(void)
-{
-	char pid[10];
-
-	/* Close read end from child */
-	if ((close(pfd[0])) == -1)
-		perror("close(pfd[0]) failed");
-
-	sprintf(pid, "%d", getpid());
-
-	/* Write pid string to pipe */
-	if ((write(pfd[1], pid, sizeof(pid))) == -1)
-		perror("write to pipe failed");
-
-	/* Close write end of pipe from child */
-	if ((close(pfd[1])) == -1)
-		perror("close(pfd[1]) failed");
-
-	exit(1);
-}
+static struct tst_test test = {
+	.setup = setup,
+	.test_all = verify_clone,
+	.bufs = (struct tst_buffers []) {
+		{&child_stack, .size = CHILD_STACK_SIZE},
+		{},
+	},
+	.cleanup = cleanup,
+};
--
2.20.1




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

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

* [LTP] [PATCH v4 3/5] syscalls/clone05: Convert to new API
  2021-10-14  1:25 [LTP] [PATCH v4 1/5] syscalls/clone02: Convert to new API zhanglianjie
  2021-10-14  1:25 ` [LTP] [PATCH v4 2/5] syscalls/clone03: " zhanglianjie
@ 2021-10-14  1:25 ` zhanglianjie
  2021-10-27 12:52   ` Cyril Hrubis
  2021-10-14  1:25 ` [LTP] [PATCH v4 4/5] syscalls/clone06: " zhanglianjie
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 12+ messages in thread
From: zhanglianjie @ 2021-10-14  1:25 UTC (permalink / raw)
  To: ltp

Signed-off-by: zhanglianjie <zhanglianjie@uniontech.com>

diff --git a/testcases/kernel/syscalls/clone/clone05.c b/testcases/kernel/syscalls/clone/clone05.c
index 494b772dd..69816ece6 100644
--- a/testcases/kernel/syscalls/clone/clone05.c
+++ b/testcases/kernel/syscalls/clone/clone05.c
@@ -1,103 +1,56 @@
+// SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) Wipro Technologies Ltd, 2002.  All Rights Reserved.
  * Copyright (c) 2012 Wanlong Gao <gaowanlong@cn.fujitsu.com>
  * Copyright (c) 2012 Cyril Hrubis <chrubis@suse.cz>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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.
- *
- * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
  */

-/*
+/*\
+ * [Description]
  * Call clone() with CLONE_VFORK flag set. verify that
  * execution of parent is suspended until child finishes
  */

 #define _GNU_SOURCE

-#include <errno.h>
+#include <stdlib.h>
 #include <sched.h>
-#include <sys/wait.h>
-#include "test.h"
+#include "tst_test.h"
 #include "clone_platform.h"

-char *TCID = "clone05";
-int TST_TOTAL = 1;
-
-static void setup(void);
-static void cleanup(void);
-static int child_fn(void *);
+static volatile int child_exited;
+static void *child_stack;

-static int child_exited = 0;
-
-int main(int ac, char **av)
+static int child_fn(void *unused LTP_ATTRIBUTE_UNUSED)
 {
+	int i;

-	int lc, status;
-	void *child_stack;
-
-	tst_parse_opts(ac, av, NULL, NULL);
-
-	setup();
-
-	child_stack = malloc(CHILD_STACK_SIZE);
-	if (child_stack == NULL)
-		tst_brkm(TBROK, cleanup, "Cannot allocate stack for child");
-
-	for (lc = 0; TEST_LOOPING(lc); lc++) {
-		tst_count = 0;
-
-		TEST(ltp_clone(CLONE_VM | CLONE_VFORK | SIGCHLD, child_fn, NULL,
-		               CHILD_STACK_SIZE, child_stack));
-
-		if ((TEST_RETURN != -1) && (child_exited))
-			tst_resm(TPASS, "Test Passed");
-		else
-			tst_resm(TFAIL, "Test Failed");
-
-		if ((wait(&status)) == -1)
-			tst_brkm(TBROK | TERRNO, cleanup,
-				 "wait failed, status: %d", status);
-
-		child_exited = 0;
+	for (i = 0; i < 100; i++) {
+		sched_yield();
+		usleep(1000);
 	}

-	free(child_stack);
-
-	cleanup();
-	tst_exit();
+	child_exited = 1;
+	_exit(0);
 }

-static void setup(void)
+static void verify_clone(void)
 {
-	tst_sig(FORK, DEF_HANDLER, cleanup);
+	child_exited = 0;
+
+	TST_EXP_PID_SILENT(ltp_clone(CLONE_VM | CLONE_VFORK | SIGCHLD, child_fn, NULL,
+					CHILD_STACK_SIZE, child_stack), "clone with vfork");

-	TEST_PAUSE;
-}
+	if (!TST_PASS)
+		return;

-static void cleanup(void)
-{
+	TST_EXP_VAL(child_exited, 1);
 }

-static int child_fn(void *unused __attribute__((unused)))
-{
-	int i;
-
-	/* give the kernel scheduler chance to run the parent */
-	for (i = 0; i < 100; i++) {
-		sched_yield();
-		usleep(1000);
-	}
-
-	child_exited = 1;
-	_exit(1);
-}
+static struct tst_test test = {
+	.test_all = verify_clone,
+	.bufs = (struct tst_buffers []) {
+		{&child_stack, .size = CHILD_STACK_SIZE},
+		{},
+	},
+};
--
2.20.1




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

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

* [LTP] [PATCH v4 4/5] syscalls/clone06: Convert to new API
  2021-10-14  1:25 [LTP] [PATCH v4 1/5] syscalls/clone02: Convert to new API zhanglianjie
  2021-10-14  1:25 ` [LTP] [PATCH v4 2/5] syscalls/clone03: " zhanglianjie
  2021-10-14  1:25 ` [LTP] [PATCH v4 3/5] syscalls/clone05: " zhanglianjie
@ 2021-10-14  1:25 ` zhanglianjie
  2021-10-27 13:26   ` Cyril Hrubis
  2021-10-14  1:25 ` [LTP] [PATCH v4 5/5] syscalls/clone07: " zhanglianjie
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 12+ messages in thread
From: zhanglianjie @ 2021-10-14  1:25 UTC (permalink / raw)
  To: ltp

Signed-off-by: zhanglianjie <zhanglianjie@uniontech.com>

diff --git a/testcases/kernel/syscalls/clone/clone06.c b/testcases/kernel/syscalls/clone/clone06.c
index 99e7f3864..8337b5d90 100644
--- a/testcases/kernel/syscalls/clone/clone06.c
+++ b/testcases/kernel/syscalls/clone/clone06.c
@@ -1,140 +1,65 @@
+// SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) Wipro Technologies Ltd, 2002.  All Rights Reserved.
  * Copyright (c) 2012 Wanlong Gao <gaowanlong@cn.fujitsu.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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.
- *
- * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
  */

-/*
- *	Test to verify inheritance of environment variables by child.
+/*\
+ * [Description]
+ * Test to verify inheritance of environment variables by child.
  */

-#if defined UCLINUX && !__THROW
-/* workaround for libc bug */
-#define __THROW
-#endif
-
-#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
 #include <sched.h>
-#include <sys/wait.h>
-#include <fcntl.h>
-#include "test.h"
+#include "tst_test.h"
 #include "clone_platform.h"

 #define MAX_LINE_LENGTH 256
+#define ENV_VAL "LTP test variable value"
+#define ENV_ID "LTP_CLONE_TEST"

-static void setup(void);
-static void cleanup(void);
-static int child_environ();
-
-static int pfd[2];
+static void *child_stack;

-char *TCID = "clone06";
-int TST_TOTAL = 1;
-
-int main(int ac, char **av)
+static int child_environ(void *arg LTP_ATTRIBUTE_UNUSED)
 {
-
-	int lc, status;
-	void *child_stack;
-	char *parent_env;
-	char buff[MAX_LINE_LENGTH];
-
-	tst_parse_opts(ac, av, NULL, NULL);
-
-	setup();
-
-	child_stack = malloc(CHILD_STACK_SIZE);
-	if (child_stack == NULL)
-		tst_brkm(TBROK, cleanup, "Cannot allocate stack for child");
-
-	for (lc = 0; TEST_LOOPING(lc); lc++) {
-		tst_count = 0;
-
-		if ((pipe(pfd)) == -1)
-			tst_brkm(TBROK | TERRNO, cleanup, "pipe() failed");
-
-		TEST(ltp_clone(SIGCHLD, child_environ, NULL, CHILD_STACK_SIZE,
-			       child_stack));
-
-		if (TEST_RETURN == -1)
-			tst_brkm(TFAIL | TTERRNO, cleanup, "clone failed");
-
-		/* close write end from parent */
-		if ((close(pfd[1])) == -1)
-			tst_resm(TWARN | TERRNO, "close(pfd[1]) failed");
-
-		/* Read env var from read end */
-		if ((read(pfd[0], buff, sizeof(buff))) == -1)
-			tst_brkm(TBROK | TERRNO, cleanup,
-				 "read from pipe failed");
-
-		/* Close read end from parent */
-		if ((close(pfd[0])) == -1)
-			tst_resm(TWARN | TERRNO, "close(pfd[0]) failed");
-
-		parent_env = getenv("TERM") ? : "";
-
-		if ((strcmp(buff, parent_env)) == 0)
-			tst_resm(TPASS, "Test Passed");
-		else
-			tst_resm(TFAIL, "Test Failed");
-
-		if ((wait(&status)) == -1)
-			tst_brkm(TBROK | TERRNO, cleanup,
-				 "wait failed, status: %d", status);
+	const char *env_val = getenv(ENV_ID);
+	if (!env_val) {
+		tst_res(TFAIL, "Variable " ENV_ID " not defined in child");
+		exit(-1);
 	}

-	free(child_stack);
+	if (strcmp(env_val, ENV_VAL)) {
+		tst_res(TFAIL, "Variable value is different");
+		exit(-1);
+	}
+
+	tst_res(TPASS, "The environment variables of the child and the parent are the same ");

-	cleanup();
-	tst_exit();
+	exit(0);
 }

-static void setup(void)
+static void verify_clone(void)
 {
-	tst_sig(FORK, DEF_HANDLER, cleanup);
-	TEST_PAUSE;
-}
+	TST_EXP_PID_SILENT(ltp_clone(SIGCHLD, child_environ, NULL, CHILD_STACK_SIZE,
+				child_stack));

-static void cleanup(void)
-{
+	if (!TST_PASS)
+		return;
+
+	tst_reap_children();
 }

-/*
- *	Function executed by child.
- *	Gets the value for environment variable,TERM &
- *	writes it to  a pipe.
- */
-static int child_environ(void)
+static void setup(void)
 {
-
-	char var[MAX_LINE_LENGTH];
-
-	/* Close read end from child */
-	if ((close(pfd[0])) == -1)
-		tst_brkm(TBROK | TERRNO, cleanup, "close(pfd[0]) failed");
-
-	if ((sprintf(var, "%s", getenv("TERM") ? : "")) < 0)
-		tst_resm(TWARN | TERRNO, "sprintf() failed");
-
-	if ((write(pfd[1], var, MAX_LINE_LENGTH)) == -1)
-		tst_resm(TWARN | TERRNO, "write to pipe failed");
-
-	/* Close write end of pipe from child */
-	if ((close(pfd[1])) == -1)
-		tst_resm(TWARN | TERRNO, "close(pfd[1]) failed");
-
-	exit(0);
+	SAFE_SETENV(ENV_ID, ENV_VAL, 0);
 }
+
+static struct tst_test test = {
+	.setup = setup,
+	.test_all = verify_clone,
+	.bufs = (struct tst_buffers []) {
+		{&child_stack, .size = CHILD_STACK_SIZE},
+		{},
+	},
+};
--
2.20.1




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

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

* [LTP] [PATCH v4 5/5] syscalls/clone07: Convert to new API
  2021-10-14  1:25 [LTP] [PATCH v4 1/5] syscalls/clone02: Convert to new API zhanglianjie
                   ` (2 preceding siblings ...)
  2021-10-14  1:25 ` [LTP] [PATCH v4 4/5] syscalls/clone06: " zhanglianjie
@ 2021-10-14  1:25 ` zhanglianjie
  2021-10-27 13:40   ` Cyril Hrubis
  2021-10-15  9:57 ` [LTP] [PATCH v4 1/5] syscalls/clone02: " Petr Vorel
  2021-10-27 12:00 ` Cyril Hrubis
  5 siblings, 1 reply; 12+ messages in thread
From: zhanglianjie @ 2021-10-14  1:25 UTC (permalink / raw)
  To: ltp

Signed-off-by: zhanglianjie <zhanglianjie@uniontech.com>

diff --git a/testcases/kernel/syscalls/clone/clone07.c b/testcases/kernel/syscalls/clone/clone07.c
index 4b2e04ee7..2c5931907 100644
--- a/testcases/kernel/syscalls/clone/clone07.c
+++ b/testcases/kernel/syscalls/clone/clone07.c
@@ -1,128 +1,55 @@
+// SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) International Business Machines  Corp., 2003.
  * Copyright (c) 2012 Wanlong Gao <gaowanlong@cn.fujitsu.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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.
- *
- * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-/*
- *	This is a test for a glibc bug for the clone(2) system call.
  */

-#if defined UCLINUX && !__THROW
-/* workaround for libc bug */
-#define __THROW
-#endif
+/*\
+ * [Description]
+ * Test for a libc bug where exitting child function by returning from
+ * it caused SIGSEGV.
+ */

-#include <errno.h>
 #include <sched.h>
-#include <sys/wait.h>
-#include "test.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "tst_test.h"
+#include "lapi/syscalls.h"
 #include "clone_platform.h"

-#define TRUE 1
-#define FALSE 0
-
-static void setup();
-static int do_child();
+static void *child_stack;

-char *TCID = "clone07";
-int TST_TOTAL = 1;
-
-static void sigsegv_handler(int);
-static void sigusr2_handler(int);
-static int child_pid;
-static int fail = FALSE;
-
-int main(int ac, char **av)
+static int do_child(void *arg LTP_ATTRIBUTE_UNUSED)
 {
-
-	int lc, status;
-	void *child_stack;
-
-	tst_parse_opts(ac, av, NULL, NULL);
-
-	setup();
-
-	for (lc = 0; TEST_LOOPING(lc); lc++) {
-		tst_count = 0;
-		child_stack = malloc(CHILD_STACK_SIZE);
-		if (child_stack == NULL)
-			tst_brkm(TBROK, NULL,
-				 "Cannot allocate stack for child");
-
-		child_pid = ltp_clone(SIGCHLD, do_child, NULL,
-				      CHILD_STACK_SIZE, child_stack);
-
-		if (child_pid < 0)
-			tst_brkm(TBROK | TERRNO, NULL, "clone failed");
-
-		if ((wait(&status)) == -1)
-			tst_brkm(TBROK | TERRNO, NULL,
-				 "wait failed, status: %d", status);
-
-		free(child_stack);
-	}
-
-	if (fail == FALSE)
-		tst_resm(TPASS,
-			 "Use of return() in child did not cause SIGSEGV");
-	else
-		tst_resm(TFAIL, "Use of return() in child caused SIGSEGV");
-
-	tst_exit();
+	return 0;
 }

-static void setup(void)
+static void verify_clone(void)
 {
-	struct sigaction def_act;
-	struct sigaction act;
+	int status;
+	pid_t pid = 0;

-	TEST_PAUSE;
+	TST_EXP_PID_SILENT(ltp_clone(SIGCHLD, do_child, NULL, CHILD_STACK_SIZE,
+				child_stack));

-	act.sa_handler = sigsegv_handler;
-	act.sa_flags = SA_RESTART;
-	sigemptyset(&act.sa_mask);
-	if ((sigaction(SIGSEGV, &act, NULL)) == -1)
-		tst_resm(TWARN | TERRNO,
-			 "sigaction() for SIGSEGV failed in test_setup()");
+	if (!TST_PASS)
+		return;

-	/* Setup signal handler for SIGUSR2 */
-	def_act.sa_handler = sigusr2_handler;
-	def_act.sa_flags = SA_RESTART | SA_RESETHAND;
-	sigemptyset(&def_act.sa_mask);
+	SAFE_WAITPID(pid, &status, 0);

-	if ((sigaction(SIGUSR2, &def_act, NULL)) == -1)
-		tst_resm(TWARN | TERRNO,
-			 "sigaction() for SIGUSR2 failed in test_setup()");
-}
-
-static int do_child(void)
-{
-	return 0;
-}
+	if (WIFEXITED(status) && WEXITSTATUS(status) == 0)
+		tst_res(TPASS, "Using return() in child will not cause abnormal exit");
+	else
+		tst_res(TFAIL, "Using return() in child will cause abnormal exit");

-static void sigsegv_handler(int sig)
-{
-	if (child_pid == 0) {
-		kill(getppid(), SIGUSR2);
-		_exit(42);
-	}
+	if (WIFSIGNALED(status) && WTERMSIG(status) == SIGSEGV)
+		tst_res(TFAIL, "Use of return() in child caused SIGSEGV");
 }

-/* sig_default_handler() - Default handler for parent */
-static void sigusr2_handler(int sig)
-{
-	if (child_pid != 0)
-		fail = TRUE;
-}
+static struct tst_test test = {
+	.test_all = verify_clone,
+	.bufs = (struct tst_buffers []) {
+		{&child_stack, .size = CHILD_STACK_SIZE},
+		{},
+	},
+};
--
2.20.1




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

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

* Re: [LTP] [PATCH v4 1/5] syscalls/clone02: Convert to new API
  2021-10-14  1:25 [LTP] [PATCH v4 1/5] syscalls/clone02: Convert to new API zhanglianjie
                   ` (3 preceding siblings ...)
  2021-10-14  1:25 ` [LTP] [PATCH v4 5/5] syscalls/clone07: " zhanglianjie
@ 2021-10-15  9:57 ` Petr Vorel
  2021-10-16 13:07   ` zhanglianjie
  2021-10-27 12:00 ` Cyril Hrubis
  5 siblings, 1 reply; 12+ messages in thread
From: Petr Vorel @ 2021-10-15  9:57 UTC (permalink / raw)
  To: zhanglianjie; +Cc: ltp

Hi,

> +++ b/testcases/kernel/syscalls/clone/clone02.c
...
> +static char *res_name[] = {
> +	[1] = "CLONE_VM",
> +	[2] = "CLONE_FS",
> +	[4] = "CLONE_FILES",
> +	[8] = "CLONE_SIGHAND",
>  };

Not really that important, but you could
1) Instead of hardwired indexes use constants from <sched.h>.
2) To get their string values with macro stringification.

#define CLONE_DESC(x) [x] = #x

static char *res_name[] = {
	CLONE_DESC(CLONE_VM),
	CLONE_DESC(CLONE_FS),
	CLONE_DESC(CLONE_FILES),
	CLONE_DESC(CLONE_SIGHAND),
};

If this is the only change, it can be replaced during merge.

Kind regards,
Petr

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

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

* Re: [LTP] [PATCH v4 1/5] syscalls/clone02: Convert to new API
  2021-10-15  9:57 ` [LTP] [PATCH v4 1/5] syscalls/clone02: " Petr Vorel
@ 2021-10-16 13:07   ` zhanglianjie
  0 siblings, 0 replies; 12+ messages in thread
From: zhanglianjie @ 2021-10-16 13:07 UTC (permalink / raw)
  To: Petr Vorel; +Cc: ltp

Hi,
This is great, thanks.

在 2021/10/15 17:57, Petr Vorel 写道:
> Hi,
> 
>> +++ b/testcases/kernel/syscalls/clone/clone02.c
> ...
>> +static char *res_name[] = {
>> +	[1] = "CLONE_VM",
>> +	[2] = "CLONE_FS",
>> +	[4] = "CLONE_FILES",
>> +	[8] = "CLONE_SIGHAND",
>>   };
> 
> Not really that important, but you could
> 1) Instead of hardwired indexes use constants from <sched.h>.
> 2) To get their string values with macro stringification.
> 
> #define CLONE_DESC(x) [x] = #x
> 
> static char *res_name[] = {
> 	CLONE_DESC(CLONE_VM),
> 	CLONE_DESC(CLONE_FS),
> 	CLONE_DESC(CLONE_FILES),
> 	CLONE_DESC(CLONE_SIGHAND),
> };
> 
> If this is the only change, it can be replaced during merge.
> 
> Kind regards,
> Petr
> 

-- 
Regards,
Zhang Lianjie



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

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

* Re: [LTP] [PATCH v4 1/5] syscalls/clone02: Convert to new API
  2021-10-14  1:25 [LTP] [PATCH v4 1/5] syscalls/clone02: Convert to new API zhanglianjie
                   ` (4 preceding siblings ...)
  2021-10-15  9:57 ` [LTP] [PATCH v4 1/5] syscalls/clone02: " Petr Vorel
@ 2021-10-27 12:00 ` Cyril Hrubis
  5 siblings, 0 replies; 12+ messages in thread
From: Cyril Hrubis @ 2021-10-27 12:00 UTC (permalink / raw)
  To: zhanglianjie; +Cc: ltp

Hi!
> +/*\
> + * [Description]

Ideally we should put one empty line after the description.

> + *   TEST1

And this could be slightly better described than TEST1, something as:

/*\
 * [Description]
 *
 * clone() share all test
 *
 * - call clone() with all resources shared
 * ...
 *
 * clone() share none test
 *
 * - call clone() no resources shared
 * ...
 */

> + * - call clone() with all resources shared.
> + * - child modify the shared resources.
> + * - parent wait for child to finish.
> + * - verify that the shared resourses are modified.
> + * - if the parent shared resource is modified, then pass.
>   *	 TEST2
> - *	 -----
> - *		Call clone() with no resources shared.
> - *
> - *		CHILD:
> - *			modify the resources in child's address space
> - *			return 1 on success
> - *		PARENT:
> - *			wait for child to finish
> - *			verify that the parent's resourses are not modified
> - *			return 1 on success
> - *		If parent & child returns successfully
> - *			test passed
> - *		else
> - *			test failed
> + * - call clone() with no resources shared.
> + * - modify the resources in child's address space.
> + * - parent wait for child to finish.
> + * - verify that the parent's resourses are not modified.
> + * - if the parent shared resource are modified, then pass.
                 ^
This is actually wrong, this case passes if resources are not modified

Also we can omit the last sentence completely in both cases it does not
add anything over the line that says "- verify ..."


>   */
> 
> -#if defined UCLINUX && !__THROW
> -/* workaround for libc bug */
> -#define __THROW
> -#endif
> -
>  #define _GNU_SOURCE
> 
> -#include <errno.h>
> -#include <fcntl.h>
> -#include <sys/wait.h>
> -#include <sys/types.h>
> -#include <sys/syscall.h>
>  #include <sched.h>
> -#include "test.h"
> -#include "safe_macros.h"
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include "tst_test.h"
> +#include "lapi/syscalls.h"
> +#include "clone_platform.h"
> 
> +#define TESTFILE "testfile"
> +#define TESTDIR "testdir"
>  #define FLAG_ALL (CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|SIGCHLD)
>  #define FLAG_NONE SIGCHLD
>  #define PARENT_VALUE 1
>  #define CHILD_VALUE 2
> -#define TRUE 1
> -#define FALSE 0
> -
> -#include "clone_platform.h"
> -
> -static void setup(void);
> -static int test_setup(void);
> -static void cleanup(void);
> -static void test_cleanup(void);
> -static int child_fn();
> -static int parent_test1(void);
> -static int parent_test2(void);
> -static int test_VM(void);
> -static int test_FS(void);
> -static int test_FILES(void);
> -static int test_SIG(void);
> -static int modified_VM(void);
> -static int modified_FS(void);
> -static int modified_FILES(void);
> -static int modified_SIG(void);
> -static void sig_child_defined_handler(int);
> -static void sig_default_handler();
> 
>  static int fd_parent;
> -static char file_name[25];
>  static int parent_variable;
> -static char cwd_parent[FILENAME_MAX];
> +static char *cwd_parent;
>  static int parent_got_signal, child_pid;
> -
> -char *TCID = "clone02";
> -
> -struct test_case_t {
> -	int flags;
> -	int (*parent_fn) ();
> -} test_cases[] = {
> -	{
> -	FLAG_ALL, parent_test1}, {
> -	FLAG_NONE, parent_test2}
> +static void *child_stack;
> +static char cwd_child[FILENAME_MAX];
> +
> +static char *res_name[] = {
> +	[1] = "CLONE_VM",
> +	[2] = "CLONE_FS",
> +	[4] = "CLONE_FILES",
> +	[8] = "CLONE_SIGHAND",
>  };
> 
> -int TST_TOTAL = sizeof(test_cases) / sizeof(test_cases[0]);
> -
> -int main(int ac, char **av)
> -{
> -
> -	int lc;
> -	void *child_stack;
> -	int status, i;
> -
> -	tst_parse_opts(ac, av, NULL, NULL);
> -
> -	setup();
> -
> -	child_stack = malloc(CHILD_STACK_SIZE);
> -	if (child_stack == NULL)
> -		tst_brkm(TBROK, cleanup, "Cannot allocate stack for child");
> -
> -	for (lc = 0; TEST_LOOPING(lc); lc++) {
> -		tst_count = 0;
> -
> -		for (i = 0; i < TST_TOTAL; ++i) {
> -			if (test_setup() != 0) {
> -				tst_resm(TWARN, "test_setup() failed, skipping this test case");
> -				continue;
> -			}
> -
> -			/* Test the system call */
> -			TEST(ltp_clone(test_cases[i].flags, child_fn, NULL,
> -				       CHILD_STACK_SIZE, child_stack));
> -
> -			/* check return code */
> -			if (TEST_RETURN == -1) {
> -				tst_resm(TFAIL | TTERRNO, "clone() failed");
> -				/* Cleanup & continue with next test case */
> -				test_cleanup();
> -				continue;
> -			}
> -
> -			/* Wait for child to finish */
> -			if ((wait(&status)) == -1) {
> -				tst_resm(TWARN | TERRNO,
> -					 "wait failed; skipping testcase");
> -				/* Cleanup & continue with next test case */
> -				test_cleanup();
> -				continue;
> -			}
> -
> -			if (WTERMSIG(status))
> -				tst_resm(TWARN, "child exitied with signal %d",
> -					 WTERMSIG(status));
> -
> -			/*
> -			 * Check the return value from child function and
> -			 * parent function. If both functions returned
> -			 * successfully, test passed, else failed
> -			 */
> -			if (WIFEXITED(status) && WEXITSTATUS(status) == 0 &&
> -			    test_cases[i].parent_fn())
> -				tst_resm(TPASS, "Test Passed");
> -			else
> -				tst_resm(TFAIL, "Test Failed");
> -
> -			/* Do test specific cleanup */
> -			test_cleanup();
> -		}
> -	}
> -
> -	free(child_stack);
> -
> -	cleanup();
> -	tst_exit();
> -}
> -
> -static void setup(void)
> +static void sig_child_defined_handler(int pid LTP_ATTRIBUTE_UNUSED)
>  {
> -	tst_sig(FORK, DEF_HANDLER, cleanup);
> -	TEST_PAUSE;
> -	tst_tmpdir();
> -
> -	/* Get unique file name for each child process */
> -	if ((sprintf(file_name, "parent_file_%ld", syscall(__NR_gettid))) <= 0)
> -		tst_brkm(TBROK | TERRNO, cleanup, "sprintf() failed");
> +	TEST(tst_syscall(__NR_gettid));

There is no point in using the TEST() macro here, we do not need to save
the errno at all, just do:

	int tid = tst_syscall(__NR_gettid);

> +	if (TST_RET == child_pid)
> +		tst_res(TWARN, "Child got SIGUSR2 signal");
> +	else
> +		parent_got_signal = 1;
>  }
> 
> -static void cleanup(void)
> +static void modify_resources(void)
>  {
> -	if (unlink(file_name) == -1)
> -		tst_resm(TWARN | TERRNO, "unlink(%s) failed", file_name);
> -	tst_rmdir();
> -}
> +	struct sigaction new_act;
> 
> -static int test_setup(void)
> -{
> +	parent_variable = CHILD_VALUE;
> 
> -	struct sigaction def_act;
> +	close(fd_parent);

Please use SAFE_CLOSE() here as well. The SAFE_CLOSE() also sets the fd
to -1 after it has been closed so we can use this to detect that the
file have been closed in the reset_resource();

> -	/* Save current working directory of parent */
> -	if (getcwd(cwd_parent, sizeof(cwd_parent)) == NULL) {
> -		tst_resm(TWARN | TERRNO, "getcwd() failed in test_setup()");
> -		return -1;
> -	}
> +	SAFE_CHDIR(cwd_child);
> 
> -	/*
> -	 * Set value for parent_variable in parent, which will be
> -	 * changed by child in test_VM(), for testing CLONE_VM flag
> -	 */
> -	parent_variable = PARENT_VALUE;
> +	new_act.sa_handler = sig_child_defined_handler;
> +	new_act.sa_flags = SA_RESTART;
> +	SAFE_SIGEMPTYSET(&new_act.sa_mask);
> 
> -	/*
> -	 * Open file from parent, which will be closed by
> -	 * child in test_FILES(), used for testing CLONE_FILES flag
> -	 */
> -	fd_parent = open(file_name, O_CREAT | O_RDWR, 0777);
> -	if (fd_parent == -1) {
> -		tst_resm(TWARN | TERRNO, "open() failed in test_setup()");
> -		return -1;
> -	}
> +	SAFE_SIGACTION(SIGUSR2, &new_act, NULL);
> +	SAFE_KILL(getppid(), SIGUSR2);
> +}
> 
> -	/*
> -	 * set parent_got_signal to FALSE, used for testing
> -	 * CLONE_SIGHAND flag
> -	 */
> -	parent_got_signal = FALSE;
> +static int verify_resources(void)
> +{
> +	char buff[20];
> +	char cwd[FILENAME_MAX];
> 
> -	/* Setup signal handler for SIGUSR2 */
> -	def_act.sa_handler = sig_default_handler;
> -	def_act.sa_flags = SA_RESTART;
> -	sigemptyset(&def_act.sa_mask);
> +	unsigned int changed = 0;
> 
> -	if (sigaction(SIGUSR2, &def_act, NULL) == -1) {
> -		tst_resm(TWARN | TERRNO, "sigaction() failed in test_setup()");
> -		return -1;
> -	}
> +	if (parent_variable == CHILD_VALUE)
> +		changed |= CLONE_VM;
> 
> -	return 0;
> -}
> +	if (((read(fd_parent, buff, sizeof(buff))) == -1) && (errno == EBADF))
> +		changed |= CLONE_FS;
> +	else
> +		SAFE_CLOSE(fd_parent);
> 
> -static void test_cleanup(void)
> -{
> +	SAFE_GETCWD(cwd, sizeof(cwd));
> +	if (strcmp(cwd, cwd_parent))
> +		changed |= CLONE_FILES;
> 
> -	/* Restore parent's working directory */
> -	SAFE_CHDIR(cleanup, cwd_parent);
> +	if (parent_got_signal)
> +		changed |= CLONE_SIGHAND;
> 
> +	return changed;
>  }
> 
> -static int child_fn(void)
> +static void sig_parent_default_handler(int pid LTP_ATTRIBUTE_UNUSED)
>  {
> 
> -	/* save child pid */
> -	child_pid = syscall(__NR_gettid);
> -
> -	if (test_VM() == 0 && test_FILES() == 0 && test_FS() == 0 &&
> -	    test_SIG() == 0)
> -		_exit(0);
> -	_exit(1);
>  }
> 
> -static int parent_test1(void)
> +static int child_fn(void *arg LTP_ATTRIBUTE_UNUSED)
>  {
> +	TEST(tst_syscall(__NR_gettid));
> +	child_pid = TST_RET;

Here as well, just do:

	child_pid = tst_syscall(__NR_gettid);

> -	/*
> -	 * For first test case (with all flags set), all resources are
> -	 * shared between parent and child. So whatever changes made by
> -	 * child should get reflected in parent also. modified_*()
> -	 * functions check this. All of them should return 1 for
> -	 * parent_test1() to return 1
> -	 */
> -
> -	if (modified_VM() && modified_FILES() && modified_FS() &&
> -	    modified_SIG())
> -		return 0;
> -	return -1;
> +	modify_resources();
> +	_exit(0);
>  }
> 
> -static int parent_test2(void)
> +static void reset_resources(void)
>  {
> +	struct sigaction def_act;
> 
> -	/*
> -	 * For second test case (with no resouce shared), all of the
> -	 * modified_*() functions should return 0 for parent_test2()
> -	 * to return 1
> -	 */
> -	if (modified_VM() || modified_FILES() || modified_FS() ||
> -	    modified_SIG())
> -		return 0;
> +	parent_variable = PARENT_VALUE;
> +	fd_parent = SAFE_OPEN(TESTFILE, O_CREAT | O_RDWR, 0777);

I guess that we may as well drop the SAFE_CLOSE() from the
verify_resouce() and reopen the fd only when it was actually closed.

If we use SAFE_CLOSE() in the child we can simply check if the fd is
valid with:

	if (fd_parent <= 0)
		fd_parent = SAFE_OPEN(...);

> +	parent_got_signal = 0;
> +	SAFE_CHDIR(cwd_parent);
> 
> -	return -1;
> +	def_act.sa_handler = sig_parent_default_handler;
> +	def_act.sa_flags = SA_RESTART;
> +	SAFE_SIGEMPTYSET(&def_act.sa_mask);
> +	SAFE_SIGACTION(SIGUSR2, &def_act, NULL);
>  }
> 
> -/*
> - * test_VM() - function to change parent_variable from child's
> - *	       address space. If CLONE_VM flag is set, child shares
> - *	       the memory space with parent so this will be visible
> - *	       to parent also.
> - */
> -
> -static int test_VM(void)
> -{
> -	parent_variable = CHILD_VALUE;
> -	return 0;
> -}
> +struct tcase {
> +	unsigned long flags;
> +	char *desc;
> +} tcases[] = {
> +	{FLAG_ALL, "clone() with all resources shared"},
> +	{FLAG_NONE, "clone() with all no resources shared"}
> +};
> 
> -/*
> - * test_FILES() - This function closes a file descriptor opened by
> - *		  parent. If CLONE_FILES flag is set, the parent and
> - *		  the child process share the same file descriptor
> - *		  table. so this affects the parent also
> - */
> -static int test_FILES(void)
> +static void verify_clone(unsigned int tc)
>  {
> -	if (close(fd_parent) == -1) {
> -		tst_resm(TWARN | TERRNO, "close failed in test_FILES");
> -		return -1;
> -	}
> -	return 0;
> -}
> +	unsigned int flag;
> +	unsigned int i;
> 
> -/*
> - * test_FS() -  This function changes the current working directory
> - *		of the child process. If CLONE_FS flag is set, this
> - *		will be visible to parent also.
> - */
> -static int test_FS(void)
> -{
> -	char *test_tmpdir;
> -	int rval;
> -
> -	test_tmpdir = tst_get_tmpdir();
> -	if (test_tmpdir == NULL) {
> -		tst_resm(TWARN | TERRNO, "tst_get_tmpdir failed");
> -		rval = -1;
> -	} else if (chdir(test_tmpdir) == -1) {
> -		tst_resm(TWARN | TERRNO, "chdir failed in test_FS");
> -		rval = -1;
> -	} else {
> -		rval = 0;
> -	}
> +	tst_res(TINFO, "%s", tcases[tc].desc);
> 
> -	free(test_tmpdir);
> -	return rval;
> -}
> +	reset_resources();
> 
> -/*
> - * test_SIG() - This function changes the signal handler for SIGUSR2
> - *		signal for child. If CLONE_SIGHAND flag is set, this
> - *		affects parent also.
> - */
> -static int test_SIG(void)
> -{
> +	TST_EXP_PID_SILENT(ltp_clone(tcases[tc].flags, child_fn, NULL,
> +				CHILD_STACK_SIZE, child_stack));
> 
> -	struct sigaction new_act;
> +	if (!TST_PASS)
> +		return;
> 
> -	new_act.sa_handler = sig_child_defined_handler;
> -	new_act.sa_flags = SA_RESTART;
> -	sigemptyset(&new_act.sa_mask);
> +	tst_reap_children();
> 
> -	/* Set signal handler to sig_child_defined_handler */
> -	if (sigaction(SIGUSR2, &new_act, NULL) == -1) {
> -		tst_resm(TWARN | TERRNO, "signal failed in test_SIG");
> -		return -1;
> -	}
> +	flag = verify_resources();
> 
> -	/* Send SIGUSR2 signal to parent */
> -	if (kill(getppid(), SIGUSR2) == -1) {
> -		tst_resm(TWARN | TERRNO, "kill failed in test_SIG");
> -		return -1;
> +	for (i = CLONE_VM; i <= CLONE_SIGHAND; i <<= 1) {
> +		if (tcases[tc].flags == FLAG_ALL) {
> +			if (flag & i)
> +				tst_res(TPASS, "The resource %s of the parent process has changed", res_name[i >> 8]);
> +			else
> +				tst_res(TFAIL, "The resource %s of the parent process has not changed", res_name[i >> 8]);

I would make the messages less verbose and more to the point something
as:

		if (flag & i)
			tst_res(TPASS, "%s was shared with child");
		else
			tst_res(TFAIL, "%s was not shared with child");

> +		} else {
> +			if (flag & i)
> +				tst_res(TFAIL, "The resource %s of the parent process has changed", res_name[i >> 8]);
> +			else
> +				tst_res(TPASS, "The resource %s of the parent process has not changed", res_name[i >> 8]);
> +		}
>  	}
> -
> -	return 0;
> -}
> -
> -/*
> - * modified_VM() - This function is called by parent process to check
> - *		   whether child's modification to parent_variable
> - *		   is visible to parent
> - */
> -
> -static int modified_VM(void)
> -{
> -
> -	if (parent_variable == CHILD_VALUE)
> -		/* child has modified parent_variable */
> -		return 1;
> -
> -	return 0;
>  }
> 
> -/*
> - * modified_FILES() - This function checks for file descriptor table
> - *		      modifications done by child
> - */
> -static int modified_FILES(void)
> +static void cleanup(void)
>  {
> -	char buff[20];
> -
> -	if (((read(fd_parent, buff, sizeof(buff))) == -1) && (errno == EBADF))
> -		/* Child has closed this file descriptor */
> -		return 1;
> -
> -	/* close fd_parent */
> -	if ((close(fd_parent)) == -1)
> -		tst_resm(TWARN | TERRNO, "close() failed in modified_FILES()");
> -
> -	return 0;
> +	SAFE_CHDIR(cwd_parent);
> +	SAFE_UNLINK(TESTFILE);

There is no need to unlink anything here, the test library will do that
for you.

> +	free(cwd_parent);
>  }
> 
> -/*
> - * modified_FS() - This function checks parent's current working directory
> - *		   to see whether its modified by child or not.
> - */
> -static int modified_FS(void)
> +static void setup(void)
>  {
> -	char cwd[FILENAME_MAX];
> -
> -	if ((getcwd(cwd, sizeof(cwd))) == NULL)
> -		tst_resm(TWARN | TERRNO, "getcwd() failed");
> -
> -	if (!(strcmp(cwd, cwd_parent)))
> -		/* cwd hasn't changed */
> -		return 0;
> -
> -	return 1;
> -}
> +	struct sigaction def_act;
> 
> -/*
> - * modified_SIG() - This function checks whether child has changed
> - *		    parent's signal handler for signal, SIGUSR2
> - */
> -static int modified_SIG(void)
> -{
> +	/* Save current working directory of parent */
> +	cwd_parent = tst_get_tmpdir();
> 
> -	if (parent_got_signal)
> -		/*
> -		 * parent came through sig_child_defined_handler()
> -		 * this means child has changed parent's handler
> -		 */
> -		return 1;
> +	/*
> +	 * Set value for parent_variable in parent, which will be
> +	 * changed by child for testing CLONE_VM flag
> +	 */
> +	parent_variable = PARENT_VALUE;
> 
> -	return 0;
> -}
> +	/*
> +	 * Open file from parent, which will be closed by
> +	 * child, used for testing CLONE_FILES flag
> +	 */
> +	fd_parent = SAFE_OPEN(TESTFILE, O_CREAT | O_RDWR, 0777);

Since we call reset_resources() in the verify_clone() function now, most
of the code can be removed from the setup.

> -/*
> - * sig_child_defined_handler()  - Signal handler installed by child
> - */
> -static void sig_child_defined_handler(int pid)
> -{
> -	if ((syscall(__NR_gettid)) == child_pid)
> -		/* Child got signal, give warning */
> -		tst_resm(TWARN, "Child got SIGUSR2 signal");
> -	else
> -		parent_got_signal = TRUE;
> -}
> +	/*
> +	 * set parent_got_signal to 0, used for testing
> +	 * CLONE_SIGHAND flag
> +	 */
> +	parent_got_signal = 0;
> 
> -/* sig_default_handler() - Default handler for parent */
> -static void sig_default_handler(void)
> -{
> -}
> +	def_act.sa_handler = sig_parent_default_handler;
> +	def_act.sa_flags = SA_RESTART;
> +	SAFE_SIGEMPTYSET(&def_act.sa_mask);
> +	SAFE_SIGACTION(SIGUSR2, &def_act, NULL);
> +
> +	SAFE_MKDIR(TESTDIR, 0777);
> +	sprintf(cwd_child, "%s/%s", cwd_parent, TESTDIR);
> +}
> +
> +static struct tst_test test = {
> +	.setup = setup,
> +	.cleanup = cleanup,
> +	.tcnt = ARRAY_SIZE(tcases),
> +	.test = verify_clone,
> +	.bufs = (struct tst_buffers []) {
> +		{&child_stack, .size = CHILD_STACK_SIZE},

The array is missing the terminating element {} without it the test will
crash randomly.

> +	},
> +	.needs_tmpdir = 1,
> +};
> --
> 2.20.1
> 
> 
> 
> 
> -- 
> Mailing list info: https://lists.linux.it/listinfo/ltp

-- 
Cyril Hrubis
chrubis@suse.cz

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

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

* Re: [LTP] [PATCH v4 2/5] syscalls/clone03: Convert to new API
  2021-10-14  1:25 ` [LTP] [PATCH v4 2/5] syscalls/clone03: " zhanglianjie
@ 2021-10-27 12:32   ` Cyril Hrubis
  0 siblings, 0 replies; 12+ messages in thread
From: Cyril Hrubis @ 2021-10-27 12:32 UTC (permalink / raw)
  To: zhanglianjie; +Cc: ltp

Hi!
I've adjusted the description comment a bit and pushed, thanks.

-- 
Cyril Hrubis
chrubis@suse.cz

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

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

* Re: [LTP] [PATCH v4 3/5] syscalls/clone05: Convert to new API
  2021-10-14  1:25 ` [LTP] [PATCH v4 3/5] syscalls/clone05: " zhanglianjie
@ 2021-10-27 12:52   ` Cyril Hrubis
  0 siblings, 0 replies; 12+ messages in thread
From: Cyril Hrubis @ 2021-10-27 12:52 UTC (permalink / raw)
  To: zhanglianjie; +Cc: ltp

Hi!
Pushed, good job, thanks.

-- 
Cyril Hrubis
chrubis@suse.cz

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

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

* Re: [LTP] [PATCH v4 4/5] syscalls/clone06: Convert to new API
  2021-10-14  1:25 ` [LTP] [PATCH v4 4/5] syscalls/clone06: " zhanglianjie
@ 2021-10-27 13:26   ` Cyril Hrubis
  0 siblings, 0 replies; 12+ messages in thread
From: Cyril Hrubis @ 2021-10-27 13:26 UTC (permalink / raw)
  To: zhanglianjie; +Cc: ltp

Hi!
> +	const char *env_val = getenv(ENV_ID);
> +	if (!env_val) {
> +		tst_res(TFAIL, "Variable " ENV_ID " not defined in child");
> +		exit(-1);

I've changed these two exit(-1) in child to just exit(0), since the test
result is propagated automatically (by the tst_res(TFAIL, ...) call) and
the child shouldn't do anything else than exit(0).

And pushed, thanks.

-- 
Cyril Hrubis
chrubis@suse.cz

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

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

* Re: [LTP] [PATCH v4 5/5] syscalls/clone07: Convert to new API
  2021-10-14  1:25 ` [LTP] [PATCH v4 5/5] syscalls/clone07: " zhanglianjie
@ 2021-10-27 13:40   ` Cyril Hrubis
  0 siblings, 0 replies; 12+ messages in thread
From: Cyril Hrubis @ 2021-10-27 13:40 UTC (permalink / raw)
  To: zhanglianjie; +Cc: ltp

Hi!
I've changed the code so that only one TFAIL message is printed in the
case when the child dies with SIGSEGV and pushed, thanks.

-- 
Cyril Hrubis
chrubis@suse.cz

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

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

end of thread, other threads:[~2021-10-27 13:40 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-14  1:25 [LTP] [PATCH v4 1/5] syscalls/clone02: Convert to new API zhanglianjie
2021-10-14  1:25 ` [LTP] [PATCH v4 2/5] syscalls/clone03: " zhanglianjie
2021-10-27 12:32   ` Cyril Hrubis
2021-10-14  1:25 ` [LTP] [PATCH v4 3/5] syscalls/clone05: " zhanglianjie
2021-10-27 12:52   ` Cyril Hrubis
2021-10-14  1:25 ` [LTP] [PATCH v4 4/5] syscalls/clone06: " zhanglianjie
2021-10-27 13:26   ` Cyril Hrubis
2021-10-14  1:25 ` [LTP] [PATCH v4 5/5] syscalls/clone07: " zhanglianjie
2021-10-27 13:40   ` Cyril Hrubis
2021-10-15  9:57 ` [LTP] [PATCH v4 1/5] syscalls/clone02: " Petr Vorel
2021-10-16 13:07   ` zhanglianjie
2021-10-27 12:00 ` Cyril Hrubis

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).