Clone allows more flexible control. Currently, if there is any inherited fd,
lxc-start exits with error. With clone it's possible not to pass open fd's to 
childs.

Signed-off-by: Vladimir Smirnov <ci...@yandex-team.ru>
---
 src/lxc/lxc_attach.c |   79 +++++++++++++++++++++++++++++---------------------
 src/lxc/lxc_init.c   |   46 ++++++++++++++++++-----------
 2 files changed, 75 insertions(+), 50 deletions(-)

diff --git a/src/lxc/lxc_attach.c b/src/lxc/lxc_attach.c
index ed3d5a4..930865e 100644
--- a/src/lxc/lxc_attach.c
+++ b/src/lxc/lxc_attach.c
@@ -20,6 +20,7 @@
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
+#define STACKSIZE 16384
 
 #define _GNU_SOURCE
 #include <unistd.h>
@@ -29,6 +30,7 @@
 #include <sys/param.h>
 #include <sys/types.h>
 #include <sys/wait.h>
+#include <sched.h>
 
 #include "commands.h"
 #include "arguments.h"
@@ -56,14 +58,48 @@ Options :\n\
        .checker  = NULL,
 };
 
+static char *envp_global;
+
+int child_main()
+{
+       struct passwd *passwd;
+       uid_t uid;
+
+       if (my_args.argc) {
+               execve(my_args.argv[0], my_args.argv, envp_global);
+               SYSERROR("failed to exec '%s'", my_args.argv[0]);
+               return -1;
+       }
+
+       uid = getuid();
+
+       passwd = getpwuid(uid);
+       if (!passwd) {
+               SYSERROR("failed to get passwd "                \
+                        "entry for uid '%d'", uid);
+               return -1;
+       }
+
+       {
+               char *const args[] = {
+                       passwd->pw_shell,
+                       NULL,
+               };
+
+               execve(args[0], args, envp_global);
+               SYSERROR("failed to exec '%s'", args[0]);
+               return -1;
+       }
+}
+
 int main(int argc, char *argv[], char *envp[])
 {
        int ret;
        pid_t pid;
-       struct passwd *passwd;
-       uid_t uid;
        char *curdir;
 
+       envp_global = envp;
+
        ret = lxc_caps_init();
        if (ret)
                return ret;
@@ -96,7 +132,14 @@ int main(int argc, char *argv[], char *envp[])
 
        free(curdir);
 
-       pid = fork();
+       void **newstack;
+       newstack = (void **) malloc(STACKSIZE);
+       if (!newstack)
+               exit(newstack);
+
+       newstack = (void **)(STACKSIZE + (char *)newstack);
+       *--newstack = 0;
+       pid = clone(child_main, newstack, CLONE_VM | CLONE_FS | CLONE_SIGHAND, 
0);
 
        if (pid < 0) {
                SYSERROR("failed to fork");
@@ -120,35 +163,5 @@ int main(int argc, char *argv[], char *envp[])
                return -1;
        }
 
-       if (!pid) {
-
-               if (my_args.argc) {
-                       execve(my_args.argv[0], my_args.argv, envp);
-                       SYSERROR("failed to exec '%s'", my_args.argv[0]);
-                       return -1;
-               }
-
-               uid = getuid();
-
-               passwd = getpwuid(uid);
-               if (!passwd) {
-                       SYSERROR("failed to get passwd "                \
-                                "entry for uid '%d'", uid);
-                       return -1;
-               }
-
-               {
-                       char *const args[] = {
-                               passwd->pw_shell,
-                               NULL,
-                       };
-
-                       execve(args[0], args, envp);
-                       SYSERROR("failed to exec '%s'", args[0]);
-                       return -1;
-               }
-
-       }
-
        return 0;
 }
diff --git a/src/lxc/lxc_init.c b/src/lxc/lxc_init.c
index a534b51..7debd6f 100644
--- a/src/lxc/lxc_init.c
+++ b/src/lxc/lxc_init.c
@@ -20,6 +20,7 @@
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
+#define STACKSIZE 16384
 
 #include <stdio.h>
 #include <unistd.h>
@@ -32,6 +33,7 @@
 #include <sys/wait.h>
 #define _GNU_SOURCE
 #include <getopt.h>
+#include <sched.h>
 
 #include "log.h"
 #include "caps.h"
@@ -40,6 +42,9 @@
 
 lxc_log_define(lxc_init, lxc);
 
+static sigset_t mask, omask;
+static char **aargv;
+
 static int quiet;
 
 static struct option options[] = {
@@ -49,6 +54,23 @@ static struct option options[] = {
 
 static int was_interrupted = 0;
 
+int child_main()
+{
+       int i;
+       int err = -1;
+       /* restore default signal handlers */
+       for (i = 1; i < NSIG; i++)
+               signal(i, SIG_DFL);
+
+       sigprocmask(SIG_SETMASK, &omask, NULL);
+
+       NOTICE("about to exec '%s'", aargv[0]);
+
+       execvp(aargv[0], aargv);
+       ERROR("failed to exec: '%s' : %m", aargv[0]);
+       exit(err);
+}
+
 int main(int argc, char *argv[])
 {
 
@@ -61,8 +83,6 @@ int main(int argc, char *argv[])
        pid_t pid;
        int nbargs = 0;
        int err = -1;
-       char **aargv;
-       sigset_t mask, omask;
        int i, shutdown = 0;
 
        while (1) {
@@ -115,25 +135,17 @@ int main(int argc, char *argv[])
        if (lxc_caps_reset())
                exit(err);
 
-       pid = fork();
-
-       if (pid < 0)
+       void **newstack;
+       newstack = (void **) malloc(STACKSIZE);
+       if (!newstack)
                exit(err);
 
-       if (!pid) {
-
-               /* restore default signal handlers */
-               for (i = 1; i < NSIG; i++)
-                       signal(i, SIG_DFL);
+       newstack = (void **)(STACKSIZE + (char *)newstack);
+       *--newstack = 0;
+       pid = clone(child_main, newstack, CLONE_VM | CLONE_FS | CLONE_SIGHAND, 
0);
 
-               sigprocmask(SIG_SETMASK, &omask, NULL);
-
-               NOTICE("about to exec '%s'", aargv[0]);
-
-               execvp(aargv[0], aargv);
-               ERROR("failed to exec: '%s' : %m", aargv[0]);
+       if (pid < 0)
                exit(err);
-       }
 
        /* let's process the signals now */
        sigdelset(&omask, SIGALRM);
-- 
1.7.6


------------------------------------------------------------------------------
EMC VNX: the world's simplest storage, starting under $10K
The only unified storage solution that offers unified management 
Up to 160% more powerful than alternatives and 25% more efficient. 
Guaranteed. http://p.sf.net/sfu/emc-vnx-dev2dev
_______________________________________________
Lxc-devel mailing list
Lxc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lxc-devel

Reply via email to