aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordlezcano <dlezcano>2008-09-09 14:35:44 +0000
committerdlezcano <dlezcano>2008-09-09 14:35:44 +0000
commitf4d507d5fe92f643dff267c87a2010a25cb7f2c4 (patch)
treea74581d9bea6398e3d2dc4c9f5951087c6dd173a
parentA little example to launch an isolated sshd daemon inside a container (diff)
downloadlxc-f4d507d5fe92f643dff267c87a2010a25cb7f2c4.tar.gz
lxc-f4d507d5fe92f643dff267c87a2010a25cb7f2c4.tar.bz2
lxc-f4d507d5fe92f643dff267c87a2010a25cb7f2c4.zip
Added console support
-rw-r--r--src/lxc/start.c54
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)) {