]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
clone: add infrastructure for CLONE_PIDFD 2984/head
authorChristian Brauner <christian.brauner@ubuntu.com>
Thu, 9 May 2019 13:01:27 +0000 (15:01 +0200)
committerChristian Brauner <christian.brauner@ubuntu.com>
Thu, 9 May 2019 13:01:27 +0000 (15:01 +0200)
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=eac7078a0fff1e72cf2b641721e3f55ec7e5e21e

Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
src/lxc/attach.c
src/lxc/conf.c
src/lxc/raw_syscalls.c
src/lxc/raw_syscalls.h
src/lxc/start.c
src/lxc/utils.c
src/tests/lxc_raw_clone.c

index 9d37793e5cfdea0112568bc561265215b34137a9..ce51352c67df5f08f5f88ea072d77546f6832356 100644 (file)
@@ -1426,7 +1426,7 @@ int lxc_attach(const char *name, const char *lxcpath,
        payload.exec_function = exec_function;
        payload.exec_payload = exec_payload;
 
-       pid = lxc_raw_clone(CLONE_PARENT);
+       pid = lxc_raw_clone(CLONE_PARENT, NULL);
        if (pid < 0) {
                SYSERROR("Failed to clone attached process");
                shutdown(ipc_sockets[1], SHUT_RDWR);
index ec9543f743de8ba1ced5f1ca2ed57520cff84346..2515c881ef0d7916a47d9e4e8d992fec9ea65a33 100644 (file)
@@ -4337,7 +4337,7 @@ int userns_exec_1(struct lxc_conf *conf, int (*fn)(void *), void *data,
        d.p[1] = p[1];
 
        /* Clone child in new user namespace. */
-       pid = lxc_raw_clone_cb(run_userns_fn, &d, CLONE_NEWUSER);
+       pid = lxc_raw_clone_cb(run_userns_fn, &d, CLONE_NEWUSER, NULL);
        if (pid < 0) {
                ERROR("Failed to clone process in new user namespace");
                goto on_error;
index bbf5409b0fc4560c1a4bbd9f68887629a2bdb611..f58b8d89876211d457ee1829096f6064e5bf9ab5 100644 (file)
@@ -33,7 +33,7 @@ int lxc_raw_execveat(int dirfd, const char *pathname, char *const argv[],
  * 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)
+__returns_twice 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
@@ -48,7 +48,7 @@ __returns_twice pid_t lxc_raw_clone(unsigned long flags)
        /* On s390/s390x and cris the order of the first and second arguments
         * of the system call is reversed.
         */
-       return syscall(__NR_clone, NULL, flags | SIGCHLD);
+       return syscall(__NR_clone, NULL, flags | SIGCHLD, pidfd);
 #elif defined(__sparc__) && defined(__arch64__)
        {
                /*
@@ -59,6 +59,7 @@ __returns_twice pid_t lxc_raw_clone(unsigned long flags)
                register long g1 asm("g1") = __NR_clone;
                register long o0 asm("o0") = flags | SIGCHLD;
                register long o1 asm("o1") = 0; /* is parent/child indicator */
+               register long o2 asm("o2") = (unsigned long)pidfd;
                long is_error, retval, in_child;
                pid_t child_pid;
 
@@ -74,9 +75,9 @@ __returns_twice pid_t lxc_raw_clone(unsigned long flags)
                     * full register.
                     */
                    "addx %%g0, 0, %g1"
-                   : "=r"(g1), "=r"(o0), "=r"(o1) /* outputs */
-                   : "r"(g1), "r"(o0), "r"(o1)    /* inputs */
-                   : "%cc");                      /* clobbers */
+                   : "=r"(g1), "=r"(o0), "=r"(o1), "=r"(o2) /* outputs */
+                   : "r"(g1), "r"(o0), "r"(o1), "r"(o2)     /* inputs */
+                   : "%cc");                                /* clobbers */
 
                is_error = g1;
                retval = o0;
@@ -95,17 +96,18 @@ __returns_twice pid_t lxc_raw_clone(unsigned long flags)
        }
 #elif defined(__ia64__)
        /* On ia64 the stack and stack size are passed as separate arguments. */
-       return syscall(__NR_clone, flags | SIGCHLD, NULL, prctl_arg(0));
+       return syscall(__NR_clone, flags | SIGCHLD, NULL, prctl_arg(0), pidfd);
 #else
-       return syscall(__NR_clone, flags | SIGCHLD, NULL);
+       return syscall(__NR_clone, flags | SIGCHLD, NULL, pidfd);
 #endif
 }
 
-pid_t lxc_raw_clone_cb(int (*fn)(void *), void *args, unsigned long flags)
+pid_t lxc_raw_clone_cb(int (*fn)(void *), void *args, unsigned long flags,
+                      int *pidfd)
 {
        pid_t pid;
 
-       pid = lxc_raw_clone(flags);
+       pid = lxc_raw_clone(flags, pidfd);
        if (pid < 0)
                return -1;
 
index 6c27f26a0b013302e3ba884db0ecb63b3e7ade03..82ff47dfd8662800eb6e1bb36f71117b0abc103f 100644 (file)
 #include <sys/syscall.h>
 #include <unistd.h>
 
+/* clone */
+#ifndef CLONE_PIDFD
+#define CLONE_PIDFD 0x00001000
+#endif
+
 /*
  * lxc_raw_clone() - create a new process
  *
@@ -57,7 +62,7 @@
  * - must call lxc_raw_getpid():
  *   The child must use lxc_raw_getpid() to retrieve its pid.
  */
-extern pid_t lxc_raw_clone(unsigned long flags);
+extern pid_t lxc_raw_clone(unsigned long flags, int *pidfd);
 
 /*
  * lxc_raw_clone_cb() - create a new process
@@ -70,7 +75,8 @@ extern pid_t lxc_raw_clone(unsigned long flags);
  * All other comments that apply to lxc_raw_clone() apply to lxc_raw_clone_cb()
  * as well.
  */
-extern pid_t lxc_raw_clone_cb(int (*fn)(void *), void *args, unsigned long flags);
+extern pid_t lxc_raw_clone_cb(int (*fn)(void *), void *args,
+                             unsigned long flags, int *pidfd);
 
 extern int lxc_raw_execveat(int dirfd, const char *pathname, char *const argv[],
                            char *const envp[], int flags);
index 651511dbe35d008106bf4dd83da9c2ae0d0b351e..34798292cfe86287f002326b6482575489e4aa14 100644 (file)
@@ -1601,7 +1601,7 @@ static inline int do_share_ns(void *arg)
 
        flags = handler->ns_on_clone_flags;
        flags |= CLONE_PARENT;
-       handler->pid = lxc_raw_clone_cb(do_start, handler, flags);
+       handler->pid = lxc_raw_clone_cb(do_start, handler, flags, NULL);
        if (handler->pid < 0)
                return -1;
 
@@ -1748,7 +1748,7 @@ static int lxc_spawn(struct lxc_handler *handler)
                }
        } else {
                handler->pid = lxc_raw_clone_cb(do_start, handler,
-                                               handler->ns_on_clone_flags);
+                                               handler->ns_on_clone_flags, NULL);
        }
        if (handler->pid < 0) {
                SYSERROR(LXC_CLONE_ERROR);
index ea081c566c842e67036f1f1855c17181c720aea4..331e216793cf77166da723422546422374d9a53b 100644 (file)
@@ -1609,7 +1609,7 @@ int run_command_internal(char *buf, size_t buf_size, int (*child_fn)(void *), vo
                return -1;
        }
 
-       child = lxc_raw_clone(0);
+       child = lxc_raw_clone(0, NULL);
        if (child < 0) {
                close(pipefd[0]);
                close(pipefd[1]);
index 63a836176401f4e5902f6fa5257ea6f30257d3ca..655454f39529ae66975ec0049611c4061baac067 100644 (file)
@@ -48,42 +48,42 @@ int main(int argc, char *argv[])
        pid_t pid;
        int flags = 0;
 
-       pid = lxc_raw_clone(CLONE_PARENT_SETTID);
+       pid = lxc_raw_clone(CLONE_PARENT_SETTID, NULL);
        if (pid >= 0 || pid != -EINVAL) {
                lxc_error("%s\n", "Calling lxc_raw_clone(CLONE_PARENT_SETTID) "
                                  "should not be possible");
                exit(EXIT_FAILURE);
        }
 
-       pid = lxc_raw_clone(CLONE_CHILD_SETTID);
+       pid = lxc_raw_clone(CLONE_CHILD_SETTID, NULL);
        if (pid >= 0 || pid != -EINVAL) {
                lxc_error("%s\n", "Calling lxc_raw_clone(CLONE_CHILD_SETTID) "
                                  "should not be possible");
                exit(EXIT_FAILURE);
        }
 
-       pid = lxc_raw_clone(CLONE_CHILD_CLEARTID);
+       pid = lxc_raw_clone(CLONE_CHILD_CLEARTID, NULL);
        if (pid >= 0 || pid != -EINVAL) {
                lxc_error("%s\n", "Calling lxc_raw_clone(CLONE_CHILD_CLEARTID) "
                                  "should not be possible");
                exit(EXIT_FAILURE);
        }
 
-       pid = lxc_raw_clone(CLONE_SETTLS);
+       pid = lxc_raw_clone(CLONE_SETTLS, NULL);
        if (pid >= 0 || pid != -EINVAL) {
                lxc_error("%s\n", "Calling lxc_raw_clone(CLONE_SETTLS) should "
                                  "not be possible");
                exit(EXIT_FAILURE);
        }
 
-       pid = lxc_raw_clone(CLONE_VM);
+       pid = lxc_raw_clone(CLONE_VM, NULL);
        if (pid >= 0 || pid != -EINVAL) {
                lxc_error("%s\n", "Calling lxc_raw_clone(CLONE_VM) should "
                          "not be possible");
                exit(EXIT_FAILURE);
        }
 
-       pid = lxc_raw_clone(0);
+       pid = lxc_raw_clone(0, NULL);
        if (pid < 0) {
                lxc_error("%s\n", "Failed to call lxc_raw_clone(0)");
                exit(EXIT_FAILURE);
@@ -100,7 +100,7 @@ int main(int argc, char *argv[])
                exit(EXIT_FAILURE);
        }
 
-       pid = lxc_raw_clone(0);
+       pid = lxc_raw_clone(0, NULL);
        if (pid < 0) {
                lxc_error("%s\n", "Failed to call lxc_raw_clone(0)");
                exit(EXIT_FAILURE);
@@ -127,7 +127,7 @@ int main(int argc, char *argv[])
        flags |= CLONE_NEWPID;
        flags |= CLONE_NEWUTS;
 
-       pid = lxc_raw_clone(flags);
+       pid = lxc_raw_clone(flags, NULL);
        if (pid < 0) {
                lxc_error("%s\n", "Failed to call lxc_raw_clone(CLONE_NEWUSER "
                                  "| CLONE_NEWCGROUP | CLONE_NEWNS | "
@@ -147,7 +147,7 @@ int main(int argc, char *argv[])
                exit(EXIT_FAILURE);
        }
 
-       pid = lxc_raw_clone(flags);
+       pid = lxc_raw_clone(flags, NULL);
        if (pid < 0) {
                lxc_error("%s\n", "Failed to call lxc_raw_clone(CLONE_NEWUSER "
                                  "| CLONE_NEWCGROUP | CLONE_NEWNS | "
@@ -168,7 +168,7 @@ int main(int argc, char *argv[])
                exit(EXIT_FAILURE);
        }
 
-       pid = lxc_raw_clone(CLONE_VFORK);
+       pid = lxc_raw_clone(CLONE_VFORK, NULL);
        if (pid < 0) {
                lxc_error("%s\n", "Failed to call lxc_raw_clone(CLONE_VFORK);");
                exit(EXIT_FAILURE);
@@ -185,7 +185,7 @@ int main(int argc, char *argv[])
                exit(EXIT_FAILURE);
        }
 
-       pid = lxc_raw_clone(CLONE_VFORK);
+       pid = lxc_raw_clone(CLONE_VFORK, NULL);
        if (pid < 0) {
                lxc_error("%s\n", "Failed to call lxc_raw_clone(CLONE_VFORK);");
                exit(EXIT_FAILURE);
@@ -202,7 +202,7 @@ int main(int argc, char *argv[])
                exit(EXIT_FAILURE);
        }
 
-       pid = lxc_raw_clone(CLONE_FILES);
+       pid = lxc_raw_clone(CLONE_FILES, NULL);
        if (pid < 0) {
                lxc_error("%s\n", "Failed to call lxc_raw_clone(CLONE_FILES);");
                exit(EXIT_FAILURE);
@@ -219,7 +219,7 @@ int main(int argc, char *argv[])
                exit(EXIT_FAILURE);
        }
 
-       pid = lxc_raw_clone(CLONE_FILES);
+       pid = lxc_raw_clone(CLONE_FILES, NULL);
        if (pid < 0) {
                lxc_error("%s\n", "Failed to call lxc_raw_clone(CLONE_FILES);");
                exit(EXIT_FAILURE);