console: add "write_logfile" to console_log struct

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. Signed-off-by: 's avatarChristian Brauner <christian.brauner@ubuntu.com>
parent 40117d05
...@@ -994,6 +994,7 @@ int lxc_cmd_console_log(const char *name, const char *lxcpath, ...@@ -994,6 +994,7 @@ int lxc_cmd_console_log(const char *name, const char *lxcpath,
data.clear = log->clear; data.clear = log->clear;
data.read = log->read; data.read = log->read;
data.read_max = *log->read_max; data.read_max = *log->read_max;
data.write_logfile = log->write_logfile;
cmd.req.cmd = LXC_CMD_CONSOLE_LOG; cmd.req.cmd = LXC_CMD_CONSOLE_LOG;
cmd.req.data = &data; cmd.req.data = &data;
...@@ -1006,7 +1007,7 @@ int lxc_cmd_console_log(const char *name, const char *lxcpath, ...@@ -1006,7 +1007,7 @@ int lxc_cmd_console_log(const char *name, const char *lxcpath,
/* There is nothing to be read from the buffer. So clear any values we /* 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. * 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->read_max = 0;
log->data = NULL; log->data = NULL;
} }
...@@ -1027,6 +1028,7 @@ static int lxc_cmd_console_log_callback(int fd, struct lxc_cmd_req *req, ...@@ -1027,6 +1028,7 @@ static int lxc_cmd_console_log_callback(int fd, struct lxc_cmd_req *req,
struct lxc_cmd_rsp rsp; struct lxc_cmd_rsp rsp;
uint64_t logsize = handler->conf->console.log_size; uint64_t logsize = handler->conf->console.log_size;
const struct lxc_cmd_console_log *log = req->data; const struct lxc_cmd_console_log *log = req->data;
struct lxc_console *console = &handler->conf->console;
struct lxc_ringbuf *buf = &handler->conf->console.ringbuf; struct lxc_ringbuf *buf = &handler->conf->console.ringbuf;
rsp.ret = -EFAULT; rsp.ret = -EFAULT;
...@@ -1043,10 +1045,21 @@ static int lxc_cmd_console_log_callback(int fd, struct lxc_cmd_req *req, ...@@ -1043,10 +1045,21 @@ static int lxc_cmd_console_log_callback(int fd, struct lxc_cmd_req *req,
rsp.datalen = log->read_max; rsp.datalen = log->read_max;
/* there's nothing to read */ /* there's nothing to read */
rsp.ret = -ENODATA;
if (log->read && (buf->r_off == buf->w_off)) if (log->read && (buf->r_off == buf->w_off))
rsp.ret = -ENODATA; goto out;
else
rsp.ret = 0; 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) if (log->clear)
lxc_ringbuf_clear(buf); lxc_ringbuf_clear(buf);
......
...@@ -85,6 +85,7 @@ struct lxc_cmd_console_log { ...@@ -85,6 +85,7 @@ struct lxc_cmd_console_log {
bool clear; bool clear;
bool read; bool read;
uint64_t read_max; uint64_t read_max;
bool write_logfile;
}; };
......
...@@ -512,7 +512,7 @@ out: ...@@ -512,7 +512,7 @@ out:
return ret; return ret;
} }
static int lxc_console_write_ringbuffer(struct lxc_console *console) int lxc_console_write_ringbuffer(struct lxc_console *console)
{ {
int fd; int fd;
char *r_addr; char *r_addr;
...@@ -527,10 +527,10 @@ static int lxc_console_write_ringbuffer(struct lxc_console *console) ...@@ -527,10 +527,10 @@ static int lxc_console_write_ringbuffer(struct lxc_console *console)
if (used == 0) if (used == 0)
return 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) { if (fd < 0) {
SYSERROR("Failed to open console log file \"%s\"", console->log_path); 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); DEBUG("Using \"%s\" as console log file", console->log_path);
...@@ -538,7 +538,7 @@ static int lxc_console_write_ringbuffer(struct lxc_console *console) ...@@ -538,7 +538,7 @@ static int lxc_console_write_ringbuffer(struct lxc_console *console)
ret = lxc_write_nointr(fd, r_addr, used); ret = lxc_write_nointr(fd, r_addr, used);
close(fd); close(fd);
if (ret < 0) if (ret < 0)
return -1; return -EIO;
return 0; return 0;
} }
......
...@@ -215,4 +215,6 @@ extern int lxc_console_cb_sigwinch_fd(int fd, uint32_t events, void *cbdata, ...@@ -215,4 +215,6 @@ extern int lxc_console_cb_sigwinch_fd(int fd, uint32_t events, void *cbdata,
*/ */
extern void lxc_console_sigwinch_fini(struct lxc_tty_state *ts); extern void lxc_console_sigwinch_fini(struct lxc_tty_state *ts);
extern int lxc_console_write_ringbuffer(struct lxc_console *console);
#endif #endif
...@@ -523,11 +523,15 @@ static int do_lxcapi_console_log(struct lxc_container *c, struct lxc_console_log ...@@ -523,11 +523,15 @@ static int do_lxcapi_console_log(struct lxc_container *c, struct lxc_console_log
ret = lxc_cmd_console_log(c->name, do_lxcapi_get_config_path(c), log); ret = lxc_cmd_console_log(c->name, do_lxcapi_get_config_path(c), log);
if (ret < 0) { if (ret < 0) {
if (ret == -ENODATA) if (ret == -ENODATA)
NOTICE("%s - The console log is empty", strerror(-ret)); NOTICE("The console log is empty");
else if (ret == -EFAULT) 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 else
ERROR("%s - Failed to retrieve console log", strerror(-ret)); ERROR("Failed to retrieve console log");
} }
return ret; return ret;
......
...@@ -953,6 +953,12 @@ struct lxc_console_log { ...@@ -953,6 +953,12 @@ struct lxc_console_log {
* "data" is invalid. * "data" is invalid.
*/ */
char *data; 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;
}; };
/*! /*!
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment