]> git.proxmox.com Git - mirror_lxc.git/blobdiff - src/lxc/start.c
Change freezer to stick with the cgroup freezer fs API, replace "RUNNING" by "THAWED"
[mirror_lxc.git] / src / lxc / start.c
index 08eb5bb1e2430b8dc7be8232618ac464ba6c5503..be32fa6bd39a22791e36a22f548bc967495040a5 100644 (file)
 #include <errno.h>
 #include <unistd.h>
 #include <signal.h>
-#include <mntent.h>
 #include <sys/param.h>
 #include <sys/file.h>
+#include <sys/mount.h>
 #include <sys/types.h>
-#include <sys/stat.h>
 #include <sys/prctl.h>
 #include <sys/wait.h>
-#include <netinet/in.h>
-#include <net/if.h>
 
-#include <lxc.h>
+#include <lxc/lxc.h>
 
 LXC_TTY_HANDLER(SIGINT);
 LXC_TTY_HANDLER(SIGQUIT);
 
+int opentty(const char *ttyname)
+{
+        int i, fd, flags;
+
+        fd = open(ttyname, O_RDWR | O_NONBLOCK);
+        if (fd == -1) {
+               lxc_log_syserror("open '%s'", ttyname);
+               return -1;
+        }
+
+        flags = fcntl(fd, F_GETFL);
+        flags &= ~O_NONBLOCK;
+        fcntl(fd, F_SETFL, flags);
+
+        for (i = 0; i < fd; i++)
+                close(i);
+        for (i = 0; i < 3; i++)
+                if (fd != i)
+                        dup2(fd, i);
+        if (fd >= 3)
+                close(fd);
+
+       return 0;
+}
+
 int lxc_start(const char *name, int argc, char *argv[], 
              lxc_callback_t prestart, void *data)
 {
        char *init = NULL, *val = NULL;
+       char ttyname[MAXPATHLEN];
        int fd, lock, sv[2], sync = 0, err = -1;
        pid_t pid;
        int clone_flags;
-       
+
        lock = lxc_get_lock(name);
        if (!lock) {
                lxc_log_error("'%s' is busy", name);
@@ -65,27 +88,29 @@ int lxc_start(const char *name, int argc, char *argv[],
                return -1;
        }
 
-       fcntl(lock, F_SETFD, FD_CLOEXEC);
-
        /* Begin the set the state to STARTING*/
        if (lxc_setstate(name, STARTING)) {
                lxc_log_error("failed to set state %s", lxc_state2str(STARTING));
                goto out;
        }
 
+       if (readlink("/proc/self/fd/0", ttyname, sizeof(ttyname)) < 0) {
+               lxc_log_syserror("failed to read '/proc/self/fd/0'");
+               goto out;
+       }
+
+
        /* Synchro socketpair */
        if (socketpair(AF_LOCAL, SOCK_STREAM, 0, sv)) {
                lxc_log_syserror("failed to create communication socketpair");
-               goto err;
+               goto out;
        }
 
        /* Avoid signals from terminal */
        LXC_TTY_ADD_HANDLER(SIGINT);
        LXC_TTY_ADD_HANDLER(SIGQUIT);
 
-       clone_flags = CLONE_NEWPID|CLONE_NEWIPC;
-       if (conf_has_fstab(name))
-               clone_flags |= CLONE_NEWNS;
+       clone_flags = CLONE_NEWPID|CLONE_NEWIPC|CLONE_NEWNS;
        if (conf_has_utsname(name))
                clone_flags |= CLONE_NEWUTS;
        if (conf_has_network(name))
@@ -125,6 +150,17 @@ int lxc_start(const char *name, int argc, char *argv[],
                        return -1;
                }
 
+               /* Open the tty */
+               if (opentty(ttyname)) {
+                       lxc_log_syserror("failed to open the tty");
+                       return -1;
+               }
+
+               if (mount(ttyname, "/dev/console", "none", MS_BIND, 0)) {
+                       lxc_log_syserror("failed to mount '/dev/console'");
+                       return -1;
+               }
+
                /* If a callback has been passed, call it before doing exec */
                if (prestart)
                        if (prestart(name, argc, argv, data)) {