data.clear = log->clear;
data.read = log->read;
data.read_max = *log->read_max;
+ data.write_logfile = log->write_logfile;
cmd.req.cmd = LXC_CMD_CONSOLE_LOG;
cmd.req.data = &data;
/* There is nothing to be read from the buffer. So clear any values we
* where passed to clearly indicate to the user that nothing went wrong.
*/
- if (cmd.rsp.ret == -ENODATA || cmd.rsp.ret == -EFAULT) {
+ if (cmd.rsp.ret == -ENODATA || cmd.rsp.ret == -EFAULT || cmd.rsp.ret == -ENOENT) {
*log->read_max = 0;
log->data = NULL;
}
struct lxc_cmd_rsp rsp;
uint64_t logsize = handler->conf->console.log_size;
const struct lxc_cmd_console_log *log = req->data;
+ struct lxc_console *console = &handler->conf->console;
struct lxc_ringbuf *buf = &handler->conf->console.ringbuf;
rsp.ret = -EFAULT;
rsp.datalen = log->read_max;
/* there's nothing to read */
+ rsp.ret = -ENODATA;
if (log->read && (buf->r_off == buf->w_off))
- rsp.ret = -ENODATA;
- else
- rsp.ret = 0;
+ goto out;
+
+ if (log->write_logfile && rsp.datalen > 0) {
+ rsp.ret = -ENOENT;
+ if (!console->log_path)
+ goto out;
+
+ rsp.ret = lxc_console_write_ringbuffer(console);
+ if (rsp.ret < 0)
+ goto out;
+ }
+
+ rsp.ret = 0;
if (log->clear)
lxc_ringbuf_clear(buf);
bool clear;
bool read;
uint64_t read_max;
+ bool write_logfile;
};
return ret;
}
-static int lxc_console_write_ringbuffer(struct lxc_console *console)
+int lxc_console_write_ringbuffer(struct lxc_console *console)
{
int fd;
char *r_addr;
if (used == 0)
return 0;
- fd = lxc_unpriv(open(console->log_path, O_CLOEXEC | O_RDWR | O_CREAT, 0600));
+ fd = lxc_unpriv(open(console->log_path, O_CLOEXEC | O_RDWR | O_CREAT | O_TRUNC, 0600));
if (fd < 0) {
SYSERROR("Failed to open console log file \"%s\"", console->log_path);
- return -1;
+ return -EIO;
}
DEBUG("Using \"%s\" as console log file", console->log_path);
ret = lxc_write_nointr(fd, r_addr, used);
close(fd);
if (ret < 0)
- return -1;
+ return -EIO;
return 0;
}
*/
extern void lxc_console_sigwinch_fini(struct lxc_tty_state *ts);
+extern int lxc_console_write_ringbuffer(struct lxc_console *console);
+
#endif
ret = lxc_cmd_console_log(c->name, do_lxcapi_get_config_path(c), log);
if (ret < 0) {
if (ret == -ENODATA)
- NOTICE("%s - The console log is empty", strerror(-ret));
+ NOTICE("The console log is empty");
else if (ret == -EFAULT)
- NOTICE("%s - The container does not have a console log configured", strerror(-ret));
+ NOTICE("The container does not keep a console log");
+ else if (ret == -ENOENT)
+ NOTICE("The container does not keep a console log file");
+ else if (ret == -EIO)
+ NOTICE("Failed to write console log to log file");
else
- ERROR("%s - Failed to retrieve console log", strerror(-ret));
+ ERROR("Failed to retrieve console log");
}
return ret;
* "data" is invalid.
*/
char *data;
+
+ /* If a console log file was specified this flag indicates whether the
+ * contents of the ringbuffer should be written to the logfile when a
+ * request is sent to the ringbuffer.
+ */
+ bool write_logfile;
};
/*!