diff options
author | 2008-09-09 14:35:44 +0000 | |
---|---|---|
committer | 2008-09-09 14:35:44 +0000 | |
commit | f4d507d5fe92f643dff267c87a2010a25cb7f2c4 (patch) | |
tree | a74581d9bea6398e3d2dc4c9f5951087c6dd173a | |
parent | A little example to launch an isolated sshd daemon inside a container (diff) | |
download | lxc-f4d507d5fe92f643dff267c87a2010a25cb7f2c4.tar.gz lxc-f4d507d5fe92f643dff267c87a2010a25cb7f2c4.tar.bz2 lxc-f4d507d5fe92f643dff267c87a2010a25cb7f2c4.zip |
Added console support
-rw-r--r-- | src/lxc/start.c | 54 |
1 files changed, 47 insertions, 7 deletions
diff --git a/src/lxc/start.c b/src/lxc/start.c index 3a99c7c..be32fa6 100644 --- a/src/lxc/start.c +++ b/src/lxc/start.c @@ -32,6 +32,7 @@ #include <signal.h> #include <sys/param.h> #include <sys/file.h> +#include <sys/mount.h> #include <sys/types.h> #include <sys/prctl.h> #include <sys/wait.h> @@ -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)) { |