[lxc-devel] [PATCH 1/1] systemd: specify container_ttys in environment

Serge Hallyn serge.hallyn at ubuntu.com
Tue Jan 27 23:06:22 UTC 2015


Quoting Stéphane Graber (stgraber at ubuntu.com):
> On Tue, Jan 27, 2015 at 08:48:25PM +0000, Serge Hallyn wrote:
> > 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: Serge Hallyn <serge.hallyn at ubuntu.com>
> > ---
> >  src/lxc/conf.c  | 43 ++++++++++++++++++++++++++++++++++++++++---
> >  src/lxc/conf.h  |  1 +
> >  src/lxc/start.c |  8 +++++---
> >  3 files changed, 46 insertions(+), 6 deletions(-)
> > 
> > diff --git a/src/lxc/conf.c b/src/lxc/conf.c
> > index c7db06f..da4a928 100644
> > --- a/src/lxc/conf.c
> > +++ b/src/lxc/conf.c
> > @@ -943,9 +943,34 @@ static int setup_dev_symlinks(const struct lxc_rootfs *rootfs)
> >  	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];
> >  	int i, ret;
> >  
> > @@ -999,6 +1024,8 @@ static int setup_tty(const struct lxc_rootfs *rootfs,
> >  				SYSERROR("failed to create symlink for tty %d", i+1);
> >  				return -1;
> >  			}
> > +			/* Now save the relative path in @path for append_ptyname */
> > +			sprintf(path, "%s/tty%d", ttydir, i + 1);
> >  		} else {
> >  			/* If we populated /dev, then we need to create /dev/ttyN */
> >  			if (access(path, F_OK)) {
> > @@ -1015,6 +1042,12 @@ static int setup_tty(const struct lxc_rootfs *rootfs,
> >  						pty_info->name, path);
> >  				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)
> >  			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);
> >  		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)) {
> >  		ERROR("failed to setup /dev symlinks for '%s'", name);
> >  		return -1;
> > @@ -4172,6 +4208,7 @@ void lxc_conf_free(struct lxc_conf *conf)
> >  	free(conf->rcfile);
> >  	free(conf->init_cmd);
> >  	free(conf->unexpanded_config);
> > +	free(conf->pty_names);
> >  	lxc_clear_config_network(conf);
> >  	free(conf->lsm_aa_profile);
> >  	free(conf->lsm_se_context);
> > diff --git a/src/lxc/conf.h b/src/lxc/conf.h
> > index 09065a1..8ec3e8e 100644
> > --- a/src/lxc/conf.h
> > +++ b/src/lxc/conf.h
> > @@ -304,6 +304,7 @@ struct lxc_conf {
> >  	struct lxc_list caps;
> >  	struct lxc_list keepcaps;
> >  	struct lxc_tty_info tty_info;
> > +	char *pty_names; // comma-separated list of lxc.tty pty names
> >  	struct lxc_console console;
> >  	struct lxc_rootfs rootfs;
> >  	char *ttydir;
> > diff --git a/src/lxc/start.c b/src/lxc/start.c
> > index 161e4c0..b2c9424 100644
> > --- a/src/lxc/start.c
> > +++ b/src/lxc/start.c
> > @@ -745,9 +745,11 @@ static int do_start(void *data)
> >  		}
> >  	}
> >  
> > -	if (putenv("container=lxc")) {
> > -		SYSERROR("failed to set environment variable 'container=lxc'");
> > -		goto out_warn_father;
> 
> Why is that being removed?

Oh I was just testing you.  yeah...

The "real" patch follows.  yeah.

Subject: [PATCH 1/1] 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: Serge Hallyn <serge.hallyn at ubuntu.com>
---
 src/lxc/conf.c  | 43 ++++++++++++++++++++++++++++++++++++++++---
 src/lxc/conf.h  |  1 +
 src/lxc/start.c |  7 +++++++
 3 files changed, 48 insertions(+), 3 deletions(-)

diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index c7db06f..da4a928 100644
--- a/src/lxc/conf.c
+++ b/src/lxc/conf.c
@@ -943,9 +943,34 @@ static int setup_dev_symlinks(const struct lxc_rootfs *rootfs)
 	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];
 	int i, ret;
 
@@ -999,6 +1024,8 @@ static int setup_tty(const struct lxc_rootfs *rootfs,
 				SYSERROR("failed to create symlink for tty %d", i+1);
 				return -1;
 			}
+			/* Now save the relative path in @path for append_ptyname */
+			sprintf(path, "%s/tty%d", ttydir, i + 1);
 		} else {
 			/* If we populated /dev, then we need to create /dev/ttyN */
 			if (access(path, F_OK)) {
@@ -1015,6 +1042,12 @@ static int setup_tty(const struct lxc_rootfs *rootfs,
 						pty_info->name, path);
 				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)
 			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);
 		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)) {
 		ERROR("failed to setup /dev symlinks for '%s'", name);
 		return -1;
@@ -4172,6 +4208,7 @@ void lxc_conf_free(struct lxc_conf *conf)
 	free(conf->rcfile);
 	free(conf->init_cmd);
 	free(conf->unexpanded_config);
+	free(conf->pty_names);
 	lxc_clear_config_network(conf);
 	free(conf->lsm_aa_profile);
 	free(conf->lsm_se_context);
diff --git a/src/lxc/conf.h b/src/lxc/conf.h
index 09065a1..8ec3e8e 100644
--- a/src/lxc/conf.h
+++ b/src/lxc/conf.h
@@ -304,6 +304,7 @@ struct lxc_conf {
 	struct lxc_list caps;
 	struct lxc_list keepcaps;
 	struct lxc_tty_info tty_info;
+	char *pty_names; // comma-separated list of lxc.tty pty names
 	struct lxc_console console;
 	struct lxc_rootfs rootfs;
 	char *ttydir;
diff --git a/src/lxc/start.c b/src/lxc/start.c
index 161e4c0..1949886 100644
--- a/src/lxc/start.c
+++ b/src/lxc/start.c
@@ -750,6 +750,13 @@ static int do_start(void *data)
 		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);
 
 	/* after this call, we are in error because this
-- 
2.1.0



More information about the lxc-devel mailing list