From f4d507d5fe92f643dff267c87a2010a25cb7f2c4 Mon Sep 17 00:00:00 2001 From: dlezcano Date: Tue, 9 Sep 2008 14:35:44 +0000 Subject: [PATCH] Added console support --- src/lxc/start.c | 54 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 47 insertions(+), 7 deletions(-) diff --git a/src/lxc/start.c b/src/lxc/start.c index 3a99c7cc8..be32fa6bd 100644 --- a/src/lxc/start.c +++ b/src/lxc/start.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -41,14 +42,40 @@ 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); @@ -61,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)) @@ -121,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)) {