]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
systemd: specify container_ttys in environment
authorSerge Hallyn <serge.hallyn@ubuntu.com>
Tue, 27 Jan 2015 23:06:22 +0000 (23:06 +0000)
committerStéphane Graber <stgraber@ubuntu.com>
Wed, 28 Jan 2015 08:15:43 +0000 (09:15 +0100)
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@ubuntu.com>
Acked-by: Stéphane Graber <stgraber@ubuntu.com>
src/lxc/conf.c
src/lxc/conf.h
src/lxc/start.c

index 2f22eaf3c33bcc84a3e0a2e1e7a3ce1b7cb2c4fa..e7def3e9e236979978e42568a8e83b5581df375f 100644 (file)
@@ -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;
@@ -4151,6 +4187,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);
index 09065a11062aa744d1ea5437d5be4bcddadbf4ee..8ec3e8e705415e797291db427fa1a9b709d3835b 100644 (file)
@@ -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;
index 161e4c019d61eb34580c3282b09fa4ee2af8316c..1949886a795be11c114e5d1b7fd43c721c748457 100644 (file)
@@ -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