]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
confile: add lxc.console.buffer.logfile
authorChristian Brauner <christian.brauner@ubuntu.com>
Tue, 14 Nov 2017 23:23:07 +0000 (00:23 +0100)
committerChristian Brauner <christian.brauner@ubuntu.com>
Fri, 17 Nov 2017 23:17:46 +0000 (00:17 +0100)
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
doc/lxc.container.conf.sgml.in
src/lxc/commands.c
src/lxc/conf.c
src/lxc/conf.h
src/lxc/confile.c
src/lxc/console.c

index 2ed83ca7850b471b664a2915a042a24652be479d..2e2879e719f3b472a87278e216f67ff8f9bfed4b 100644 (file)
@@ -707,6 +707,26 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
           </listitem>
         </varlistentry>
 
+        <varlistentry>
+          <term>
+            <option>lxc.console.buffer.logfile</option>
+          </term>
+          <listitem>
+            <para>
+            Setting this option instructs liblxc to write the in-memory
+            ringbuffer to disk. For performance reasons liblxc will only write
+            the in-memory ringbuffer to disk when requested. Note that the this
+            option is only used by liblxc when
+            <option>lxc.console.buffer.size</option> is set.
+
+            By default liblxc will dump the contents of the in-memory ringbuffer
+            to disk when the container terminates. This allows users to diagnose
+            boot failures when the container crashed before an API request to
+            retrieve the in-memory ringbuffer could be sent or handled.
+            </para>
+          </listitem>
+        </varlistentry>
+
         <varlistentry>
           <term>
             <option>lxc.console.logfile</option>
index 653fd994f59b891ace33fb4694bc50d2e924ec3c..c158672ede6f0dd518f0f713d5c5e44511db66e3 100644 (file)
@@ -1051,7 +1051,7 @@ static int lxc_cmd_console_log_callback(int fd, struct lxc_cmd_req *req,
 
        if (log->write_logfile && rsp.datalen > 0) {
                rsp.ret = -ENOENT;
-               if (!console->log_path)
+               if (!console->buffer_log_file)
                        goto out;
 
                rsp.ret = lxc_console_write_ringbuffer(console);
index a2b3673a79b8115d29fea4d99e2fee26dc0a373f..4681a7274e4a19a1e4047ce472f0138e7db0a1bb 100644 (file)
@@ -2430,9 +2430,11 @@ struct lxc_conf *lxc_conf_init(void)
        new->loglevel = LXC_LOG_LEVEL_NOTSET;
        new->personality = -1;
        new->autodev = 1;
+       new->console.buffer_log_file = NULL;
+       new->console.buffer_log_file_fd = -1;
+       new->console.buffer_size = 0;
        new->console.log_path = NULL;
        new->console.log_fd = -1;
-       new->console.buffer_size = 0;
        new->console.path = NULL;
        new->console.peer = -1;
        new->console.peerpty.busy = -1;
@@ -3461,6 +3463,7 @@ void lxc_conf_free(struct lxc_conf *conf)
                return;
        if (current_config == conf)
                current_config = NULL;
+       free(conf->console.buffer_log_file);
        free(conf->console.log_path);
        free(conf->console.path);
        if (conf->console.buffer_size > 0 && conf->console.ringbuf.addr)
index 1dc8924307a0d21438aa3b0449bf0c9438a058ff..b07c92e74edad6176aa3e5fbfe1c505fc2449bbc 100644 (file)
@@ -153,7 +153,17 @@ struct lxc_console {
        char name[MAXPATHLEN];
        struct termios *tios;
        struct lxc_tty_state *tty_state;
+
+       /* size of the ringbuffer */
        uint64_t buffer_size;
+
+       /* path to the log file for the ringbuffer */
+       char *buffer_log_file;
+
+       /* fd to the log file for the ringbuffer */
+       int buffer_log_file_fd;
+
+       /* the in-memory ringbuffer */
        struct lxc_ringbuf ringbuf;
 };
 
index 852589531a240cc2ef77e90c863ddde46a7d8abf..977bea2edb2cde09d2d4d4b22c463f54b7b43bfb 100644 (file)
@@ -83,6 +83,7 @@ lxc_config_define(cap_keep);
 lxc_config_define(cgroup_controller);
 lxc_config_define(cgroup_dir);
 lxc_config_define(console_logfile);
+lxc_config_define(console_buffer_logfile);
 lxc_config_define(console_buffer_size);
 lxc_config_define(console_path);
 lxc_config_define(environment);
@@ -149,12 +150,13 @@ static struct lxc_config_t config[] = {
        { "lxc.cap.keep",                  false,                  set_config_cap_keep,                    get_config_cap_keep,                    clr_config_cap_keep,                  },
        { "lxc.cgroup.dir",                false,                  set_config_cgroup_dir,                  get_config_cgroup_dir,                  clr_config_cgroup_dir,                },
        { "lxc.cgroup",                    false,                  set_config_cgroup_controller,           get_config_cgroup_controller,           clr_config_cgroup_controller,         },
+       { "lxc.console.buffer.logfile",    false,                  set_config_console_buffer_logfile,      get_config_console_buffer_logfile,      clr_config_console_buffer_logfile,    },
        { "lxc.console.buffer.size",       false,                  set_config_console_buffer_size,         get_config_console_buffer_size,         clr_config_console_buffer_size,       },
        { "lxc.console.logfile",           false,                  set_config_console_logfile,             get_config_console_logfile,             clr_config_console_logfile,           },
        { "lxc.console.path",              false,                  set_config_console_path,                get_config_console_path,                clr_config_console_path,              },
        { "lxc.environment",               false,                  set_config_environment,                 get_config_environment,                 clr_config_environment,               },
        { "lxc.ephemeral",                 false,                  set_config_ephemeral,                   get_config_ephemeral,                   clr_config_ephemeral,                 },
-       { "lxc.execute.cmd",               false,                  set_config_execute_cmd,                 get_config_execute_cmd,                 clr_config_execute_cmd,                  },
+       { "lxc.execute.cmd",               false,                  set_config_execute_cmd,                 get_config_execute_cmd,                 clr_config_execute_cmd,               },
        { "lxc.group",                     false,                  set_config_group,                       get_config_group,                       clr_config_group,                     },
        { "lxc.hook.autodev",              false,                  set_config_hooks,                       get_config_hooks,                       clr_config_hooks,                     },
        { "lxc.hook.clone",                false,                  set_config_hooks,                       get_config_hooks,                       clr_config_hooks,                     },
@@ -1841,6 +1843,13 @@ static int set_config_console_buffer_size(const char *key, const char *value,
        return 0;
 }
 
+static int set_config_console_buffer_logfile(const char *key, const char *value,
+                                            struct lxc_conf *lxc_conf,
+                                            void *data)
+{
+       return set_config_path_item(&lxc_conf->console.buffer_log_file, value);
+}
+
 int append_unexp_config_line(const char *line, struct lxc_conf *conf)
 {
        size_t len = conf->unexpanded_len, linelen = strlen(line);
@@ -3098,6 +3107,13 @@ static int get_config_console_buffer_size(const char *key, char *retv,
        return lxc_get_conf_uint64(c, retv, inlen, c->autodev);
 }
 
+static int get_config_console_buffer_logfile(const char *key, char *retv,
+                                            int inlen, struct lxc_conf *c,
+                                            void *data)
+{
+       return lxc_get_conf_str(retv, inlen, c->console.buffer_log_file);
+}
+
 static int get_config_seccomp_profile(const char *key, char *retv, int inlen,
                                      struct lxc_conf *c, void *data)
 {
@@ -3509,6 +3525,15 @@ static inline int clr_config_console_buffer_size(const char *key,
        return 0;
 }
 
+static inline int clr_config_console_buffer_logfile(const char *key,
+                                                   struct lxc_conf *c,
+                                                   void *data)
+{
+       free(c->console.buffer_log_file);
+       c->console.buffer_log_file = NULL;
+       return 0;
+}
+
 static inline int clr_config_seccomp_profile(const char *key,
                                             struct lxc_conf *c, void *data)
 {
index c16e39bb685bb46495d53bc4b89e0cfcbd4e6867..d83b3830e08bc4324117e59150ea78b2fd4a4079 100644 (file)
@@ -558,19 +558,19 @@ int lxc_console_write_ringbuffer(struct lxc_console *console)
        uint64_t used;
        struct lxc_ringbuf *buf = &console->ringbuf;
 
-       if (!console->log_path)
+       if (!console->buffer_log_file)
                return 0;
 
        used = lxc_ringbuf_used(buf);
        if (used == 0)
                return 0;
 
-       fd = lxc_unpriv(open(console->log_path, O_CLOEXEC | O_RDWR | O_CREAT | O_TRUNC, 0600));
+       fd = lxc_unpriv(open(console->buffer_log_file, O_CLOEXEC | O_RDWR | O_CREAT | O_TRUNC, 0600));
        if (fd < 0) {
-               SYSERROR("Failed to open console log file \"%s\"", console->log_path);
+               SYSERROR("Failed to open console log file \"%s\"", console->buffer_log_file);
                return -EIO;
        }
-       DEBUG("Using \"%s\" as console log file", console->log_path);
+       DEBUG("Using \"%s\" as console log file", console->buffer_log_file);
 
        r_addr = lxc_ringbuf_get_read_addr(buf);
        ret = lxc_write_nointr(fd, r_addr, used);
@@ -698,7 +698,7 @@ int lxc_console_create(struct lxc_conf *conf)
                goto err;
        }
 
-       if (console->log_path && console->buffer_size <= 0) {
+       if (console->log_path) {
                console->log_fd = lxc_unpriv(open(console->log_path, O_CLOEXEC | O_RDWR | O_CREAT | O_APPEND, 0600));
                if (console->log_fd < 0) {
                        SYSERROR("Failed to open console log file \"%s\"", console->log_path);