]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
process_utils: make lxc use clone3() whenever possible
authorChristian Brauner <christian.brauner@ubuntu.com>
Fri, 15 May 2020 12:13:07 +0000 (14:13 +0200)
committerChristian Brauner <christian.brauner@ubuntu.com>
Fri, 15 May 2020 14:08:31 +0000 (16:08 +0200)
No more weird api quirks between architectures and cool new features.

Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
configure.ac
src/lxc/process_utils.c
src/lxc/process_utils.h

index 4e11254b5b44b6af112cc3b97275ab3d70d12ad6..61db4f2c1fd823d25a5804ec49fc6cdeca02af67 100644 (file)
@@ -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 <linux/sched.h>]])
 AC_CHECK_MEMBERS([struct clone_args.set_tid],[],[],[[#include <linux/sched.h>]])
 AC_CHECK_MEMBERS([struct clone_args.cgroup],[],[],[[#include <linux/sched.h>]])
index 89abddec54d19f01e5444809ce9a7c0c591898d7..7494def46b4897284504db5c214185112f6636bb 100644 (file)
@@ -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)
 {
index 8795247596880040f74be823eef9ec4aa2041d57..4ea898a6331686d301ebb2dd3c1534d6608db7c2 100644 (file)
@@ -15,6 +15,7 @@
 #include <sys/syscall.h>
 #include <unistd.h>
 
+#include "compiler.h"
 #include "config.h"
 #include "syscall_numbers.h"
 
 #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__)