From: Christian Brauner Date: Fri, 15 May 2020 12:13:07 +0000 (+0200) Subject: process_utils: make lxc use clone3() whenever possible X-Git-Tag: lxc-5.0.0~433^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2f46fe6e7a875137fc7798f27f26365f71050419;p=thirdparty%2Flxc.git process_utils: make lxc use clone3() whenever possible No more weird api quirks between architectures and cool new features. Signed-off-by: Christian Brauner --- diff --git a/configure.ac b/configure.ac index 4e11254b5..61db4f2c1 100644 --- a/configure.ac +++ b/configure.ac @@ -623,7 +623,6 @@ AC_HEADER_MAJOR # Check for some syscalls functions AC_CHECK_FUNCS([setns pivot_root sethostname unshare rand_r confstr faccessat gettid memfd_create move_mount open_tree execveat clone3]) -# HAVE_STRUCT_CLONE_ARGS={0,1} AC_CHECK_TYPES([struct clone_args], [], [], [[#include ]]) AC_CHECK_MEMBERS([struct clone_args.set_tid],[],[],[[#include ]]) AC_CHECK_MEMBERS([struct clone_args.cgroup],[],[],[[#include ]]) diff --git a/src/lxc/process_utils.c b/src/lxc/process_utils.c index 89abddec5..7494def46 100644 --- a/src/lxc/process_utils.c +++ b/src/lxc/process_utils.c @@ -28,16 +28,8 @@ lxc_log_define(process_utils, lxc); * The nice thing about this is that we get fork() behavior. That is * lxc_raw_clone() returns 0 in the child and the child pid in the parent. */ -__returns_twice pid_t lxc_raw_clone(unsigned long flags, int *pidfd) +__returns_twice static pid_t __lxc_raw_clone(unsigned long flags, int *pidfd) { - /* - * These flags don't interest at all so we don't jump through any hoops - * of retrieving them and passing them to the kernel. - */ - errno = EINVAL; - if ((flags & (CLONE_VM | CLONE_PARENT_SETTID | CLONE_CHILD_SETTID | - CLONE_CHILD_CLEARTID | CLONE_SETTLS))) - return -EINVAL; #if defined(__s390x__) || defined(__s390__) || defined(__CRIS__) /* On s390/s390x and cris the order of the first and second arguments @@ -97,6 +89,31 @@ __returns_twice pid_t lxc_raw_clone(unsigned long flags, int *pidfd) #endif } +__returns_twice pid_t lxc_raw_clone(unsigned long flags, int *pidfd) +{ + pid_t pid; + struct lxc_clone_args args = { + .flags = flags, + .pidfd = ptr_to_u64(pidfd), + }; + + if (flags & (CLONE_VM | CLONE_PARENT_SETTID | CLONE_CHILD_SETTID | + CLONE_CHILD_CLEARTID | CLONE_SETTLS)) + return ret_errno(EINVAL); + + /* On CLONE_PARENT we inherit the parent's exit signal. */ + if (!(flags & CLONE_PARENT)) + args.exit_signal = SIGCHLD; + + pid = lxc_clone3(&args, CLONE_ARGS_SIZE_VER0); + if (pid < 0 && errno == ENOSYS) { + SYSTRACE("Falling back to legacy clone"); + return __lxc_raw_clone(flags, pidfd); + } + + return pid; +} + pid_t lxc_raw_clone_cb(int (*fn)(void *), void *args, unsigned long flags, int *pidfd) { diff --git a/src/lxc/process_utils.h b/src/lxc/process_utils.h index 879524759..4ea898a63 100644 --- a/src/lxc/process_utils.h +++ b/src/lxc/process_utils.h @@ -15,6 +15,7 @@ #include #include +#include "compiler.h" #include "config.h" #include "syscall_numbers.h" @@ -152,8 +153,14 @@ #define CLONE_ARGS_SIZE_VER2 88 /* sizeof third published struct */ #endif -#ifndef HAVE_STRUCT_CLONE_ARGS -struct clone_args { +#ifndef ptr_to_u64 +#define ptr_to_u64(ptr) ((__u64)((uintptr_t)(ptr))) +#endif +#ifndef u64_to_ptr +#define u64_to_ptr(x) ((void *)(uintptr_t)x) +#endif + +struct lxc_clone_args { __aligned_u64 flags; __aligned_u64 pidfd; __aligned_u64 child_tid; @@ -166,22 +173,10 @@ struct clone_args { __aligned_u64 set_tid_size; __aligned_u64 cgroup; }; -#endif - -struct lxc_clone_args { - struct clone_args; -#ifndef HAVE_STRUCT_CLONE_ARGS_SET_TID - __aligned_u64 set_tid; - __aligned_u64 set_tid_size; -#endif -#ifndef HAVE_STRUCT_CLONE_ARGS_CGROUP - __aligned_u64 cgroup; -#endif -}; -static inline pid_t lxc_clone3(struct lxc_clone_args *args, size_t size) +__returns_twice static inline pid_t lxc_clone3(struct lxc_clone_args *args, size_t size) { - return syscall(__NR_clone3, (struct clone_args *)args, size); + return syscall(__NR_clone3, args, size); } #if defined(__ia64__)