From: Zeng L. <zen...@cn...> - 2014-01-09 11:30:59
|
Cyril reported that clone breaks compilation on older distributions, such as SLES11 on s390 and s390x, SLES10, RHEL4. It was introduece by this patch 5f5cb63b7ddb6d1333345d6bc0759a263addfee7. So create m4/ltp-clone7args.m4 to check whether clone support 7 arguments. If HAVE_CLONE7ARGS is defined, ltp_clone7args will be defined in lib/cloner.c. When tests need pass 7 arguments to clone, ltp_clone7args should be used. When HAVE_CLONE7ARGS is not defined, make these tests return TCONF, like clone08. Signed-off-by: Zeng Linggang <zen...@cn...> --- configure.ac | 1 + include/test.h | 5 +++++ lib/cloner.c | 27 ++++++++++++++++++++++- m4/ltp-clone7args.m4 | 36 +++++++++++++++++++++++++++++++ testcases/kernel/syscalls/clone/clone08.c | 18 ++++++++++++++-- 5 files changed, 84 insertions(+), 3 deletions(-) create mode 100644 m4/ltp-clone7args.m4 diff --git a/configure.ac b/configure.ac index 4af7662..e564ee5 100644 --- a/configure.ac +++ b/configure.ac @@ -171,5 +171,6 @@ LTP_CHECK_FS_IOC_FLAGS LTP_CHECK_MREMAP_FIXED LTP_CHECK_KERNEL_DEVEL LTP_CHECK_XFS_QUOTACTL +LTP_CHECK_CLONE7ARGS AC_OUTPUT diff --git a/include/test.h b/include/test.h index ffc1c8c..6568737 100644 --- a/include/test.h +++ b/include/test.h @@ -46,6 +46,7 @@ #include "tst_checkpoint.h" #include "tst_process_state.h" #include "tst_resource.h" +#include "config.h" /* Use low 6 bits to encode test type */ #define TTYPE_MASK 0x3f @@ -200,7 +201,11 @@ int self_exec(char *argv0, char *fmt, ...); /* Functions from lib/cloner.c */ int ltp_clone(unsigned long clone_flags, int (*fn)(void *arg), void *arg, + size_t stack_size, void *stack); +#ifdef HAVE_CLONE7ARGS +int ltp_clone7args(unsigned long clone_flags, int (*fn)(void *arg), void *arg, size_t stack_size, void *stack, ...); +#endif int ltp_clone_malloc(unsigned long clone_flags, int (*fn)(void *arg), void *arg, size_t stacksize); int ltp_clone_quick(unsigned long clone_flags, int (*fn)(void *arg), diff --git a/lib/cloner.c b/lib/cloner.c index 93e3f8c..ba18a94 100644 --- a/lib/cloner.c +++ b/lib/cloner.c @@ -29,6 +29,7 @@ #include <sched.h> #include <stdarg.h> #include "test.h" +#include "config.h" #undef clone /* we want to use clone() */ @@ -51,7 +52,30 @@ extern int __clone2(int (*fn) (void *arg), void *child_stack_base, */ int ltp_clone(unsigned long clone_flags, int (*fn) (void *arg), void *arg, - size_t stack_size, void *stack, ...) + size_t stack_size, void *stack) +{ + int ret; + +#if defined(__hppa__) || defined(__metag__) + ret = clone(fn, stack, clone_flags, arg); +#elif defined(__ia64__) + ret = clone2(fn, stack, stack_size, clone_flags, arg, NULL, NULL, NULL); +#else + /* + * For archs where stack grows downwards, stack points to the topmost + * address of the memory space set up for the child stack. + */ + ret = clone(fn, (stack ? stack + stack_size : NULL), clone_flags, arg); +#endif + + return ret; +} + +#ifdef HAVE_CLONE7ARGS +/* ltp_clone7args is like ltp_clone, and supports 7 args */ +int +ltp_clone7args(unsigned long clone_flags, int (*fn)(void *arg), void *arg, + size_t stack_size, void *stack, ...) { int ret; pid_t *parent_tid, *child_tid; @@ -80,6 +104,7 @@ ltp_clone(unsigned long clone_flags, int (*fn) (void *arg), void *arg, return ret; } +#endif /* * ltp_clone_malloc: also does the memory allocation for clone with a diff --git a/m4/ltp-clone7args.m4 b/m4/ltp-clone7args.m4 new file mode 100644 index 0000000..927c9f8 --- /dev/null +++ b/m4/ltp-clone7args.m4 @@ -0,0 +1,36 @@ +dnl +dnl Copyright (c) Linux Test Project, 2013 +dnl +dnl This program is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 2 of the License, or +dnl (at your option) any later version. +dnl +dnl This program is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See +dnl the GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with this program; if not, write to the Free Software +dnl Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +dnl + +dnl +dnl LTP_CHECK_CLONE7ARGS +dnl ---------------------------- +dnl +AC_DEFUN([LTP_CHECK_CLONE7ARGS],[ +AH_TEMPLATE(HAVE_CLONE7ARGS, +[Define to 1 if clone() supports 7 arguments.]) +AC_MSG_CHECKING([for CLONE7ARGS]) +AC_TRY_LINK([#define _GNU_SOURCE + #include <sched.h> + #include <stdlib.h>], + [ + #if !defined(__ia64__) + clone(NULL, NULL, 0, NULL, NULL, NULL, NULL); + #endif + ], + AC_DEFINE(HAVE_CLONE7ARGS) AC_MSG_RESULT(yes), AC_MSG_RESULT(no)) +]) diff --git a/testcases/kernel/syscalls/clone/clone08.c b/testcases/kernel/syscalls/clone/clone08.c index ec559a3..1c2b549 100644 --- a/testcases/kernel/syscalls/clone/clone08.c +++ b/testcases/kernel/syscalls/clone/clone08.c @@ -23,6 +23,11 @@ #include "clone_platform.h" #include "safe_macros.h" #include "linux_syscall_numbers.h" +#include "config.h" + +char *TCID = "clone08"; + +#ifdef HAVE_CLONE7ARGS static pid_t ptid, ctid, tgid; static void *child_stack; @@ -76,7 +81,6 @@ static struct test_case { test_clone_thread, child_clone_thread}, }; -char *TCID = "clone08"; int TST_TOTAL = ARRAY_SIZE(test_cases); int main(int ac, char **av) @@ -122,7 +126,7 @@ static void cleanup(void) static long clone_child(const struct test_case *t, int use_tst) { - TEST(ltp_clone(t->flags, t->do_child, NULL, CHILD_STACK_SIZE, + TEST(ltp_clone7args(t->flags, t->do_child, NULL, CHILD_STACK_SIZE, child_stack, &ptid, NULL, &ctid)); if (TEST_RETURN == -1) { if (use_tst) { @@ -305,3 +309,13 @@ static int child_clone_thread(void) ltp_syscall(__NR_exit, 0); return 0; } + +#else + +int TST_TOTAL = 1; + +int main(void) +{ + tst_brkm(TCONF, NULL, "This test needs clone support 7 args"); +} +#endif -- 1.8.4.2 |