From 5af3ca59ebc3189a3ba848c795bd465bbd1bd3c3 Mon Sep 17 00:00:00 2001 From: Kirill Tkhai Date: Fri, 14 Jul 2017 15:40:23 +0300 Subject: [PATCH] utils: Add sys_clone_unified() Cleanup fork() definition and make a generic function for all archs. It may be useful, when you want to add more clone flags to fork(), or if you want to pass more, than one argument to child function (glibc's clone alows only one). Signed-off-by: Kirill Tkhai Signed-off-by: Andrei Vagin --- criu/include/util.h | 3 +++ criu/util.c | 25 +++++++++++++++---------- test/zdtm/lib/test.c | 25 +++++++++++++++---------- 3 files changed, 33 insertions(+), 20 deletions(-) diff --git a/criu/include/util.h b/criu/include/util.h index 2077f44e3..20684ccf9 100644 --- a/criu/include/util.h +++ b/criu/include/util.h @@ -61,6 +61,9 @@ extern int open_pid_proc(pid_t pid); extern int close_pid_proc(void); extern int set_proc_fd(int fd); +extern pid_t sys_clone_unified(unsigned long flags, void *child_stack, void *parent_tid, + void *child_tid, unsigned long newtls); + /* * Values for pid argument of the proc opening routines below. * SELF would open file under /proc/self diff --git a/criu/util.c b/criu/util.c index 201ba096f..28fc80488 100644 --- a/criu/util.c +++ b/criu/util.c @@ -1476,20 +1476,25 @@ int getpid() return syscall(__NR_getpid); } +pid_t sys_clone_unified(unsigned long flags, void *child_stack, void *parent_tid, + void *child_tid, unsigned long newtls) +{ +#ifdef __x86_64__ + return (pid_t)syscall(__NR_clone, flags, child_stack, parent_tid, child_tid, newtls); +#elif (__i386__ || __arm__ || __aarch64__ || __powerpc64__) + return (pid_t)syscall(__NR_clone, flags, child_stack, parent_tid, newtls, child_tid); +#elif __s390x__ + return (pid_t)syscall(__NR_clone, child_stack, flags, parent_tid, child_tid, newtls); +#else +#error "Unsupported architecture" +#endif +} + /* * In glibc 2.24, fork() may fail when parent and child are * from different pid namespaces and have the same pid. */ pid_t fork() { - /* - * Two last arguments are swapped on different archs, - * but we don't care as they are zero anyway. - */ -#ifdef __s390x__ - /* See kernel/fork.c: CONFIG_CLONE_BACKWARDS2 */ - return (pid_t)syscall(__NR_clone, 0, SIGCHLD, NULL, 0, NULL); -#else - return (pid_t)syscall(__NR_clone, SIGCHLD, 0, 0, 0, 0); -#endif + return sys_clone_unified(SIGCHLD, 0, NULL, NULL, 0); } diff --git a/test/zdtm/lib/test.c b/test/zdtm/lib/test.c index fc4c82630..6dce027f0 100644 --- a/test/zdtm/lib/test.c +++ b/test/zdtm/lib/test.c @@ -297,18 +297,23 @@ void test_waitsig(void) futex_wait_while(&sig_received, 0); } +pid_t sys_clone_unified(unsigned long flags, void *child_stack, void *parent_tid, + void *child_tid, unsigned long newtls) +{ +#ifdef __x86_64__ + return (pid_t)syscall(__NR_clone, flags, child_stack, parent_tid, child_tid, newtls); +#elif (__i386__ || __arm__ || __aarch64__ ||__powerpc64__) + return (pid_t)syscall(__NR_clone, flags, child_stack, parent_tid, newtls, child_tid); +#elif __s390x__ + return (pid_t)syscall(__NR_clone, child_stack, flags, parent_tid, child_tid, newtls); +#else +#error "Unsupported architecture" +#endif +} + pid_t fork() { - /* - * Two last arguments are swapped on different archs, - * but we don't care as they are zero anyway. - */ -#ifdef __s390x__ - /* See kernel/fork.c: CONFIG_CLONE_BACKWARDS2 */ - return (pid_t)syscall(__NR_clone, 0, SIGCHLD, NULL, 0, NULL); -#else - return (pid_t)syscall(__NR_clone, SIGCHLD, 0, 0, 0, 0); -#endif + return sys_clone_unified(SIGCHLD, NULL, NULL, NULL, 0); } int getpid()