* [LTP] [PATCH v4 2/2] clone/clone08.c: add new flags
@ 2013-12-12 11:35 zenglg.jy
2013-12-12 16:22 ` Jan Stancek
0 siblings, 1 reply; 3+ messages in thread
From: zenglg.jy @ 2013-12-12 11:35 UTC (permalink / raw)
To: Jan Stancek; +Cc: ltp-list
Add new case for clone(2)
CLONE_PARENT
CLONE_CHILD_SETTID
CLONE_PARENT_SETTID
CLONE_STOPPED
CLONE_THREAD
Signed-off-by: Zeng Linggang <zenglg.jy@cn.fujitsu.com>
---
runtest/ltplite | 1 +
runtest/stress.part3 | 1 +
runtest/syscalls | 1 +
testcases/kernel/syscalls/.gitignore | 1 +
testcases/kernel/syscalls/clone/clone08.c | 350 ++++++++++++++++++++++++++++++
5 files changed, 354 insertions(+)
create mode 100644 testcases/kernel/syscalls/clone/clone08.c
diff --git a/runtest/ltplite b/runtest/ltplite
index 2382dec..fe6cb04 100644
--- a/runtest/ltplite
+++ b/runtest/ltplite
@@ -127,6 +127,7 @@ clone04 clone04
clone05 clone05
clone06 clone06
clone07 clone07
+clone08 clone08
close01 close01
close02 close02
diff --git a/runtest/stress.part3 b/runtest/stress.part3
index 16247e9..16b08a7 100644
--- a/runtest/stress.part3
+++ b/runtest/stress.part3
@@ -68,6 +68,7 @@ clone04 clone04
clone05 clone05
clone06 clone06
clone07 clone07
+clone08 clone08
close01 close01
close02 close02
diff --git a/runtest/syscalls b/runtest/syscalls
index 717342e..a17fec7 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -85,6 +85,7 @@ clone04 clone04
clone05 clone05
clone06 clone06
clone07 clone07
+clone08 clone08
close01 close01
close02 close02
diff --git a/testcases/kernel/syscalls/.gitignore b/testcases/kernel/syscalls/.gitignore
index bbefb25..91cf0f1 100644
--- a/testcases/kernel/syscalls/.gitignore
+++ b/testcases/kernel/syscalls/.gitignore
@@ -65,6 +65,7 @@
/clone/clone05
/clone/clone06
/clone/clone07
+/clone/clone08
/close/close01
/close/close02
/close/close08
diff --git a/testcases/kernel/syscalls/clone/clone08.c b/testcases/kernel/syscalls/clone/clone08.c
new file mode 100644
index 0000000..19b47c8
--- /dev/null
+++ b/testcases/kernel/syscalls/clone/clone08.c
@@ -0,0 +1,350 @@
+/*
+ * Copyright (c) 2013 Fujitsu Ltd.
+ * Author: Zeng Linggang <zenglg.jy@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.
+ */
+
+#include <errno.h>
+#include <linux/sched.h>
+#include <sched.h>
+#include <sys/wait.h>
+#include "test.h"
+#include "usctest.h"
+#include "clone_platform.h"
+#include "safe_macros.h"
+#include "linux_syscall_numbers.h"
+
+#define BUFSIZE 512
+
+static pid_t parent_ppid;
+static pid_t ptid, ctid;
+static pid_t tgid;
+static void *child_stack;
+static int tst_result;
+
+static void setup(void);
+static void cleanup(void);
+
+static void do_master_child_setup(void);
+static void do_master_child(int i);
+static void wait_child(pid_t child, int index);
+
+static int child_clone_parent(void);
+
+static int child_clone_child_settid(void);
+static int child_clone_parent_settid(void);
+
+static int child_clone_thread(void);
+static int check_clone_thread_terminated(pid_t tgid);
+static int get_threas_num(pid_t tgid);
+
+#ifdef CLONE_STOPPED
+static int stopped_flag;
+static void test_clone_stopped(int tid);
+static int child_clone_stopped(void);
+#endif
+
+static struct test_case {
+ char *name;
+ int flags;
+ void (*testfunc)(int);
+ int (*do_child)();
+} test_cases[] = {
+ {"CLONE_PARENT", CLONE_PARENT | SIGCHLD, NULL, child_clone_parent},
+ {"CLONE_CHILD_SETTID", CLONE_CHILD_SETTID | CLONE_VM | SIGCHLD, NULL,
+ child_clone_child_settid},
+ {"CLONE_PARENT_SETTID", CLONE_PARENT_SETTID | CLONE_VM | SIGCHLD, NULL,
+ child_clone_parent_settid},
+#ifdef CLONE_STOPPED
+ {"CLONE_STOPPED", CLONE_STOPPED | CLONE_VM | SIGCHLD,
+ test_clone_stopped, child_clone_stopped},
+#endif
+ {"CLONE_THREAD", CLONE_THREAD | CLONE_SIGHAND | CLONE_VM | SIGCHLD,
+ NULL, child_clone_thread},
+};
+
+char *TCID = "clone08";
+int TST_TOTAL = ARRAY_SIZE(test_cases);
+
+int main(int ac, char **av)
+{
+ int lc;
+ char *msg;
+ int i;
+ pid_t child;
+
+ msg = parse_opts(ac, av, NULL, NULL);
+ if (msg != NULL)
+ tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+
+ setup();
+
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+
+ tst_count = 0;
+
+ for (i = 0; i < TST_TOTAL; i++) {
+
+ fflush(stdout);
+
+ child = FORK_OR_VFORK();
+ if (child < 0) {
+ tst_brkm(TBROK, cleanup, "Fork failed");
+ } else if (child == 0) {
+ do_master_child(i);
+ } else {
+ wait_child(child, i);
+ /*
+ * for CLONE_PARENT, we need to wait twice and
+ * ignore CLONE_PARENT thread return status.
+ */
+ if (test_cases[i].flags & CLONE_PARENT)
+ wait_child(child, i);
+ }
+ }
+ }
+
+ cleanup();
+
+ tst_exit();
+}
+
+static void do_master_child_setup(void)
+{
+ parent_ppid = getppid();
+
+ tgid = ltp_syscall(__NR_getpid);
+
+ tst_result = TFAIL;
+
+#ifdef CLONE_STOPPED
+ stopped_flag = 0;
+#endif
+}
+
+static void do_master_child(int i)
+{
+ int status;
+
+ do_master_child_setup();
+
+ TEST(ltp_clone(test_cases[i].flags, test_cases[i].do_child, NULL,
+ CHILD_STACK_SIZE, child_stack, &ptid, NULL, &ctid));
+
+ if (TEST_RETURN == -1)
+ exit(TBROK);
+
+ if (test_cases[i].testfunc != NULL)
+ test_cases[i].testfunc(TEST_RETURN);
+
+ if (test_cases[i].flags & CLONE_PARENT) {
+ /*
+ * parent process will wait CLONE_PARENT thread to
+ * get test result.
+ */
+ exit(0);
+ } else if (test_cases[i].flags & CLONE_THREAD) {
+ int ret;
+
+ ret = check_clone_thread_terminated(tgid);
+ if (ret == 0) {
+ fprintf(stderr,
+ "CLONE_THREAD thread does't terminated in "
+ "time\n");
+ exit(TBROK);
+ }
+ } else {
+ if (wait(&status) == -1) {
+ fprintf(stderr, "%s wait failed in do_master_child\n",
+ test_cases[i].name);
+ exit(TBROK);
+ }
+ }
+
+ exit(tst_result);
+}
+
+void show_test_result(int status, int index)
+{
+ int ret;
+
+ if (WIFEXITED(status)) {
+ ret = WEXITSTATUS(status);
+ if (ret == TPASS || ret == TFAIL) {
+ tst_resm(ret, "test %s %s", test_cases[index].name,
+ ret ? "failed" : "success");
+ } else {
+ tst_brkm(TBROK, cleanup, "test %s failed",
+ test_cases[index].name);
+ }
+ } else {
+ tst_brkm(TBROK, cleanup, "%s clone() exit abnormally",
+ test_cases[index].name);
+ }
+}
+
+static void wait_child(pid_t child, int index)
+{
+ int status;
+ pid_t exit_pid;
+
+ exit_pid = wait(&status);
+ if (exit_pid == -1) {
+ tst_brkm(TBROK | TERRNO, cleanup, "%s wait failed",
+ test_cases[index].name);
+ } else if (test_cases[index].flags & CLONE_PARENT) {
+ if (exit_pid != child)
+ show_test_result(status, index);
+ } else {
+ show_test_result(status, index);
+ }
+}
+
+static void setup(void)
+{
+ tst_sig(FORK, DEF_HANDLER, cleanup);
+
+ TEST_PAUSE;
+
+ tst_tmpdir();
+
+ child_stack = SAFE_MALLOC(NULL, CHILD_STACK_SIZE);
+}
+
+static void cleanup(void)
+{
+ free(child_stack);
+
+ tst_rmdir();
+
+ TEST_CLEANUP;
+}
+
+static int child_clone_parent(void)
+{
+ if (parent_ppid == getppid())
+ tst_result = TPASS;
+ else
+ tst_result = TFAIL;
+ exit(tst_result);
+}
+
+static int child_clone_child_settid(void)
+{
+ if (ctid == getpid())
+ tst_result = TPASS;
+ else
+ tst_result = TFAIL;
+
+ exit(tst_result);
+}
+
+static int child_clone_parent_settid(void)
+{
+ if (ptid == getpid())
+ tst_result = TPASS;
+ else
+ tst_result = TFAIL;
+
+ exit(tst_result);
+}
+
+#ifdef CLONE_STOPPED
+static void test_clone_stopped(int tid)
+{
+ int i;
+
+ /* give the kernel scheduler chance to run the CLONE_STOPPED thread*/
+ for (i = 0; i < 100; i++) {
+ sched_yield();
+ usleep(1000);
+ }
+ /*
+ * if stopped_flag is not changed in the above time interval,
+ * we think the CLONE_STOPPED thread is stopped.
+ */
+ if (stopped_flag == 1)
+ tst_result = TFAIL;
+ else
+ tst_result = TPASS;
+
+ if (kill(tid, SIGCONT) != 0) {
+ fprintf(stderr, "kill SIGCONT failed\n");
+ tst_result = TBROK;
+ }
+}
+
+static int child_clone_stopped(void)
+{
+ stopped_flag = 1;
+ exit(tst_result);
+}
+#endif
+
+/* check whether CLONE_THREAD thread was terminated */
+static int check_clone_thread_terminated(pid_t tgid)
+{
+ int i;
+ int num;
+
+ for (i = 0; i < 5000; i++) {
+ num = get_threas_num(tgid);
+ if (num == 1)
+ return 1;
+ sched_yield();
+ usleep(1000);
+ }
+ return 0;
+}
+
+static int get_threas_num(pid_t tgid)
+{
+ FILE *fp;
+ int ret;
+ char com[BUFSIZE];
+ int thread_nums;
+
+ ret = sprintf(com, "ls /proc/%d/task/ | wc -l", tgid);
+ if (ret < 0) {
+ fprintf(stderr, "sprintf failed\n");
+ exit(TBROK);
+ }
+
+ fp = popen(com, "r");
+ if (!fp) {
+ fprintf(stderr, "run:ls /proc/%d/task/ | wc -l failed\n", tgid);
+ exit(TBROK);
+ }
+
+ ret = fscanf(fp, "%d", &thread_nums);
+ if (ret != 1) {
+ fprintf(stderr,
+ "could not get the numbers of threads in current "
+ "thread group\n");
+ exit(TBROK);
+ }
+ pclose(fp);
+ return thread_nums;
+}
+
+static int child_clone_thread(void)
+{
+ if (tgid == ltp_syscall(__NR_getpid))
+ tst_result = TPASS;
+ else
+ tst_result = TFAIL;
+
+ ltp_syscall(__NR_exit, 0);
+ return 0;
+}
--
1.8.3.1
------------------------------------------------------------------------------
Rapidly troubleshoot problems before they affect your business. Most IT
organizations don't have a clear picture of how application performance
affects their revenue. With AppDynamics, you get 100% visibility into your
Java,.NET, & PHP application. Start your 15-day FREE TRIAL of AppDynamics Pro!
http://pubads.g.doubleclick.net/gampad/clk?id=84349831&iu=/4140/ostg.clktrk
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [LTP] [PATCH v4 2/2] clone/clone08.c: add new flags
2013-12-12 11:35 [LTP] [PATCH v4 2/2] clone/clone08.c: add new flags zenglg.jy
@ 2013-12-12 16:22 ` Jan Stancek
2013-12-18 5:41 ` zenglg.jy
0 siblings, 1 reply; 3+ messages in thread
From: Jan Stancek @ 2013-12-12 16:22 UTC (permalink / raw)
To: zenglg.jy; +Cc: ltp-list
----- Original Message -----
> From: "zenglg.jy" <zenglg.jy@cn.fujitsu.com>
> To: "Jan Stancek" <jstancek@redhat.com>
> Cc: "ltp-list" <ltp-list@lists.sourceforge.net>
> Sent: Thursday, 12 December, 2013 12:35:36 PM
> Subject: [PATCH v4 2/2] clone/clone08.c: add new flags
>
> Add new case for clone(2)
> CLONE_PARENT
> CLONE_CHILD_SETTID
> CLONE_PARENT_SETTID
> CLONE_STOPPED
> CLONE_THREAD
>
> Signed-off-by: Zeng Linggang <zenglg.jy@cn.fujitsu.com>
Hi,
I sent a patch named "[PATCH v4b 2/2] clone/clone08.c: add new flags"
few moments ago. It's a re-arranged v4 of your patch.
I have removed the various "if" checks from main and do_master_child().
by splitting do_master_child() into separate test_ functions for each testcase.
I also removed check_clone_thread_terminated() and used same kind of check
we have in test_clone_stopped().
Can you have a look if you'd be OK with these changes?
Regards,
Jan
> ---
> runtest/ltplite | 1 +
> runtest/stress.part3 | 1 +
> runtest/syscalls | 1 +
> testcases/kernel/syscalls/.gitignore | 1 +
> testcases/kernel/syscalls/clone/clone08.c | 350
> ++++++++++++++++++++++++++++++
> 5 files changed, 354 insertions(+)
> create mode 100644 testcases/kernel/syscalls/clone/clone08.c
>
> diff --git a/runtest/ltplite b/runtest/ltplite
> index 2382dec..fe6cb04 100644
> --- a/runtest/ltplite
> +++ b/runtest/ltplite
> @@ -127,6 +127,7 @@ clone04 clone04
> clone05 clone05
> clone06 clone06
> clone07 clone07
> +clone08 clone08
>
> close01 close01
> close02 close02
> diff --git a/runtest/stress.part3 b/runtest/stress.part3
> index 16247e9..16b08a7 100644
> --- a/runtest/stress.part3
> +++ b/runtest/stress.part3
> @@ -68,6 +68,7 @@ clone04 clone04
> clone05 clone05
> clone06 clone06
> clone07 clone07
> +clone08 clone08
>
> close01 close01
> close02 close02
> diff --git a/runtest/syscalls b/runtest/syscalls
> index 717342e..a17fec7 100644
> --- a/runtest/syscalls
> +++ b/runtest/syscalls
> @@ -85,6 +85,7 @@ clone04 clone04
> clone05 clone05
> clone06 clone06
> clone07 clone07
> +clone08 clone08
>
> close01 close01
> close02 close02
> diff --git a/testcases/kernel/syscalls/.gitignore
> b/testcases/kernel/syscalls/.gitignore
> index bbefb25..91cf0f1 100644
> --- a/testcases/kernel/syscalls/.gitignore
> +++ b/testcases/kernel/syscalls/.gitignore
> @@ -65,6 +65,7 @@
> /clone/clone05
> /clone/clone06
> /clone/clone07
> +/clone/clone08
> /close/close01
> /close/close02
> /close/close08
> diff --git a/testcases/kernel/syscalls/clone/clone08.c
> b/testcases/kernel/syscalls/clone/clone08.c
> new file mode 100644
> index 0000000..19b47c8
> --- /dev/null
> +++ b/testcases/kernel/syscalls/clone/clone08.c
> @@ -0,0 +1,350 @@
> +/*
> + * Copyright (c) 2013 Fujitsu Ltd.
> + * Author: Zeng Linggang <zenglg.jy@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.
> + */
> +
> +#include <errno.h>
> +#include <linux/sched.h>
> +#include <sched.h>
> +#include <sys/wait.h>
> +#include "test.h"
> +#include "usctest.h"
> +#include "clone_platform.h"
> +#include "safe_macros.h"
> +#include "linux_syscall_numbers.h"
> +
> +#define BUFSIZE 512
> +
> +static pid_t parent_ppid;
> +static pid_t ptid, ctid;
> +static pid_t tgid;
> +static void *child_stack;
> +static int tst_result;
> +
> +static void setup(void);
> +static void cleanup(void);
> +
> +static void do_master_child_setup(void);
> +static void do_master_child(int i);
> +static void wait_child(pid_t child, int index);
> +
> +static int child_clone_parent(void);
> +
> +static int child_clone_child_settid(void);
> +static int child_clone_parent_settid(void);
> +
> +static int child_clone_thread(void);
> +static int check_clone_thread_terminated(pid_t tgid);
> +static int get_threas_num(pid_t tgid);
> +
> +#ifdef CLONE_STOPPED
> +static int stopped_flag;
> +static void test_clone_stopped(int tid);
> +static int child_clone_stopped(void);
> +#endif
> +
> +static struct test_case {
> + char *name;
> + int flags;
> + void (*testfunc)(int);
> + int (*do_child)();
> +} test_cases[] = {
> + {"CLONE_PARENT", CLONE_PARENT | SIGCHLD, NULL, child_clone_parent},
> + {"CLONE_CHILD_SETTID", CLONE_CHILD_SETTID | CLONE_VM | SIGCHLD, NULL,
> + child_clone_child_settid},
> + {"CLONE_PARENT_SETTID", CLONE_PARENT_SETTID | CLONE_VM | SIGCHLD, NULL,
> + child_clone_parent_settid},
> +#ifdef CLONE_STOPPED
> + {"CLONE_STOPPED", CLONE_STOPPED | CLONE_VM | SIGCHLD,
> + test_clone_stopped, child_clone_stopped},
> +#endif
> + {"CLONE_THREAD", CLONE_THREAD | CLONE_SIGHAND | CLONE_VM | SIGCHLD,
> + NULL, child_clone_thread},
> +};
> +
> +char *TCID = "clone08";
> +int TST_TOTAL = ARRAY_SIZE(test_cases);
> +
> +int main(int ac, char **av)
> +{
> + int lc;
> + char *msg;
> + int i;
> + pid_t child;
> +
> + msg = parse_opts(ac, av, NULL, NULL);
> + if (msg != NULL)
> + tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
> +
> + setup();
> +
> + for (lc = 0; TEST_LOOPING(lc); lc++) {
> +
> + tst_count = 0;
> +
> + for (i = 0; i < TST_TOTAL; i++) {
> +
> + fflush(stdout);
> +
> + child = FORK_OR_VFORK();
> + if (child < 0) {
> + tst_brkm(TBROK, cleanup, "Fork failed");
> + } else if (child == 0) {
> + do_master_child(i);
> + } else {
> + wait_child(child, i);
> + /*
> + * for CLONE_PARENT, we need to wait twice and
> + * ignore CLONE_PARENT thread return status.
> + */
> + if (test_cases[i].flags & CLONE_PARENT)
> + wait_child(child, i);
> + }
> + }
> + }
> +
> + cleanup();
> +
> + tst_exit();
> +}
> +
> +static void do_master_child_setup(void)
> +{
> + parent_ppid = getppid();
> +
> + tgid = ltp_syscall(__NR_getpid);
> +
> + tst_result = TFAIL;
> +
> +#ifdef CLONE_STOPPED
> + stopped_flag = 0;
> +#endif
> +}
> +
> +static void do_master_child(int i)
> +{
> + int status;
> +
> + do_master_child_setup();
> +
> + TEST(ltp_clone(test_cases[i].flags, test_cases[i].do_child, NULL,
> + CHILD_STACK_SIZE, child_stack, &ptid, NULL, &ctid));
> +
> + if (TEST_RETURN == -1)
> + exit(TBROK);
> +
> + if (test_cases[i].testfunc != NULL)
> + test_cases[i].testfunc(TEST_RETURN);
> +
> + if (test_cases[i].flags & CLONE_PARENT) {
> + /*
> + * parent process will wait CLONE_PARENT thread to
> + * get test result.
> + */
> + exit(0);
> + } else if (test_cases[i].flags & CLONE_THREAD) {
> + int ret;
> +
> + ret = check_clone_thread_terminated(tgid);
> + if (ret == 0) {
> + fprintf(stderr,
> + "CLONE_THREAD thread does't terminated in "
> + "time\n");
> + exit(TBROK);
> + }
> + } else {
> + if (wait(&status) == -1) {
> + fprintf(stderr, "%s wait failed in do_master_child\n",
> + test_cases[i].name);
> + exit(TBROK);
> + }
> + }
> +
> + exit(tst_result);
> +}
> +
> +void show_test_result(int status, int index)
> +{
> + int ret;
> +
> + if (WIFEXITED(status)) {
> + ret = WEXITSTATUS(status);
> + if (ret == TPASS || ret == TFAIL) {
> + tst_resm(ret, "test %s %s", test_cases[index].name,
> + ret ? "failed" : "success");
> + } else {
> + tst_brkm(TBROK, cleanup, "test %s failed",
> + test_cases[index].name);
> + }
> + } else {
> + tst_brkm(TBROK, cleanup, "%s clone() exit abnormally",
> + test_cases[index].name);
> + }
> +}
> +
> +static void wait_child(pid_t child, int index)
> +{
> + int status;
> + pid_t exit_pid;
> +
> + exit_pid = wait(&status);
> + if (exit_pid == -1) {
> + tst_brkm(TBROK | TERRNO, cleanup, "%s wait failed",
> + test_cases[index].name);
> + } else if (test_cases[index].flags & CLONE_PARENT) {
> + if (exit_pid != child)
> + show_test_result(status, index);
> + } else {
> + show_test_result(status, index);
> + }
> +}
> +
> +static void setup(void)
> +{
> + tst_sig(FORK, DEF_HANDLER, cleanup);
> +
> + TEST_PAUSE;
> +
> + tst_tmpdir();
> +
> + child_stack = SAFE_MALLOC(NULL, CHILD_STACK_SIZE);
> +}
> +
> +static void cleanup(void)
> +{
> + free(child_stack);
> +
> + tst_rmdir();
> +
> + TEST_CLEANUP;
> +}
> +
> +static int child_clone_parent(void)
> +{
> + if (parent_ppid == getppid())
> + tst_result = TPASS;
> + else
> + tst_result = TFAIL;
> + exit(tst_result);
> +}
> +
> +static int child_clone_child_settid(void)
> +{
> + if (ctid == getpid())
> + tst_result = TPASS;
> + else
> + tst_result = TFAIL;
> +
> + exit(tst_result);
> +}
> +
> +static int child_clone_parent_settid(void)
> +{
> + if (ptid == getpid())
> + tst_result = TPASS;
> + else
> + tst_result = TFAIL;
> +
> + exit(tst_result);
> +}
> +
> +#ifdef CLONE_STOPPED
> +static void test_clone_stopped(int tid)
> +{
> + int i;
> +
> + /* give the kernel scheduler chance to run the CLONE_STOPPED thread*/
> + for (i = 0; i < 100; i++) {
> + sched_yield();
> + usleep(1000);
> + }
> + /*
> + * if stopped_flag is not changed in the above time interval,
> + * we think the CLONE_STOPPED thread is stopped.
> + */
> + if (stopped_flag == 1)
> + tst_result = TFAIL;
> + else
> + tst_result = TPASS;
> +
> + if (kill(tid, SIGCONT) != 0) {
> + fprintf(stderr, "kill SIGCONT failed\n");
> + tst_result = TBROK;
> + }
> +}
> +
> +static int child_clone_stopped(void)
> +{
> + stopped_flag = 1;
> + exit(tst_result);
> +}
> +#endif
> +
> +/* check whether CLONE_THREAD thread was terminated */
> +static int check_clone_thread_terminated(pid_t tgid)
> +{
> + int i;
> + int num;
> +
> + for (i = 0; i < 5000; i++) {
> + num = get_threas_num(tgid);
> + if (num == 1)
> + return 1;
> + sched_yield();
> + usleep(1000);
> + }
> + return 0;
> +}
> +
> +static int get_threas_num(pid_t tgid)
> +{
> + FILE *fp;
> + int ret;
> + char com[BUFSIZE];
> + int thread_nums;
> +
> + ret = sprintf(com, "ls /proc/%d/task/ | wc -l", tgid);
> + if (ret < 0) {
> + fprintf(stderr, "sprintf failed\n");
> + exit(TBROK);
> + }
> +
> + fp = popen(com, "r");
> + if (!fp) {
> + fprintf(stderr, "run:ls /proc/%d/task/ | wc -l failed\n", tgid);
> + exit(TBROK);
> + }
> +
> + ret = fscanf(fp, "%d", &thread_nums);
> + if (ret != 1) {
> + fprintf(stderr,
> + "could not get the numbers of threads in current "
> + "thread group\n");
> + exit(TBROK);
> + }
> + pclose(fp);
> + return thread_nums;
> +}
> +
> +static int child_clone_thread(void)
> +{
> + if (tgid == ltp_syscall(__NR_getpid))
> + tst_result = TPASS;
> + else
> + tst_result = TFAIL;
> +
> + ltp_syscall(__NR_exit, 0);
> + return 0;
> +}
> --
> 1.8.3.1
>
>
>
>
------------------------------------------------------------------------------
Rapidly troubleshoot problems before they affect your business. Most IT
organizations don't have a clear picture of how application performance
affects their revenue. With AppDynamics, you get 100% visibility into your
Java,.NET, & PHP application. Start your 15-day FREE TRIAL of AppDynamics Pro!
http://pubads.g.doubleclick.net/gampad/clk?id=84349831&iu=/4140/ostg.clktrk
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [LTP] [PATCH v4 2/2] clone/clone08.c: add new flags
2013-12-12 16:22 ` Jan Stancek
@ 2013-12-18 5:41 ` zenglg.jy
0 siblings, 0 replies; 3+ messages in thread
From: zenglg.jy @ 2013-12-18 5:41 UTC (permalink / raw)
To: Jan Stancek; +Cc: ltp-list
On Thu, 2013-12-12 at 11:22 -0500, Jan Stancek wrote:
>
> ----- Original Message -----
> > From: "zenglg.jy" <zenglg.jy@cn.fujitsu.com>
> > To: "Jan Stancek" <jstancek@redhat.com>
> > Cc: "ltp-list" <ltp-list@lists.sourceforge.net>
> > Sent: Thursday, 12 December, 2013 12:35:36 PM
> > Subject: [PATCH v4 2/2] clone/clone08.c: add new flags
> >
> > Add new case for clone(2)
> > CLONE_PARENT
> > CLONE_CHILD_SETTID
> > CLONE_PARENT_SETTID
> > CLONE_STOPPED
> > CLONE_THREAD
> >
> > Signed-off-by: Zeng Linggang <zenglg.jy@cn.fujitsu.com>
>
> Hi,
>
> I sent a patch named "[PATCH v4b 2/2] clone/clone08.c: add new flags"
> few moments ago. It's a re-arranged v4 of your patch.
>
> I have removed the various "if" checks from main and do_master_child().
> by splitting do_master_child() into separate test_ functions for each testcase.
> I also removed check_clone_thread_terminated() and used same kind of check
> we have in test_clone_stopped().
>
> Can you have a look if you'd be OK with these changes?
>
Hi Jan,
I have reviewed your patch and it looks good, much neater than my patch v4 indeed.
Next I will be more careful to such kinds problems, thanks.
The link in the comment help me much to understand why to use ltp_syscall in cloned
child thread, :)
in test_clone_parent
- tst_brkm(TBROK | TERRNO, NULL, "test_clone_parent fork");
+ tst_brkm(TBROK | TERRNO, NULL, "test_clone_thread fork");
Thank you very much.
Zeng
> Regards,
> Jan
>
> > ---
> > runtest/ltplite | 1 +
> > runtest/stress.part3 | 1 +
> > runtest/syscalls | 1 +
> > testcases/kernel/syscalls/.gitignore | 1 +
> > testcases/kernel/syscalls/clone/clone08.c | 350
> > ++++++++++++++++++++++++++++++
> > 5 files changed, 354 insertions(+)
> > create mode 100644 testcases/kernel/syscalls/clone/clone08.c
> >
> > diff --git a/runtest/ltplite b/runtest/ltplite
> > index 2382dec..fe6cb04 100644
> > --- a/runtest/ltplite
> > +++ b/runtest/ltplite
> > @@ -127,6 +127,7 @@ clone04 clone04
> > clone05 clone05
> > clone06 clone06
> > clone07 clone07
> > +clone08 clone08
> >
> > close01 close01
> > close02 close02
> > diff --git a/runtest/stress.part3 b/runtest/stress.part3
> > index 16247e9..16b08a7 100644
> > --- a/runtest/stress.part3
> > +++ b/runtest/stress.part3
> > @@ -68,6 +68,7 @@ clone04 clone04
> > clone05 clone05
> > clone06 clone06
> > clone07 clone07
> > +clone08 clone08
> >
> > close01 close01
> > close02 close02
> > diff --git a/runtest/syscalls b/runtest/syscalls
> > index 717342e..a17fec7 100644
> > --- a/runtest/syscalls
> > +++ b/runtest/syscalls
> > @@ -85,6 +85,7 @@ clone04 clone04
> > clone05 clone05
> > clone06 clone06
> > clone07 clone07
> > +clone08 clone08
> >
> > close01 close01
> > close02 close02
> > diff --git a/testcases/kernel/syscalls/.gitignore
> > b/testcases/kernel/syscalls/.gitignore
> > index bbefb25..91cf0f1 100644
> > --- a/testcases/kernel/syscalls/.gitignore
> > +++ b/testcases/kernel/syscalls/.gitignore
> > @@ -65,6 +65,7 @@
> > /clone/clone05
> > /clone/clone06
> > /clone/clone07
> > +/clone/clone08
> > /close/close01
> > /close/close02
> > /close/close08
> > diff --git a/testcases/kernel/syscalls/clone/clone08.c
> > b/testcases/kernel/syscalls/clone/clone08.c
> > new file mode 100644
> > index 0000000..19b47c8
> > --- /dev/null
> > +++ b/testcases/kernel/syscalls/clone/clone08.c
> > @@ -0,0 +1,350 @@
> > +/*
> > + * Copyright (c) 2013 Fujitsu Ltd.
> > + * Author: Zeng Linggang <zenglg.jy@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.
> > + */
> > +
> > +#include <errno.h>
> > +#include <linux/sched.h>
> > +#include <sched.h>
> > +#include <sys/wait.h>
> > +#include "test.h"
> > +#include "usctest.h"
> > +#include "clone_platform.h"
> > +#include "safe_macros.h"
> > +#include "linux_syscall_numbers.h"
> > +
> > +#define BUFSIZE 512
> > +
> > +static pid_t parent_ppid;
> > +static pid_t ptid, ctid;
> > +static pid_t tgid;
> > +static void *child_stack;
> > +static int tst_result;
> > +
> > +static void setup(void);
> > +static void cleanup(void);
> > +
> > +static void do_master_child_setup(void);
> > +static void do_master_child(int i);
> > +static void wait_child(pid_t child, int index);
> > +
> > +static int child_clone_parent(void);
> > +
> > +static int child_clone_child_settid(void);
> > +static int child_clone_parent_settid(void);
> > +
> > +static int child_clone_thread(void);
> > +static int check_clone_thread_terminated(pid_t tgid);
> > +static int get_threas_num(pid_t tgid);
> > +
> > +#ifdef CLONE_STOPPED
> > +static int stopped_flag;
> > +static void test_clone_stopped(int tid);
> > +static int child_clone_stopped(void);
> > +#endif
> > +
> > +static struct test_case {
> > + char *name;
> > + int flags;
> > + void (*testfunc)(int);
> > + int (*do_child)();
> > +} test_cases[] = {
> > + {"CLONE_PARENT", CLONE_PARENT | SIGCHLD, NULL, child_clone_parent},
> > + {"CLONE_CHILD_SETTID", CLONE_CHILD_SETTID | CLONE_VM | SIGCHLD, NULL,
> > + child_clone_child_settid},
> > + {"CLONE_PARENT_SETTID", CLONE_PARENT_SETTID | CLONE_VM | SIGCHLD, NULL,
> > + child_clone_parent_settid},
> > +#ifdef CLONE_STOPPED
> > + {"CLONE_STOPPED", CLONE_STOPPED | CLONE_VM | SIGCHLD,
> > + test_clone_stopped, child_clone_stopped},
> > +#endif
> > + {"CLONE_THREAD", CLONE_THREAD | CLONE_SIGHAND | CLONE_VM | SIGCHLD,
> > + NULL, child_clone_thread},
> > +};
> > +
> > +char *TCID = "clone08";
> > +int TST_TOTAL = ARRAY_SIZE(test_cases);
> > +
> > +int main(int ac, char **av)
> > +{
> > + int lc;
> > + char *msg;
> > + int i;
> > + pid_t child;
> > +
> > + msg = parse_opts(ac, av, NULL, NULL);
> > + if (msg != NULL)
> > + tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
> > +
> > + setup();
> > +
> > + for (lc = 0; TEST_LOOPING(lc); lc++) {
> > +
> > + tst_count = 0;
> > +
> > + for (i = 0; i < TST_TOTAL; i++) {
> > +
> > + fflush(stdout);
> > +
> > + child = FORK_OR_VFORK();
> > + if (child < 0) {
> > + tst_brkm(TBROK, cleanup, "Fork failed");
> > + } else if (child == 0) {
> > + do_master_child(i);
> > + } else {
> > + wait_child(child, i);
> > + /*
> > + * for CLONE_PARENT, we need to wait twice and
> > + * ignore CLONE_PARENT thread return status.
> > + */
> > + if (test_cases[i].flags & CLONE_PARENT)
> > + wait_child(child, i);
> > + }
> > + }
> > + }
> > +
> > + cleanup();
> > +
> > + tst_exit();
> > +}
> > +
> > +static void do_master_child_setup(void)
> > +{
> > + parent_ppid = getppid();
> > +
> > + tgid = ltp_syscall(__NR_getpid);
> > +
> > + tst_result = TFAIL;
> > +
> > +#ifdef CLONE_STOPPED
> > + stopped_flag = 0;
> > +#endif
> > +}
> > +
> > +static void do_master_child(int i)
> > +{
> > + int status;
> > +
> > + do_master_child_setup();
> > +
> > + TEST(ltp_clone(test_cases[i].flags, test_cases[i].do_child, NULL,
> > + CHILD_STACK_SIZE, child_stack, &ptid, NULL, &ctid));
> > +
> > + if (TEST_RETURN == -1)
> > + exit(TBROK);
> > +
> > + if (test_cases[i].testfunc != NULL)
> > + test_cases[i].testfunc(TEST_RETURN);
> > +
> > + if (test_cases[i].flags & CLONE_PARENT) {
> > + /*
> > + * parent process will wait CLONE_PARENT thread to
> > + * get test result.
> > + */
> > + exit(0);
> > + } else if (test_cases[i].flags & CLONE_THREAD) {
> > + int ret;
> > +
> > + ret = check_clone_thread_terminated(tgid);
> > + if (ret == 0) {
> > + fprintf(stderr,
> > + "CLONE_THREAD thread does't terminated in "
> > + "time\n");
> > + exit(TBROK);
> > + }
> > + } else {
> > + if (wait(&status) == -1) {
> > + fprintf(stderr, "%s wait failed in do_master_child\n",
> > + test_cases[i].name);
> > + exit(TBROK);
> > + }
> > + }
> > +
> > + exit(tst_result);
> > +}
> > +
> > +void show_test_result(int status, int index)
> > +{
> > + int ret;
> > +
> > + if (WIFEXITED(status)) {
> > + ret = WEXITSTATUS(status);
> > + if (ret == TPASS || ret == TFAIL) {
> > + tst_resm(ret, "test %s %s", test_cases[index].name,
> > + ret ? "failed" : "success");
> > + } else {
> > + tst_brkm(TBROK, cleanup, "test %s failed",
> > + test_cases[index].name);
> > + }
> > + } else {
> > + tst_brkm(TBROK, cleanup, "%s clone() exit abnormally",
> > + test_cases[index].name);
> > + }
> > +}
> > +
> > +static void wait_child(pid_t child, int index)
> > +{
> > + int status;
> > + pid_t exit_pid;
> > +
> > + exit_pid = wait(&status);
> > + if (exit_pid == -1) {
> > + tst_brkm(TBROK | TERRNO, cleanup, "%s wait failed",
> > + test_cases[index].name);
> > + } else if (test_cases[index].flags & CLONE_PARENT) {
> > + if (exit_pid != child)
> > + show_test_result(status, index);
> > + } else {
> > + show_test_result(status, index);
> > + }
> > +}
> > +
> > +static void setup(void)
> > +{
> > + tst_sig(FORK, DEF_HANDLER, cleanup);
> > +
> > + TEST_PAUSE;
> > +
> > + tst_tmpdir();
> > +
> > + child_stack = SAFE_MALLOC(NULL, CHILD_STACK_SIZE);
> > +}
> > +
> > +static void cleanup(void)
> > +{
> > + free(child_stack);
> > +
> > + tst_rmdir();
> > +
> > + TEST_CLEANUP;
> > +}
> > +
> > +static int child_clone_parent(void)
> > +{
> > + if (parent_ppid == getppid())
> > + tst_result = TPASS;
> > + else
> > + tst_result = TFAIL;
> > + exit(tst_result);
> > +}
> > +
> > +static int child_clone_child_settid(void)
> > +{
> > + if (ctid == getpid())
> > + tst_result = TPASS;
> > + else
> > + tst_result = TFAIL;
> > +
> > + exit(tst_result);
> > +}
> > +
> > +static int child_clone_parent_settid(void)
> > +{
> > + if (ptid == getpid())
> > + tst_result = TPASS;
> > + else
> > + tst_result = TFAIL;
> > +
> > + exit(tst_result);
> > +}
> > +
> > +#ifdef CLONE_STOPPED
> > +static void test_clone_stopped(int tid)
> > +{
> > + int i;
> > +
> > + /* give the kernel scheduler chance to run the CLONE_STOPPED thread*/
> > + for (i = 0; i < 100; i++) {
> > + sched_yield();
> > + usleep(1000);
> > + }
> > + /*
> > + * if stopped_flag is not changed in the above time interval,
> > + * we think the CLONE_STOPPED thread is stopped.
> > + */
> > + if (stopped_flag == 1)
> > + tst_result = TFAIL;
> > + else
> > + tst_result = TPASS;
> > +
> > + if (kill(tid, SIGCONT) != 0) {
> > + fprintf(stderr, "kill SIGCONT failed\n");
> > + tst_result = TBROK;
> > + }
> > +}
> > +
> > +static int child_clone_stopped(void)
> > +{
> > + stopped_flag = 1;
> > + exit(tst_result);
> > +}
> > +#endif
> > +
> > +/* check whether CLONE_THREAD thread was terminated */
> > +static int check_clone_thread_terminated(pid_t tgid)
> > +{
> > + int i;
> > + int num;
> > +
> > + for (i = 0; i < 5000; i++) {
> > + num = get_threas_num(tgid);
> > + if (num == 1)
> > + return 1;
> > + sched_yield();
> > + usleep(1000);
> > + }
> > + return 0;
> > +}
> > +
> > +static int get_threas_num(pid_t tgid)
> > +{
> > + FILE *fp;
> > + int ret;
> > + char com[BUFSIZE];
> > + int thread_nums;
> > +
> > + ret = sprintf(com, "ls /proc/%d/task/ | wc -l", tgid);
> > + if (ret < 0) {
> > + fprintf(stderr, "sprintf failed\n");
> > + exit(TBROK);
> > + }
> > +
> > + fp = popen(com, "r");
> > + if (!fp) {
> > + fprintf(stderr, "run:ls /proc/%d/task/ | wc -l failed\n", tgid);
> > + exit(TBROK);
> > + }
> > +
> > + ret = fscanf(fp, "%d", &thread_nums);
> > + if (ret != 1) {
> > + fprintf(stderr,
> > + "could not get the numbers of threads in current "
> > + "thread group\n");
> > + exit(TBROK);
> > + }
> > + pclose(fp);
> > + return thread_nums;
> > +}
> > +
> > +static int child_clone_thread(void)
> > +{
> > + if (tgid == ltp_syscall(__NR_getpid))
> > + tst_result = TPASS;
> > + else
> > + tst_result = TFAIL;
> > +
> > + ltp_syscall(__NR_exit, 0);
> > + return 0;
> > +}
> > --
> > 1.8.3.1
> >
> >
> >
> >
------------------------------------------------------------------------------
Rapidly troubleshoot problems before they affect your business. Most IT
organizations don't have a clear picture of how application performance
affects their revenue. With AppDynamics, you get 100% visibility into your
Java,.NET, & PHP application. Start your 15-day FREE TRIAL of AppDynamics Pro!
http://pubads.g.doubleclick.net/gampad/clk?id=84349831&iu=/4140/ostg.clktrk
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2013-12-18 5:42 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-12-12 11:35 [LTP] [PATCH v4 2/2] clone/clone08.c: add new flags zenglg.jy
2013-12-12 16:22 ` Jan Stancek
2013-12-18 5:41 ` zenglg.jy
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.