----- Original Message -----
> From: "zenglg.jy" <[email protected]>
> To: "chrubis" <[email protected]>
> Cc: "ltp-list" <[email protected]>
> Sent: Tuesday, 19 November, 2013 3:06:20 PM
> Subject: [LTP] [PATCH v2] clone/clone08.c: Add new flags
> 
> Add new case for clone(2) with CLONE_PARENT, CLONE_CHILD_SETTID,
> CLONE_PARENT_SETTID, CLONE_STOPPED, CLONE_THREAD.
> 
> Signed-off-by: Zeng Linggang <[email protected]>
> ---
>  runtest/ltplite                           |   1 +
>  runtest/stress.part3                      |   1 +
>  runtest/syscalls                          |   1 +
>  testcases/kernel/syscalls/.gitignore      |   1 +
>  testcases/kernel/syscalls/clone/clone08.c | 238
>  ++++++++++++++++++++++++++++++
>  5 files changed, 242 insertions(+)
>  create mode 100644 testcases/kernel/syscalls/clone/clone08.c
> 
> diff --git a/runtest/ltplite b/runtest/ltplite
> index f0738c7..71dbb5e 100644
> --- a/runtest/ltplite
> +++ b/runtest/ltplite
> @@ -126,6 +126,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 951b00e..8c42e1b 100644
> --- a/runtest/stress.part3
> +++ b/runtest/stress.part3
> @@ -67,6 +67,7 @@ clone04 clone04
>  clone05 clone05
>  clone06 clone06
>  clone07 clone07
> +clone08 clone08
>  
>  close01 close01
>  close02 close02
> diff --git a/runtest/syscalls b/runtest/syscalls
> index e5a5508..33cb11c 100644
> --- a/runtest/syscalls
> +++ b/runtest/syscalls
> @@ -84,6 +84,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 0effa6b..35dd2c5 100644
> --- a/testcases/kernel/syscalls/.gitignore
> +++ b/testcases/kernel/syscalls/.gitignore
> @@ -64,6 +64,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..8eebb4d
> --- /dev/null
> +++ b/testcases/kernel/syscalls/clone/clone08.c
> @@ -0,0 +1,238 @@
> +/*
> + * Copyright (c) 2013 Fujitsu Ltd.
> + * Author: Zeng Linggang <[email protected]>
> + *
> + * 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 "linux_syscall_numbers.h"
> +#include "safe_macros.h"
> +
> +#define PASS         0
> +#define FAIL         1
> +#define SIG_PASS     SIGUSR1
> +#define SIG_FAIL     SIGUSR2
> +
> +
> +static pid_t parent_ppid;
> +static pid_t ptid, ctid;
> +static pid_t tgid;
> +static void *child_stack;
> +static int test_index;
> +
> +static void setup(void);
> +static void cleanup(void);
> +
> +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 void test_clone_parent_settid(int tid);
> +static void sig_func(int signo);
> +
> +#ifdef CLONE_STOPPED
> +static int thread_state;
> +static void test_clone_stopped(int tid);
> +static int child_clone_stopped(void);
> +#endif
> +
> +static int notwait_flag = CLONE_PARENT | CLONE_THREAD;
> +static struct test_case {
> +     char *name;
> +     int flags;
> +     void (*testfunc)(int tid);
> +     int (*do_child)();
> +} test_cases[] = {
> +     {"CLONE_PARENT", CLONE_PARENT, NULL, child_clone_parent},
> +     {"CLONE_CHILD_SETTID", CLONE_CHILD_SETTID | SIGCHLD, NULL,
> +      child_clone_child_settid},
> +     {"CLONE_PARENT_SETTID", CLONE_PARENT_SETTID | SIGCHLD,
> +      test_clone_parent_settid, child_clone_parent_settid},
> +#ifdef CLONE_STOPPED
> +     {"CLONE_STOPPED", CLONE_STOPPED | SIGCHLD, test_clone_stopped,
> +      child_clone_stopped},
> +#endif
> +     {"CLONE_THREAD", CLONE_THREAD | CLONE_SIGHAND | CLONE_VM, NULL,
> +      child_clone_thread},
> +};
> +
> +char *TCID = "clone08";
> +int TST_TOTAL = ARRAY_SIZE(test_cases);
> +
> +int main(int ac, char **av)
> +{
> +     int lc;
> +     int i = 0;
> +     int status;
> +
> +     setup();
> +
> +     for (lc = 0; TEST_LOOPING(lc); lc++) {
> +             tst_count = 0;
> +
> +             for (i = 0; i < TST_TOTAL; i++) {
> +                     test_index = i;
> +                     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) {
> +                             tst_brkm(TFAIL | TTERRNO, cleanup,
> +                                      "%s clone() failed",
> +                                      test_cases[i].name);
> +                             continue;
> +                     }
> +
> +                     if (test_cases[i].testfunc != NULL)
> +                             test_cases[i].testfunc(TEST_RETURN);
> +
> +                     if ((test_cases[i].flags & notwait_flag) == 0) {
> +                             if (wait(&status) == -1) {
> +                                     tst_brkm(TBROK | TERRNO, cleanup,
> +                                              "wait failed, status: %d",
> +                                              status);
> +                             }
> +                             if (test_cases[i].testfunc != NULL)
> +                                     continue;
> +                             if (WIFEXITED(status) &&
> +                                 WEXITSTATUS(status) == PASS) {
> +                                     tst_resm(TPASS, "test %s success",
> +                                              test_cases[i].name);
> +                             } else {
> +                                     tst_resm(TFAIL, "test %s fail",
> +                                              test_cases[i].name);
> +                             }
> +                     } else {
> +                             /*
> +                              * wait cloned thread to wake us, and verify
> +                              * the test result in the signal hander
> +                              */
> +                             pause();
> +                     }
> +             }
> +     }
> +
> +     cleanup();
> +     tst_exit();
> +}
> +
> +static void setup(void)
> +{
> +     tst_sig(FORK, DEF_HANDLER, cleanup);
> +     TEST_PAUSE;
> +
> +     parent_ppid = getppid();
> +     tgid = getpid();
> +
> +     if (signal(SIG_PASS, sig_func) == SIG_ERR)
> +             tst_brkm(TBROK | TERRNO, cleanup, "signal failed");
> +     if (signal(SIG_FAIL, sig_func) == SIG_ERR)
> +             tst_brkm(TBROK | TERRNO, cleanup, "signal failed");
> +
> +     child_stack = SAFE_MALLOC(cleanup, CHILD_STACK_SIZE);
> +}
> +
> +static void cleanup(void)
> +{
> +     free(child_stack);
> +
> +     TEST_CLEANUP;
> +}
> +
> +static int child_clone_parent()
> +{
> +     usleep(500000);
> +     if (parent_ppid == getppid())
> +             kill(tgid, SIG_PASS);
> +     else
> +             kill(tgid, SIG_FAIL);
> +     exit(PASS);
> +}

Hi,

why not just exit with either PASS or FAIL and parent can check the status?
You wouldn't need sleep or signals.

If you need parent/child synchronization, then consider "checkpoints" 
(lib/tst_checkpoint.c)

> +
> +static void sig_func(int signo)
> +{
> +     if (signo != SIG_PASS)
> +             tst_resm(TFAIL, "test %s fail", test_cases[test_index].name);
> +     else
> +             tst_resm(TPASS, "test %s success", test_cases[test_index].name);
> +}
> +
> +static int child_clone_child_settid()
> +{
> +     if (ctid != getpid())
> +             exit(FAIL);
> +     else
> +             exit(PASS);
> +}
> +
> +static void test_clone_parent_settid(int tid)
> +{
> +     if (tid != ptid)
> +             tst_resm(TFAIL, "test CLONE_PARENT_SETTID fail");
> +     else
> +             tst_resm(TPASS, "test CLONE_PARENT_SETTID success");
> +}
> +
> +static int child_clone_parent_settid()
> +{
> +     exit(PASS);
> +}
> +
> +#ifdef CLONE_STOPPED
> +static void test_clone_stopped(int tid)
> +{
> +     int i;
> +
> +     /* give the kernel scheduler chance to run the child */
> +     for (i = 0; i < 100; i++) {
> +             sched_yield();
> +             usleep(1000);
> +     }
> +     if (thread_state == 0)

Does the child have even chance to change this value in parent without CLONE_VM?

> +             tst_resm(TPASS, "test CLONE_STOPPED success");
> +     else
> +             tst_resm(TFAIL, "test CLONE_STOPPED fail");
> +
> +     if (kill(tid, SIGCONT) != 0)
> +             tst_brkm(TBROK | TERRNO, cleanup, "kill SIGCONT failed");
> +}
> +
> +static int child_clone_stopped()
> +{
> +     thread_state = 1;

thread_state should be reset to 0 before this test, in case you run it in loop 
(-i parameter).

> +     exit(PASS);
> +}
> +#endif
> +
> +static int child_clone_thread(void)
> +{
> +     pid_t child_tgid;
> +
> +     child_tgid = getpid();
> +
> +     if (tgid == child_tgid)
> +             kill(tgid, SIG_PASS);
> +     else
> +             kill(tgid, SIG_FAIL);
> +     usleep(500000);
> +     exit(PASS);
> +}

Same as above, why not just return PASS or FAIL and check status in parent?

Regards,
Jan

> --
> 1.8.2.1
> 
> 
> 
> 
> ------------------------------------------------------------------------------
> Shape the Mobile Experience: Free Subscription
> Software experts and developers: Be at the forefront of tech innovation.
> Intel(R) Software Adrenaline delivers strategic insight and game-changing
> conversations that shape the rapidly evolving mobile landscape. Sign up now.
> http://pubads.g.doubleclick.net/gampad/clk?id=63431311&iu=/4140/ostg.clktrk
> _______________________________________________
> Ltp-list mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/ltp-list
> 

------------------------------------------------------------------------------
Shape the Mobile Experience: Free Subscription
Software experts and developers: Be at the forefront of tech innovation.
Intel(R) Software Adrenaline delivers strategic insight and game-changing 
conversations that shape the rapidly evolving mobile landscape. Sign up now. 
http://pubads.g.doubleclick.net/gampad/clk?id=63431311&iu=/4140/ostg.clktrk
_______________________________________________
Ltp-list mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ltp-list

Reply via email to