[2/3] utils: Add sys_clone_unified()

Submitted by Kirill Tkhai on June 30, 2017, 5:03 p.m.

Details

Message ID 149884218668.5013.16123437848805383865.stgit@localhost.localdomain
State New
Series "Create pid_ns helpers as children of criu main task"
Headers show

Commit Message

Kirill Tkhai June 30, 2017, 5:03 p.m.
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 <ktkhai@virtuozzo.com>
---
 criu/include/util.h  |    3 +++
 criu/util.c          |   16 +++++++++++++++-
 test/zdtm/lib/test.c |   20 +++++++++++++++-----
 3 files changed, 33 insertions(+), 6 deletions(-)

Patch hide | download patch | download mbox

diff --git a/criu/include/util.h b/criu/include/util.h
index ec93fd5c6..3285c30ce 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 db484f2f8..ecbd07e6a 100644
--- a/criu/util.c
+++ b/criu/util.c
@@ -1417,6 +1417,20 @@  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.
@@ -1427,5 +1441,5 @@  pid_t fork()
 	 * Two last arguments are swapped on different archs,
 	 * but we don't care as they are zero anyway.
 	 */
-	return (pid_t)syscall(__NR_clone, SIGCHLD, 0, 0, 0, 0);
+	return sys_clone_unified(SIGCHLD, 0, NULL, NULL, 0);
 }
diff --git a/test/zdtm/lib/test.c b/test/zdtm/lib/test.c
index 76357da01..620dcfce6 100644
--- a/test/zdtm/lib/test.c
+++ b/test/zdtm/lib/test.c
@@ -286,13 +286,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.
-	 */
-	return (pid_t)syscall(__NR_clone, SIGCHLD, 0, 0, 0, 0);
+	return sys_clone_unified(SIGCHLD, NULL, NULL, NULL, 0);
 }
 
 int getpid()

Comments

Michael Holzheu June 30, 2017, 5:47 p.m.
Am Fri, 30 Jun 2017 20:03:06 +0300
schrieb Kirill Tkhai <ktkhai@virtuozzo.com>:

> 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 <ktkhai@virtuozzo.com>
> ---
>  criu/include/util.h  |    3 +++
>  criu/util.c          |   16 +++++++++++++++-
>  test/zdtm/lib/test.c |   20 +++++++++++++++-----
>  3 files changed, 33 insertions(+), 6 deletions(-)
> 
> diff --git a/criu/include/util.h b/criu/include/util.h
> index ec93fd5c6..3285c30ce 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 db484f2f8..ecbd07e6a 100644
> --- a/criu/util.c
> +++ b/criu/util.c
> @@ -1417,6 +1417,20 @@ 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.
> @@ -1427,5 +1441,5 @@ pid_t fork()
>  	 * Two last arguments are swapped on different archs,
>  	 * but we don't care as they are zero anyway.
>  	 */
> -	return (pid_t)syscall(__NR_clone, SIGCHLD, 0, 0, 0, 0);
> +	return sys_clone_unified(SIGCHLD, 0, NULL, NULL, 0);
>  }
> diff --git a/test/zdtm/lib/test.c b/test/zdtm/lib/test.c
> index 76357da01..620dcfce6 100644
> --- a/test/zdtm/lib/test.c
> +++ b/test/zdtm/lib/test.c
> @@ -286,13 +286,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);

Looks good for s390x, thanks!
Michael