Commit 393903d1 by Serge Hallyn Committed by Stéphane Graber

systemd: specify container_ttys in environment

The lxc.tty configuration item specifies a number of ttys to create. Historically, for each of those, we create a /dev/pts/N entry and symlink it to /dev/ttyN for older inits to use. For systemd, we should instead specify each tty name in a $container_ttys environment variable passed to init. See http://www.freedesktop.org/wiki/Software/systemd/ContainerInterface/ and https://github.com/lxc/lxc/issues/419. Signed-off-by: 's avatarSerge Hallyn <serge.hallyn@ubuntu.com> Acked-by: 's avatarStéphane Graber <stgraber@ubuntu.com>
parent 8d19ce7b
...@@ -943,9 +943,34 @@ static int setup_dev_symlinks(const struct lxc_rootfs *rootfs) ...@@ -943,9 +943,34 @@ static int setup_dev_symlinks(const struct lxc_rootfs *rootfs)
return 0; return 0;
} }
static int setup_tty(const struct lxc_rootfs *rootfs, /*
const struct lxc_tty_info *tty_info, char *ttydir) * Build a space-separate list of ptys to pass to systemd.
*/
static bool append_ptyname(char **pp, char *name)
{ {
char *p;
if (!*pp) {
*pp = malloc(strlen(name) + strlen("container_ttys=") + 1);
if (!*pp)
return false;
sprintf(*pp, "container_ttys=%s", name);
return true;
}
p = realloc(*pp, strlen(*pp) + strlen(name) + 2);
if (!p)
return false;
*pp = p;
strcat(p, " ");
strcat(p, name);
return true;
}
static int setup_tty(struct lxc_conf *conf)
{
const struct lxc_rootfs *rootfs = &conf->rootfs;
const struct lxc_tty_info *tty_info = &conf->tty_info;
char *ttydir = conf->ttydir;
char path[MAXPATHLEN], lxcpath[MAXPATHLEN]; char path[MAXPATHLEN], lxcpath[MAXPATHLEN];
int i, ret; int i, ret;
...@@ -999,6 +1024,8 @@ static int setup_tty(const struct lxc_rootfs *rootfs, ...@@ -999,6 +1024,8 @@ static int setup_tty(const struct lxc_rootfs *rootfs,
SYSERROR("failed to create symlink for tty %d", i+1); SYSERROR("failed to create symlink for tty %d", i+1);
return -1; return -1;
} }
/* Now save the relative path in @path for append_ptyname */
sprintf(path, "%s/tty%d", ttydir, i + 1);
} else { } else {
/* If we populated /dev, then we need to create /dev/ttyN */ /* If we populated /dev, then we need to create /dev/ttyN */
if (access(path, F_OK)) { if (access(path, F_OK)) {
...@@ -1015,6 +1042,12 @@ static int setup_tty(const struct lxc_rootfs *rootfs, ...@@ -1015,6 +1042,12 @@ static int setup_tty(const struct lxc_rootfs *rootfs,
pty_info->name, path); pty_info->name, path);
continue; continue;
} }
/* Now save the relative path in @path for append_ptyname */
sprintf(path, "tty%d", i + 1);
}
if (!append_ptyname(&conf->pty_names, path)) {
ERROR("Error setting up container_ttys string");
return -1;
} }
} }
...@@ -3794,11 +3827,14 @@ int lxc_setup(struct lxc_handler *handler) ...@@ -3794,11 +3827,14 @@ int lxc_setup(struct lxc_handler *handler)
ERROR("failed to setup kmsg for '%s'", name); ERROR("failed to setup kmsg for '%s'", name);
} }
if (!lxc_conf->is_execute && setup_tty(&lxc_conf->rootfs, &lxc_conf->tty_info, lxc_conf->ttydir)) { if (!lxc_conf->is_execute && setup_tty(lxc_conf)) {
ERROR("failed to setup the ttys for '%s'", name); ERROR("failed to setup the ttys for '%s'", name);
return -1; return -1;
} }
if (lxc_conf->pty_names && setenv("container_ttys", lxc_conf->pty_names, 1))
SYSERROR("failed to set environment variable for container ptys");
if (!lxc_conf->is_execute && setup_dev_symlinks(&lxc_conf->rootfs)) { if (!lxc_conf->is_execute && setup_dev_symlinks(&lxc_conf->rootfs)) {
ERROR("failed to setup /dev symlinks for '%s'", name); ERROR("failed to setup /dev symlinks for '%s'", name);
return -1; return -1;
...@@ -4151,6 +4187,7 @@ void lxc_conf_free(struct lxc_conf *conf) ...@@ -4151,6 +4187,7 @@ void lxc_conf_free(struct lxc_conf *conf)
free(conf->rcfile); free(conf->rcfile);
free(conf->init_cmd); free(conf->init_cmd);
free(conf->unexpanded_config); free(conf->unexpanded_config);
free(conf->pty_names);
lxc_clear_config_network(conf); lxc_clear_config_network(conf);
free(conf->lsm_aa_profile); free(conf->lsm_aa_profile);
free(conf->lsm_se_context); free(conf->lsm_se_context);
......
...@@ -304,6 +304,7 @@ struct lxc_conf { ...@@ -304,6 +304,7 @@ struct lxc_conf {
struct lxc_list caps; struct lxc_list caps;
struct lxc_list keepcaps; struct lxc_list keepcaps;
struct lxc_tty_info tty_info; struct lxc_tty_info tty_info;
char *pty_names; // comma-separated list of lxc.tty pty names
struct lxc_console console; struct lxc_console console;
struct lxc_rootfs rootfs; struct lxc_rootfs rootfs;
char *ttydir; char *ttydir;
......
...@@ -750,6 +750,13 @@ static int do_start(void *data) ...@@ -750,6 +750,13 @@ static int do_start(void *data)
goto out_warn_father; goto out_warn_father;
} }
if (handler->conf->pty_names) {
if (putenv(handler->conf->pty_names)) {
SYSERROR("failed to set environment variable for container ptys");
goto out_warn_father;
}
}
close(handler->sigfd); close(handler->sigfd);
/* after this call, we are in error because this /* after this call, we are in error because this
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment