From: Ruben Jenster Date: Wed, 2 Jun 2021 14:31:31 +0000 (+0200) Subject: Add support for LISTEN_FDS environment variable. X-Git-Tag: lxc-5.0.0~156^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F3865%2Fhead;p=thirdparty%2Flxc.git Add support for LISTEN_FDS environment variable. The LISTEN_FDS environment variable defines the number of file descriptors that should be inherited by the container, in addition to stdio. The LISTEN_FDS environment variable is defined in the OCI spec and used to support socket activation. Refs #3845 Signed-off-by: Ruben Jenster Signed-off-by: Christian Brauner --- diff --git a/src/lxc/lxccontainer.h b/src/lxc/lxccontainer.h index 1229a1f34..3386bfff6 100644 --- a/src/lxc/lxccontainer.h +++ b/src/lxc/lxccontainer.h @@ -223,7 +223,8 @@ struct lxc_container { /*! * \brief Change whether the container wishes all file descriptors - * to be closed on startup. + * to be closed on startup. The LISTEN_FDS environment variable + * can be set to keep inherited file descriptors open. * * \param c Container. * \param state Value for the close_all_fds bit (0 or 1). diff --git a/src/lxc/start.c b/src/lxc/start.c index e07e3a647..22ec9dc8f 100644 --- a/src/lxc/start.c +++ b/src/lxc/start.c @@ -212,6 +212,31 @@ static bool match_dlog_fds(struct dirent *direntp) } #endif +/* Parses the LISTEN_FDS environment variable value. + * The returned value is the highest fd number up to which the + * file descriptors must be passed to the container process. + * + * For example, if LISTEN_FDS=2 then 4 is returned and file descriptors 3 and 4 + * MUST be passed to the container process (in addition to the standard streams) + * to support [socket activation][systemd-listen-fds]. + */ +static unsigned int get_listen_fds_max(void) +{ + int ret; + unsigned int num_fds; + const char *val; + + val = getenv("LISTEN_FDS"); + if (!val) + return 0; + + ret = lxc_safe_uint(val, &num_fds); + if (ret < 0) + return syserror_ret(0, "Failed to parse \"LISTEN_FDS=%s\" environment variable", val); + + return log_trace(num_fds, "Parsed \"LISTEN_FDS=%s\" environment variable", val); +} + int lxc_check_inherited(struct lxc_conf *conf, bool closeall, int *fds_to_ignore, size_t len_fds) { @@ -219,10 +244,13 @@ int lxc_check_inherited(struct lxc_conf *conf, bool closeall, size_t i; DIR *dir; struct dirent *direntp; + unsigned int listen_fds_max; if (conf && conf->close_all_fds) closeall = true; + listen_fds_max = get_listen_fds_max(); + /* * Disable syslog at this point to avoid the above logging * function to open a new fd and make the check_inherited function @@ -289,6 +317,12 @@ restart: continue; #endif + + if (fd <= listen_fds_max) { + INFO("Inheriting fd %d (using the LISTEN_FDS environment variable)", fd); + continue; + } + if (closeall) { if (close(fd)) SYSINFO("Closed inherited fd %d", fd);