]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
Add support for LISTEN_FDS environment variable. 3865/head
authorRuben Jenster <r.jenster@drachenfels.de>
Wed, 2 Jun 2021 14:31:31 +0000 (16:31 +0200)
committerChristian Brauner <christian.brauner@ubuntu.com>
Mon, 14 Jun 2021 09:58:24 +0000 (11:58 +0200)
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 <r.jenster@drachenfels.de>
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
src/lxc/lxccontainer.h
src/lxc/start.c

index 1229a1f3491df3cc445824a49b4e72ad33d86217..3386bfff6d20c1b97ad7fa38d9f082b3343799e2 100644 (file)
@@ -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).
index e07e3a6470ddabbded4e2f5933a84e650bfd15de..22ec9dc8f305790a24fff629c56d1de30cda5848 100644 (file)
@@ -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);