All of lore.kernel.org
 help / color / mirror / Atom feed
* [LTP] [PATCH 1/3] clone08: convert to new LTP API
@ 2017-04-17 15:44 Alexey Kodanev
  2017-04-17 15:44 ` [LTP] [PATCH 2/3] clone08: add test-case for CLONE_CHILD_CLEARTID flag Alexey Kodanev
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Alexey Kodanev @ 2017-04-17 15:44 UTC (permalink / raw)
  To: ltp

In addition:
* use tst_reap_children()

* remove usage of tst_tmpdir()

* change behaviour in CLONE_STOPPED test-case: set flag after
  clone() and before kill() to make sure the thread updated
  this flag after the signal is sent

* define clone functions with 'void *arg'

* exit forked children with _exit()

Signed-off-by: Alexey Kodanev <alexey.kodanev@oracle.com>
---
 testcases/kernel/syscalls/clone/clone08.c |  199 +++++++++++------------------
 1 files changed, 77 insertions(+), 122 deletions(-)

diff --git a/testcases/kernel/syscalls/clone/clone08.c b/testcases/kernel/syscalls/clone/clone08.c
index 4c71db4..8bc2850 100644
--- a/testcases/kernel/syscalls/clone/clone08.c
+++ b/testcases/kernel/syscalls/clone/clone08.c
@@ -1,4 +1,5 @@
 /*
+ * Copyright (c) 2017 Oracle and/or its affiliates. All Rights Reserved.
  * Copyright (c) 2013 Fujitsu Ltd.
  * Author: Zeng Linggang <zenglg.jy@cn.fujitsu.com>
  *
@@ -15,38 +16,35 @@
  */
 
 #define _GNU_SOURCE
+#include <stdlib.h>
+#include <stdio.h>
 #include <errno.h>
 #include <sched.h>
 #include <sys/wait.h>
-#include "test.h"
+
+#include "tst_test.h"
 #include "clone_platform.h"
-#include "safe_macros.h"
 #include "linux_syscall_numbers.h"
 
-char *TCID = "clone08";
-
 static pid_t ptid, ctid, tgid;
 static void *child_stack;
 
-static void setup(void);
-static void cleanup(void);
-
 static void test_clone_parent(int t);
-static int child_clone_parent(void);
+static int child_clone_parent(void *);
 static pid_t parent_ppid;
 
 static void test_clone_tid(int t);
-static int child_clone_child_settid(void);
-static int child_clone_parent_settid(void);
+static int child_clone_child_settid(void *);
+static int child_clone_parent_settid(void *);
 
 #ifdef CLONE_STOPPED
 static void test_clone_stopped(int t);
-static int child_clone_stopped(void);
+static int child_clone_stopped(void *);
 static int stopped_flag;
 #endif
 
 static void test_clone_thread(int t);
-static int child_clone_thread(void);
+static int child_clone_thread(void *);
 static int tst_result;
 
 /*
@@ -61,7 +59,7 @@ static struct test_case {
 	char *name;
 	int flags;
 	void (*testfunc)(int);
-	int (*do_child)();
+	int (*do_child)(void *);
 } test_cases[] = {
 	{"CLONE_PARENT", CLONE_PARENT | SIGCHLD,
 	 test_clone_parent, child_clone_parent},
@@ -77,42 +75,20 @@ static struct test_case {
 	 test_clone_thread, child_clone_thread},
 };
 
-int TST_TOTAL = ARRAY_SIZE(test_cases);
-
-int main(int ac, char **av)
+static void do_test(unsigned int i)
 {
-	int i, lc;
-
-	tst_parse_opts(ac, av, NULL, NULL);
-
-	setup();
-	for (lc = 0; TEST_LOOPING(lc); lc++) {
-		tst_count = 0;
-		for (i = 0; i < TST_TOTAL; i++) {
-			tst_resm(TINFO, "running %s", test_cases[i].name);
-			test_cases[i].testfunc(i);
-		}
-	}
-	cleanup();
-	tst_exit();
+	tst_res(TINFO, "running %s", test_cases[i].name);
+	test_cases[i].testfunc(i);
 }
 
 static void setup(void)
 {
-	tst_sig(FORK, DEF_HANDLER, cleanup);
-
-	TEST_PAUSE;
-
-	tst_tmpdir();
-
-	child_stack = SAFE_MALLOC(cleanup, CHILD_STACK_SIZE);
+	child_stack = SAFE_MALLOC(CHILD_STACK_SIZE);
 }
 
 static void cleanup(void)
 {
 	free(child_stack);
-
-	tst_rmdir();
 }
 
 static long clone_child(const struct test_case *t, int use_tst)
@@ -121,16 +97,16 @@ static long clone_child(const struct test_case *t, int use_tst)
 		child_stack, &ptid, NULL, &ctid));
 
 	if (TEST_RETURN == -1 && TTERRNO == ENOSYS)
-		tst_brkm(TCONF, cleanup, "clone does not support 7 args");
+		tst_brk(TCONF, "clone does not support 7 args");
 
 	if (TEST_RETURN == -1) {
 		if (use_tst) {
-			tst_brkm(TBROK | TTERRNO, cleanup, "%s clone() failed",
+			tst_brk(TBROK | TTERRNO, "%s clone() failed",
 				 t->name);
 		} else {
 			printf("%s clone() failed, errno: %d",
 			       t->name, TEST_ERRNO);
-			exit(1);
+			_exit(1);
 		}
 	}
 	return TEST_RETURN;
@@ -140,8 +116,8 @@ static int wait4child(pid_t child)
 {
 	int status;
 
-	if (waitpid(child, &status, 0) == -1)
-		tst_resm(TBROK|TERRNO, "waitpid");
+	SAFE_WAITPID(child, &status, 0);
+
 	if (WIFEXITED(status))
 		return WEXITSTATUS(status);
 	else
@@ -150,77 +126,55 @@ static int wait4child(pid_t child)
 
 static void test_clone_parent(int t)
 {
-	int status;
 	pid_t child;
 
-	fflush(stdout);
-	child = FORK_OR_VFORK();
-	switch (child) {
-	case 0:
+	child = SAFE_FORK();
+	if (!child) {
 		parent_ppid = getppid();
 		clone_child(&test_cases[t], 0);
-		exit(0);
-	case -1:
-		tst_brkm(TBROK | TERRNO, NULL, "test_clone_parent fork");
-	default:
-		status = wait4child(child);
-		if (status == 0) {
-			/* wait for CLONE_PARENT child */
-			status = wait4child(-1);
-			if (status == 0) {
-				tst_resm(TPASS, "test %s", test_cases[t].name);
-			} else {
-				tst_resm(TFAIL, "test %s, status: %d",
-					 test_cases[t].name, status);
-			}
-		} else {
-			tst_resm(TFAIL, "test %s, status: %d",
-				 test_cases[t].name, status);
-		}
-	};
+		_exit(0);
+	}
+	tst_reap_children();
+	tst_res(TPASS, "clone and forked child has the same parent");
 }
 
-static int child_clone_parent(void)
+static int child_clone_parent(void *arg LTP_ATTRIBUTE_UNUSED)
 {
 	if (parent_ppid == getppid())
-		exit(0);
+		tst_syscall(__NR_exit, 0);
 	printf("FAIL: getppid != parent_ppid (%d != %d)\n",
 	       parent_ppid, getppid());
-	exit(1);
+	tst_syscall(__NR_exit, 1);
+	return 0;
 }
 
 static void test_clone_tid(int t)
 {
-	int status;
 	pid_t child;
 
 	child = clone_child(&test_cases[t], 1);
-	status = wait4child(child);
-	if (status == 0) {
-		tst_resm(TPASS, "test %s", test_cases[t].name);
-	} else {
-		tst_resm(TFAIL, "test %s, status: %d",
-			 test_cases[t].name, status);
-	}
+
+	tst_reap_children();
+	tst_res(TPASS, "clone() correctly set ptid/ctid");
 }
 
-static int child_clone_child_settid(void)
+static int child_clone_child_settid(void *arg LTP_ATTRIBUTE_UNUSED)
 {
-	if (ctid == ltp_syscall(__NR_getpid))
-		ltp_syscall(__NR_exit, 0);
+	if (ctid == tst_syscall(__NR_getpid))
+		tst_syscall(__NR_exit, 0);
 	printf("FAIL: ctid != getpid() (%d != %d)\n",
 	       ctid, getpid());
-	ltp_syscall(__NR_exit, 1);
+	tst_syscall(__NR_exit, 1);
 	return 0;
 }
 
-static int child_clone_parent_settid(void)
+static int child_clone_parent_settid(void *arg LTP_ATTRIBUTE_UNUSED)
 {
-	if (ptid == ltp_syscall(__NR_getpid))
-		ltp_syscall(__NR_exit, 0);
+	if (ptid == tst_syscall(__NR_getpid))
+		tst_syscall(__NR_exit, 0);
 	printf("FAIL: ptid != getpid() (%d != %d)\n",
 	       ptid, getpid());
-	ltp_syscall(__NR_exit, 1);
+	tst_syscall(__NR_exit, 1);
 	return 0;
 }
 
@@ -228,16 +182,13 @@ static int child_clone_parent_settid(void)
 static void test_clone_stopped(int t)
 {
 	int i;
-	int status;
-	int flag;
 	pid_t child;
 
 	if (tst_kvercmp(2, 6, 38) >= 0) {
-		tst_resm(TINFO, "CLONE_STOPPED skipped for kernels >= 2.6.38");
+		tst_res(TCONF, "CLONE_STOPPED skipped for kernels >= 2.6.38");
 		return;
 	}
 
-	stopped_flag = 0;
 	child = clone_child(&test_cases[t], 1);
 
 	/* give the kernel scheduler chance to run the CLONE_STOPPED thread*/
@@ -246,23 +197,22 @@ static void test_clone_stopped(int t)
 		usleep(1000);
 	}
 
-	flag = stopped_flag;
-	if (kill(child, SIGCONT) != 0)
-		tst_brkm(TBROK | TERRNO, cleanup, "kill SIGCONT failed");
+	stopped_flag = 0;
 
-	status = wait4child(child);
-	if (status == 0 && flag == 0) {
-		tst_resm(TPASS, "test %s", test_cases[t].name);
-	} else {
-		tst_resm(TFAIL, "test %s, status: %d, flag: %d",
-			 test_cases[t].name, status, flag);
-	}
+	SAFE_KILL(child, SIGCONT);
+
+	tst_reap_children();
+
+	if (stopped_flag == 1)
+		tst_res(TPASS, "clone stopped and resumed as expected");
+	else
+		tst_res(TFAIL, "clone not stopped, flag %d", stopped_flag);
 }
 
-static int child_clone_stopped(void)
+static int child_clone_stopped(void *arg LTP_ATTRIBUTE_UNUSED)
 {
 	stopped_flag = 1;
-	ltp_syscall(__NR_exit, 0);
+	tst_syscall(__NR_exit, 0);
 	return 0;
 }
 #endif
@@ -272,10 +222,8 @@ static void test_clone_thread(int t)
 	pid_t child;
 	int i, status;
 
-	fflush(stdout);
-	child = FORK_OR_VFORK();
-	switch (child) {
-	case 0:
+	child = SAFE_FORK();
+	if (!child) {
 		tgid = ltp_syscall(__NR_getpid);
 		tst_result = -1;
 		clone_child(&test_cases[t], 0);
@@ -286,26 +234,33 @@ static void test_clone_thread(int t)
 			if (tst_result != -1)
 				break;
 		}
-		ltp_syscall(__NR_exit, tst_result);
-	case -1:
-		tst_brkm(TBROK | TERRNO, NULL, "test_clone_thread fork");
-	default:
-		status = wait4child(child);
-		if (status == 0) {
-			tst_resm(TPASS, "test %s", test_cases[t].name);
-		} else {
-			tst_resm(TFAIL, "test %s, status: %d",
-				 test_cases[t].name, status);
-		}
-	};
+		_exit(tst_result);
+	}
+
+	status = wait4child(child);
+	if (status == 0) {
+		tst_res(TPASS, "test %s", test_cases[t].name);
+	} else {
+		tst_res(TFAIL, "test %s, status: %d",
+			test_cases[t].name, status);
+	}
 }
 
-static int child_clone_thread(void)
+static int child_clone_thread(void *arg LTP_ATTRIBUTE_UNUSED)
 {
-	if (tgid == ltp_syscall(__NR_getpid))
+	if (tgid == tst_syscall(__NR_getpid))
 		tst_result = TPASS;
 	else
 		tst_result = TFAIL;
-	ltp_syscall(__NR_exit, 0);
+	tst_syscall(__NR_exit, 0);
 	return 0;
 }
+
+static struct tst_test test = {
+	.tid = "clone08",
+	.tcnt = ARRAY_SIZE(test_cases),
+	.test = do_test,
+	.setup = setup,
+	.cleanup = cleanup,
+	.forks_child = 1
+};
-- 
1.7.1


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

* [LTP] [PATCH 2/3] clone08: add test-case for CLONE_CHILD_CLEARTID flag
  2017-04-17 15:44 [LTP] [PATCH 1/3] clone08: convert to new LTP API Alexey Kodanev
@ 2017-04-17 15:44 ` Alexey Kodanev
  2017-04-17 15:44 ` [LTP] [PATCH 3/3] clone09: add a test for CLONE_NEWNET flag Alexey Kodanev
  2017-06-07 15:46 ` [LTP] [PATCH 1/3] clone08: convert to new LTP API Cyril Hrubis
  2 siblings, 0 replies; 5+ messages in thread
From: Alexey Kodanev @ 2017-04-17 15:44 UTC (permalink / raw)
  To: ltp

Set CLONE_CHILD_CLEARTID in 'CLONE_THREAD' test-case to clear ctid
when the child clone exits. Use futex to wait for ctid to be changed.

Signed-off-by: Alexey Kodanev <alexey.kodanev@oracle.com>
---
 testcases/kernel/syscalls/clone/clone08.c |   39 ++++++++++++++++++----------
 1 files changed, 25 insertions(+), 14 deletions(-)

diff --git a/testcases/kernel/syscalls/clone/clone08.c b/testcases/kernel/syscalls/clone/clone08.c
index 8bc2850..dcc87b8 100644
--- a/testcases/kernel/syscalls/clone/clone08.c
+++ b/testcases/kernel/syscalls/clone/clone08.c
@@ -21,6 +21,7 @@
 #include <errno.h>
 #include <sched.h>
 #include <sys/wait.h>
+#include <linux/futex.h>
 
 #include "tst_test.h"
 #include "clone_platform.h"
@@ -71,7 +72,8 @@ static struct test_case {
 	{"CLONE_STOPPED", CLONE_STOPPED | CLONE_VM | SIGCHLD,
 	 test_clone_stopped, child_clone_stopped},
 #endif
-	{"CLONE_THREAD", CLONE_THREAD | CLONE_SIGHAND | CLONE_VM | SIGCHLD,
+	{"CLONE_THREAD", CLONE_THREAD | CLONE_SIGHAND | CLONE_VM |
+	 CLONE_CHILD_CLEARTID | SIGCHLD,
 	 test_clone_thread, child_clone_thread},
 };
 
@@ -220,29 +222,38 @@ static int child_clone_stopped(void *arg LTP_ATTRIBUTE_UNUSED)
 static void test_clone_thread(int t)
 {
 	pid_t child;
-	int i, status;
+	int status;
 
 	child = SAFE_FORK();
 	if (!child) {
-		tgid = ltp_syscall(__NR_getpid);
-		tst_result = -1;
+		struct timespec timeout = { 5 /* sec */, 0 };
+
+		tgid = tst_syscall(__NR_getpid);
+		ctid = tst_result = -1;
+
 		clone_child(&test_cases[t], 0);
 
-		for (i = 0; i < 5000; i++) {
-			sched_yield();
-			usleep(1000);
-			if (tst_result != -1)
-				break;
+		if (syscall(SYS_futex, &ctid, FUTEX_WAIT, -1, &timeout) &&
+		    errno == ETIMEDOUT) {
+			_exit(TBROK);
 		}
+
 		_exit(tst_result);
 	}
 
 	status = wait4child(child);
-	if (status == 0) {
-		tst_res(TPASS, "test %s", test_cases[t].name);
-	} else {
-		tst_res(TFAIL, "test %s, status: %d",
-			test_cases[t].name, status);
+	switch (status) {
+	case TPASS:
+		tst_res(TPASS, "clone has the same thread id");
+	break;
+	case TFAIL:
+		tst_res(TFAIL, "clone's thread id not equal parent's id");
+	break;
+	case TBROK:
+		tst_res(TFAIL, "futex returned ETIMEDOUT");
+	break;
+	default:
+		tst_res(TFAIL, "unexpected status received: %d", status);
 	}
 }
 
-- 
1.7.1


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

* [LTP] [PATCH 3/3] clone09: add a test for CLONE_NEWNET flag
  2017-04-17 15:44 [LTP] [PATCH 1/3] clone08: convert to new LTP API Alexey Kodanev
  2017-04-17 15:44 ` [LTP] [PATCH 2/3] clone08: add test-case for CLONE_CHILD_CLEARTID flag Alexey Kodanev
@ 2017-04-17 15:44 ` Alexey Kodanev
  2017-06-07 15:46 ` [LTP] [PATCH 1/3] clone08: convert to new LTP API Cyril Hrubis
  2 siblings, 0 replies; 5+ messages in thread
From: Alexey Kodanev @ 2017-04-17 15:44 UTC (permalink / raw)
  To: ltp

Verify that a new thread has new network namespace by
checking interface tag value parameter for lo interface
(/proc/sys/net/ipv4/conf/lo/tag). Change the value in
parent before clone() and then compare with the value saved
inside the thread.

Signed-off-by: Alexey Kodanev <alexey.kodanev@oracle.com>
---
 runtest/syscalls                          |    1 +
 testcases/kernel/syscalls/.gitignore      |    1 +
 testcases/kernel/syscalls/clone/clone09.c |  101 +++++++++++++++++++++++++++++
 3 files changed, 103 insertions(+), 0 deletions(-)
 create mode 100644 testcases/kernel/syscalls/clone/clone09.c

diff --git a/runtest/syscalls b/runtest/syscalls
index 5909456..6f3ba35 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -84,6 +84,7 @@ clone05 clone05
 clone06 clone06
 clone07 clone07
 clone08 clone08
+clone09 clone09
 
 close01 close01
 close02 close02
diff --git a/testcases/kernel/syscalls/.gitignore b/testcases/kernel/syscalls/.gitignore
index d5985cd..39b9044 100644
--- a/testcases/kernel/syscalls/.gitignore
+++ b/testcases/kernel/syscalls/.gitignore
@@ -62,6 +62,7 @@
 /clone/clone06
 /clone/clone07
 /clone/clone08
+/clone/clone09
 /close/close01
 /close/close02
 /close/close08
diff --git a/testcases/kernel/syscalls/clone/clone09.c b/testcases/kernel/syscalls/clone/clone09.c
new file mode 100644
index 0000000..a1beda1
--- /dev/null
+++ b/testcases/kernel/syscalls/clone/clone09.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2017 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#define _GNU_SOURCE
+#include <sched.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include "tst_test.h"
+#include "clone_platform.h"
+#include "linux_syscall_numbers.h"
+
+static void *child_stack;
+static int sysctl_net = -1;
+static int sysctl_net_new = -1;
+static const char sysctl_path[] = "/proc/sys/net/ipv4/conf/lo/tag";
+static const char sysctl_path_def[] = "/proc/sys/net/ipv4/conf/default/tag";
+static int flags = CLONE_NEWNET | CLONE_VM | SIGCHLD;
+
+static void setup(void)
+{
+	child_stack = SAFE_MALLOC(CHILD_STACK_SIZE);
+}
+
+static void cleanup(void)
+{
+	if (sysctl_net != -1)
+		SAFE_FILE_PRINTF(sysctl_path, "%d", sysctl_net);
+
+	free(child_stack);
+}
+
+static int newnet(void *arg LTP_ATTRIBUTE_UNUSED)
+{
+	SAFE_FILE_SCANF(sysctl_path, "%d", &sysctl_net_new);
+	tst_syscall(__NR_exit, 0);
+	return 0;
+}
+
+static long clone_child(void)
+{
+	TEST(ltp_clone(flags, newnet, NULL, CHILD_STACK_SIZE, child_stack));
+
+	if (TEST_RETURN == -1 && TTERRNO == EINVAL)
+		tst_brk(TCONF, "CLONE_NEWNET not supported, CONFIG_NET_NS?");
+
+	if (TEST_RETURN == -1)
+		tst_brk(TBROK | TTERRNO, "clone(CLONE_NEWNET) failed");
+
+	return TEST_RETURN;
+}
+
+static void do_test(void)
+{
+	int def_val;
+	pid_t child;
+
+	tst_res(TINFO, "create clone in a new netns with 'CLONE_NEWNET' flag");
+
+	SAFE_FILE_SCANF(sysctl_path, "%d", &sysctl_net);
+	SAFE_FILE_PRINTF(sysctl_path, "%d", sysctl_net + 1);
+
+	child = clone_child();
+	tst_reap_children();
+
+	if (sysctl_net_new == (sysctl_net + 1)) {
+		tst_res(TFAIL, "sysctl params equal: %s=%d",
+			sysctl_path, sysctl_net_new);
+	}
+
+	SAFE_FILE_SCANF(sysctl_path_def, "%d", &def_val);
+
+	if (sysctl_net_new != def_val) {
+		tst_res(TFAIL, "netns param init to non-default value %d",
+			sysctl_net_new);
+	}
+
+	tst_res(TPASS, "sysctl params differ in new netns");
+}
+
+static struct tst_test test = {
+	.tid = "clone09",
+	.test_all = do_test,
+	.setup = setup,
+	.cleanup = cleanup,
+	.needs_root = 1,
+};
-- 
1.7.1


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

* [LTP] [PATCH 1/3] clone08: convert to new LTP API
  2017-04-17 15:44 [LTP] [PATCH 1/3] clone08: convert to new LTP API Alexey Kodanev
  2017-04-17 15:44 ` [LTP] [PATCH 2/3] clone08: add test-case for CLONE_CHILD_CLEARTID flag Alexey Kodanev
  2017-04-17 15:44 ` [LTP] [PATCH 3/3] clone09: add a test for CLONE_NEWNET flag Alexey Kodanev
@ 2017-06-07 15:46 ` Cyril Hrubis
  2017-06-08  9:36   ` Alexey Kodanev
  2 siblings, 1 reply; 5+ messages in thread
From: Cyril Hrubis @ 2017-06-07 15:46 UTC (permalink / raw)
  To: ltp

Hi!
>  static long clone_child(const struct test_case *t, int use_tst)
> @@ -121,16 +97,16 @@ static long clone_child(const struct test_case *t, int use_tst)
>  		child_stack, &ptid, NULL, &ctid));
>  
>  	if (TEST_RETURN == -1 && TTERRNO == ENOSYS)
> -		tst_brkm(TCONF, cleanup, "clone does not support 7 args");
> +		tst_brk(TCONF, "clone does not support 7 args");
>  
>  	if (TEST_RETURN == -1) {
>  		if (use_tst) {
> -			tst_brkm(TBROK | TTERRNO, cleanup, "%s clone() failed",
> +			tst_brk(TBROK | TTERRNO, "%s clone() failed",
>  				 t->name);
>  		} else {
>  			printf("%s clone() failed, errno: %d",
>  			       t->name, TEST_ERRNO);
> -			exit(1);
> +			_exit(1);
>  		}
>  	}

Do we still need the use_tst flag here? Calling tst_* functions in child
works fine with the new library.

>  	return TEST_RETURN;
> @@ -140,8 +116,8 @@ static int wait4child(pid_t child)
>  {
>  	int status;
>  
> -	if (waitpid(child, &status, 0) == -1)
> -		tst_resm(TBROK|TERRNO, "waitpid");
> +	SAFE_WAITPID(child, &status, 0);
> +
>  	if (WIFEXITED(status))
>  		return WEXITSTATUS(status);
>  	else
> @@ -150,77 +126,55 @@ static int wait4child(pid_t child)
>  
>  static void test_clone_parent(int t)
>  {
> -	int status;
>  	pid_t child;
>  
> -	fflush(stdout);
> -	child = FORK_OR_VFORK();
> -	switch (child) {
> -	case 0:
> +	child = SAFE_FORK();
> +	if (!child) {
>  		parent_ppid = getppid();
>  		clone_child(&test_cases[t], 0);
> -		exit(0);
> -	case -1:
> -		tst_brkm(TBROK | TERRNO, NULL, "test_clone_parent fork");
> -	default:
> -		status = wait4child(child);
> -		if (status == 0) {
> -			/* wait for CLONE_PARENT child */
> -			status = wait4child(-1);
> -			if (status == 0) {
> -				tst_resm(TPASS, "test %s", test_cases[t].name);
> -			} else {
> -				tst_resm(TFAIL, "test %s, status: %d",
> -					 test_cases[t].name, status);
> -			}
> -		} else {
> -			tst_resm(TFAIL, "test %s, status: %d",
> -				 test_cases[t].name, status);
> -		}
> -	};
> +		_exit(0);
> +	}
> +	tst_reap_children();
> +	tst_res(TPASS, "clone and forked child has the same parent");

Hmm, so supposedly we produce TBROK in the tst_reap_childer() if the
child_clone_parent() has failed, right?

The test failures are accounted for in the structure stored in the
shared memory. Only exit statuses that are propagated correctly are
these that should exit the test immediately which are TBROK and TCONF.

So if a test child fails it should call the tst_res(TFAIL, ...) function
and then exit with 0. Or exit with non-zero value while the parent waits
for it and calls the tst_res() function accordingly. At least this is
how the code in tst_test.c is structured now.

Moreover even if the code in tst_test was able to cope with tests
exitting with TFAIL this would still produce TPASS message even if the
child reported a failure.

-- 
Cyril Hrubis
chrubis@suse.cz

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

* [LTP] [PATCH 1/3] clone08: convert to new LTP API
  2017-06-07 15:46 ` [LTP] [PATCH 1/3] clone08: convert to new LTP API Cyril Hrubis
@ 2017-06-08  9:36   ` Alexey Kodanev
  0 siblings, 0 replies; 5+ messages in thread
From: Alexey Kodanev @ 2017-06-08  9:36 UTC (permalink / raw)
  To: ltp

Hi,
On 06/07/2017 06:46 PM, Cyril Hrubis wrote:
> Hi!
>>  static long clone_child(const struct test_case *t, int use_tst)
>> @@ -121,16 +97,16 @@ static long clone_child(const struct test_case *t, int use_tst)
>>  		child_stack, &ptid, NULL, &ctid));
>>  
>>  	if (TEST_RETURN == -1 && TTERRNO == ENOSYS)
>> -		tst_brkm(TCONF, cleanup, "clone does not support 7 args");
>> +		tst_brk(TCONF, "clone does not support 7 args");
>>  
>>  	if (TEST_RETURN == -1) {
>>  		if (use_tst) {
>> -			tst_brkm(TBROK | TTERRNO, cleanup, "%s clone() failed",
>> +			tst_brk(TBROK | TTERRNO, "%s clone() failed",
>>  				 t->name);
>>  		} else {
>>  			printf("%s clone() failed, errno: %d",
>>  			       t->name, TEST_ERRNO);
>> -			exit(1);
>> +			_exit(1);
>>  		}
>>  	}
> Do we still need the use_tst flag here? Calling tst_* functions in child
> works fine with the new library.

Great, this simplifies things.

>
>>  	return TEST_RETURN;
>> @@ -140,8 +116,8 @@ static int wait4child(pid_t child)
>>  {
>>  	int status;
>>  
>> -	if (waitpid(child, &status, 0) == -1)
>> -		tst_resm(TBROK|TERRNO, "waitpid");
>> +	SAFE_WAITPID(child, &status, 0);
>> +
>>  	if (WIFEXITED(status))
>>  		return WEXITSTATUS(status);
>>  	else
>> @@ -150,77 +126,55 @@ static int wait4child(pid_t child)
>>  
>>  static void test_clone_parent(int t)
>>  {
>> -	int status;
>>  	pid_t child;
>>  
>> -	fflush(stdout);
>> -	child = FORK_OR_VFORK();
>> -	switch (child) {
>> -	case 0:
>> +	child = SAFE_FORK();
>> +	if (!child) {
>>  		parent_ppid = getppid();
>>  		clone_child(&test_cases[t], 0);
>> -		exit(0);
>> -	case -1:
>> -		tst_brkm(TBROK | TERRNO, NULL, "test_clone_parent fork");
>> -	default:
>> -		status = wait4child(child);
>> -		if (status == 0) {
>> -			/* wait for CLONE_PARENT child */
>> -			status = wait4child(-1);
>> -			if (status == 0) {
>> -				tst_resm(TPASS, "test %s", test_cases[t].name);
>> -			} else {
>> -				tst_resm(TFAIL, "test %s, status: %d",
>> -					 test_cases[t].name, status);
>> -			}
>> -		} else {
>> -			tst_resm(TFAIL, "test %s, status: %d",
>> -				 test_cases[t].name, status);
>> -		}
>> -	};
>> +		_exit(0);
>> +	}
>> +	tst_reap_children();
>> +	tst_res(TPASS, "clone and forked child has the same parent");
> Hmm, so supposedly we produce TBROK in the tst_reap_childer() if the
> child_clone_parent() has failed, right?
>
> The test failures are accounted for in the structure stored in the
> shared memory. Only exit statuses that are propagated correctly are
> these that should exit the test immediately which are TBROK and TCONF.
>
> So if a test child fails it should call the tst_res(TFAIL, ...) function
> and then exit with 0. Or exit with non-zero value while the parent waits
> for it and calls the tst_res() function accordingly. At least this is
> how the code in tst_test.c is structured now.
>
> Moreover even if the code in tst_test was able to cope with tests
> exitting with TFAIL this would still produce TPASS message even if the
> child reported a failure.

Agree, I'll move tst_res() to a child function and make it exit with 0.

Thanks,
Alexey

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

end of thread, other threads:[~2017-06-08  9:36 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-04-17 15:44 [LTP] [PATCH 1/3] clone08: convert to new LTP API Alexey Kodanev
2017-04-17 15:44 ` [LTP] [PATCH 2/3] clone08: add test-case for CLONE_CHILD_CLEARTID flag Alexey Kodanev
2017-04-17 15:44 ` [LTP] [PATCH 3/3] clone09: add a test for CLONE_NEWNET flag Alexey Kodanev
2017-06-07 15:46 ` [LTP] [PATCH 1/3] clone08: convert to new LTP API Cyril Hrubis
2017-06-08  9:36   ` Alexey Kodanev

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.