Unverified Commit c4e7852b by Serge Hallyn Committed by GitHub

Merge pull request #1925 from brauner/2017-11-14/console_config_keys

console: add lxc.console.buffer.size, lxc.console.buffer.logfile, lxc.console.rotate
parents 05e1745c 8a2404e9
......@@ -682,17 +682,88 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
where the output of this console goes.
</para>
<variablelist>
<varlistentry>
<term>
<option>lxc.console.buffer.size</option>
</term>
<listitem>
<para>
Setting this option instructs liblxc to allocate an in-memory
ringbuffer. The container's console output will be written to the
ringbuffer. Note that ringbuffer must be at least as big as a
standard page size. When passed a value smaller than a single page
size liblxc will allocate a ringbuffer of a single page size. A page
size is usually 4kB.
The keyword 'auto' will cause liblxc to allocate a ringbuffer of
128kB.
When manually specifying a size for the ringbuffer the value should
be a power of 2 when converted to bytes. Valid size prefixes are
'kB', 'MB', 'GB'. (Note that all conversions are based on multiples
of 1024. That means 'kb' == 'KiB', 'MB' == 'MiB', 'GB' == 'GiB'.)
</para>
</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>
</term>
<listitem>
<para>
Specify a path to a file where the console output will
be written.
Specify a path to a file where the console output will be written.
Note that in contrast to the on-disk ringbuffer logfile this file
will keep growing potentially filling up the users disks if not
rotated and deleted. This problem can also be avoided by using the
in-memory ringbuffer options
<option>lxc.console.buffer.size</option> and
<option>lxc.console.buffer.logfile</option>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>lxc.console.rotate</option>
</term>
<listitem>
<para>
Whether to rotate the console logfile specified in
<option>lxc.console.logfile</option>. Users can send an API
request to rotate the logfile. Note that the old logfile will have
the same name as the original with the suffix ".1" appended.
Users wishing to prevent the console log file from filling the
disk should rotate the logfile and delete it if unneeded. This
problem can also be avoided by using the in-memory ringbuffer
options <option>lxc.console.buffer.size</option> and
<option>lxc.console.buffer.logfile</option>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>lxc.console.path</option>
......
......@@ -23,6 +23,7 @@
#include "config.h"
#include <caps.h>
#include <errno.h>
#include <fcntl.h>
#include <malloc.h>
......@@ -1026,7 +1027,7 @@ static int lxc_cmd_console_log_callback(int fd, struct lxc_cmd_req *req,
struct lxc_handler *handler)
{
struct lxc_cmd_rsp rsp;
uint64_t logsize = handler->conf->console.log_size;
uint64_t buffer_size = handler->conf->console.buffer_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;
......@@ -1034,10 +1035,12 @@ static int lxc_cmd_console_log_callback(int fd, struct lxc_cmd_req *req,
rsp.ret = -EFAULT;
rsp.datalen = 0;
rsp.data = NULL;
if (logsize <= 0)
if (buffer_size <= 0)
goto out;
rsp.datalen = lxc_ringbuf_used(buf);
if (log->read || log->write_logfile)
rsp.datalen = lxc_ringbuf_used(buf);
if (log->read)
rsp.data = lxc_ringbuf_get_read_addr(buf);
......@@ -1051,7 +1054,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);
......@@ -1060,11 +1063,61 @@ static int lxc_cmd_console_log_callback(int fd, struct lxc_cmd_req *req,
}
rsp.ret = 0;
if (log->clear) {
int ret;
size_t len;
char *tmp;
if (log->clear)
/* clear the ringbuffer */
lxc_ringbuf_clear(buf);
else if (rsp.datalen > 0)
/* truncate the ringbuffer log file */
if (console->buffer_log_file) {
rsp.ret = -ENOENT;
if (!file_exists(console->buffer_log_file))
goto out;
/* be very certain things are kosher */
rsp.ret = -EBADF;
if (console->buffer_log_file_fd < 0)
goto out;
rsp.ret = lxc_unpriv(ftruncate(console->buffer_log_file_fd, 0));
if (rsp.ret < 0) {
ERROR("%s - Failed to truncate console "
"ringbuffer log file \"%s\"",
strerror(errno), console->buffer_log_file);
goto out;
}
}
/* rotate the console log file */
if (!console->log_path || console->log_rotate == 0)
goto out;
/* be very certain things are kosher */
rsp.ret = -EBADF;
if (console->log_fd < 0)
goto out;
len = strlen(console->log_path) + sizeof(".1");
tmp = alloca(len);
rsp.ret = -EFBIG;
ret = snprintf(tmp, len, "%s.1", console->log_path);
if (ret < 0 || (size_t)ret >= len)
goto out;
close(console->log_fd);
console->log_fd = -1;
rsp.ret = lxc_unpriv(rename(console->log_path, tmp));
if (rsp.ret < 0)
goto out;
rsp.ret = lxc_console_create_log_file(console);
} else if (rsp.datalen > 0) {
lxc_ringbuf_move_read_addr(buf, rsp.datalen);
}
out:
return lxc_cmd_rsp_send(fd, &rsp);
......
......@@ -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.log_size = 0;
new->console.path = NULL;
new->console.peer = -1;
new->console.peerpty.busy = -1;
......@@ -3461,9 +3463,10 @@ 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.log_size > 0 && conf->console.ringbuf.addr)
if (conf->console.buffer_size > 0 && conf->console.ringbuf.addr)
lxc_ringbuf_release(&conf->console.ringbuf);
free(conf->rootfs.mount);
free(conf->rootfs.bdev_type);
......
......@@ -150,10 +150,21 @@ struct lxc_console {
char *path;
char *log_path;
int log_fd;
unsigned int log_rotate;
char name[MAXPATHLEN];
struct termios *tios;
struct lxc_tty_state *tty_state;
uint64_t log_size;
/* 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;
};
......
......@@ -83,7 +83,9 @@ lxc_config_define(cap_keep);
lxc_config_define(cgroup_controller);
lxc_config_define(cgroup_dir);
lxc_config_define(console_logfile);
lxc_config_define(console_logsize);
lxc_config_define(console_rotate);
lxc_config_define(console_buffer_logfile);
lxc_config_define(console_buffer_size);
lxc_config_define(console_path);
lxc_config_define(environment);
lxc_config_define(ephemeral);
......@@ -149,12 +151,14 @@ 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.logsize", false, set_config_console_logsize, get_config_console_logsize, clr_config_console_logsize, },
{ "lxc.console.path", false, set_config_console_path, get_config_console_path, clr_config_console_path, },
{ "lxc.console.rotate", false, set_config_console_rotate, get_config_console_rotate, clr_config_console_rotate, },
{ "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, },
......@@ -1788,27 +1792,47 @@ static int set_config_console_path(const char *key, const char *value,
return set_config_path_item(&lxc_conf->console.path, value);
}
static int set_config_console_rotate(const char *key, const char *value,
struct lxc_conf *lxc_conf, void *data)
{
if (lxc_config_value_empty(value)) {
lxc_conf->console.log_rotate = 0;
return 0;
}
if (lxc_safe_uint(value, &lxc_conf->console.log_rotate) < 0)
return -1;
if (lxc_conf->console.log_rotate > 1) {
ERROR("The \"lxc.console.rotate\" config key can only be set "
"to 0 or 1");
return -1;
}
return 0;
}
static int set_config_console_logfile(const char *key, const char *value,
struct lxc_conf *lxc_conf, void *data)
{
return set_config_path_item(&lxc_conf->console.log_path, value);
}
static int set_config_console_logsize(const char *key, const char *value,
struct lxc_conf *lxc_conf, void *data)
static int set_config_console_buffer_size(const char *key, const char *value,
struct lxc_conf *lxc_conf, void *data)
{
int ret;
int64_t size;
uint64_t logsize, pgsz;
uint64_t buffer_size, pgsz;
if (lxc_config_value_empty(value)) {
lxc_conf->console.log_size = 0;
lxc_conf->console.buffer_size = 0;
return 0;
}
/* If the user specified "auto" the default log size is 2^17 = 128 Kib */
if (!strcmp(value, "auto")) {
lxc_conf->console.log_size = 1 << 17;
lxc_conf->console.buffer_size = 1 << 17;
return 0;
}
......@@ -1829,18 +1853,25 @@ static int set_config_console_logsize(const char *key, const char *value,
size = pgsz;
}
logsize = lxc_find_next_power2((uint64_t)size);
if (logsize == 0)
buffer_size = lxc_find_next_power2((uint64_t)size);
if (buffer_size == 0)
return -EINVAL;
if (logsize != size)
if (buffer_size != size)
NOTICE("Passed size was not a power of 2. Rounding log size to "
"next power of two: %" PRIu64 " bytes", logsize);
"next power of two: %" PRIu64 " bytes", buffer_size);
lxc_conf->console.log_size = logsize;
lxc_conf->console.buffer_size = buffer_size;
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);
......@@ -3091,12 +3122,27 @@ static int get_config_console_logfile(const char *key, char *retv, int inlen,
return lxc_get_conf_str(retv, inlen, c->console.log_path);
}
static int get_config_console_logsize(const char *key, char *retv, int inlen,
struct lxc_conf *c, void *data)
static int get_config_console_rotate(const char *key, char *retv, int inlen,
struct lxc_conf *c, void *data)
{
return lxc_get_conf_int(c, retv, inlen, c->console.log_rotate);
}
static int get_config_console_buffer_size(const char *key, char *retv,
int inlen, struct lxc_conf *c,
void *data)
{
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)
{
......@@ -3501,10 +3547,26 @@ static inline int clr_config_console_logfile(const char *key,
return 0;
}
static inline int clr_config_console_logsize(const char *key,
struct lxc_conf *c, void *data)
static inline int clr_config_console_rotate(const char *key, struct lxc_conf *c,
void *data)
{
c->console.log_rotate = 0;
return 0;
}
static inline int clr_config_console_buffer_size(const char *key,
struct lxc_conf *c, void *data)
{
c->console.buffer_size = 0;
return 0;
}
static inline int clr_config_console_buffer_logfile(const char *key,
struct lxc_conf *c,
void *data)
{
c->console.log_size = 0;
free(c->console.buffer_log_file);
c->console.buffer_log_file = NULL;
return 0;
}
......
......@@ -238,7 +238,7 @@ static int lxc_console_cb_con(int fd, uint32_t events, void *data,
w = lxc_write_nointr(console->peer, buf, r);
/* write to console ringbuffer */
if (console->log_size > 0)
if (console->buffer_size > 0)
w_rbuf = lxc_ringbuf_write(&console->ringbuf, buf, r);
/* write to console log */
......@@ -552,29 +552,20 @@ out:
int lxc_console_write_ringbuffer(struct lxc_console *console)
{
int fd;
char *r_addr;
ssize_t ret;
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));
if (fd < 0) {
SYSERROR("Failed to open console log file \"%s\"", console->log_path);
return -EIO;
}
DEBUG("Using \"%s\" as console log file", console->log_path);
r_addr = lxc_ringbuf_get_read_addr(buf);
ret = lxc_write_nointr(fd, r_addr, used);
close(fd);
ret = lxc_write_nointr(console->buffer_log_file_fd, r_addr, used);
if (ret < 0)
return -EIO;
......@@ -606,6 +597,30 @@ void lxc_console_delete(struct lxc_console *console)
console->master = -1;
console->slave = -1;
console->log_fd = -1;
if (console->buffer_log_file_fd >= 0)
close(console->buffer_log_file_fd);
console->buffer_log_file_fd = -1;
}
/* This is the console ringbuffer log file. Please note that the console
* ringbuffer log file is (implementation wise not content wise) independent of
* the console log file.
*/
static int lxc_console_create_ringbuf_log_file(struct lxc_console *console)
{
if (!console->buffer_log_file)
return 0;
console->buffer_log_file_fd = lxc_unpriv(open(console->buffer_log_file,
O_CLOEXEC | O_RDWR | O_CREAT | O_TRUNC, 0600));
if (console->buffer_log_file_fd < 0) {
SYSERROR("Failed to open console ringbuffer log file \"%s\"",
console->buffer_log_file);
return -EIO;
}
DEBUG("Using \"%s\" as console ringbuffer log file", console->buffer_log_file);
return 0;
}
/**
......@@ -613,11 +628,11 @@ void lxc_console_delete(struct lxc_console *console)
* register a handler for the console's masterfd when we create the mainloop
* the console handler needs to see an allocated ringbuffer.
*/
static int lxc_setup_console_ringbuf(struct lxc_console *console)
static int lxc_console_create_ringbuf(struct lxc_console *console)
{
int ret;
struct lxc_ringbuf *buf = &console->ringbuf;
uint64_t size = console->log_size;
uint64_t size = console->buffer_size;
/* no ringbuffer previously allocated and no ringbuffer requested */
if (!buf->addr && size <= 0)
......@@ -655,6 +670,25 @@ static int lxc_setup_console_ringbuf(struct lxc_console *console)
return 0;
}
/**
* This is the console log file. Please note that the console log file is
* (implementation wise not content wise) independent of the console ringbuffer.
*/
int lxc_console_create_log_file(struct lxc_console *console)
{
if (!console->log_path)
return 0;
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);
return -1;
}
DEBUG("Using \"%s\" as console log file", console->log_path);
return 0;
}
int lxc_console_create(struct lxc_conf *conf)
{
int ret, saved_errno;
......@@ -698,16 +732,18 @@ int lxc_console_create(struct lxc_conf *conf)
goto err;
}
if (console->log_path && console->log_size <= 0) {
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);
goto err;
}
DEBUG("Using \"%s\" as console log file", console->log_path);
}
/* create console log file */
ret = lxc_console_create_log_file(console);
if (ret < 0)
goto err;
/* create console ringbuffer */
ret = lxc_console_create_ringbuf(console);
if (ret < 0)
goto err;
ret = lxc_setup_console_ringbuf(console);
/* create console ringbuffer log file */
ret = lxc_console_create_ringbuf_log_file(console);
if (ret < 0)
goto err;
......
......@@ -222,5 +222,6 @@ extern int lxc_console_cb_signal_fd(int fd, uint32_t events, void *cbdata,
extern void lxc_console_signal_fini(struct lxc_tty_state *ts);
extern int lxc_console_write_ringbuffer(struct lxc_console *console);
extern int lxc_console_create_log_file(struct lxc_console *console);
#endif
......@@ -39,7 +39,7 @@ int main(int argc, char *argv[])
int logfd, ret;
char buf[4096 + 1];
ssize_t bytes;
struct stat st;
struct stat st_buffer_log_file, st_log_file, st_log_file_old;
struct lxc_container *c;
struct lxc_console_log log;
bool do_unlink = false;
......@@ -57,12 +57,18 @@ int main(int argc, char *argv[])
}
/* Set console ringbuffer size. */
if (!c->set_config_item(c, "lxc.console.logsize", "4096")) {
lxc_error("%s\n", "Failed to set config item \"lxc.console.logsize\"");
if (!c->set_config_item(c, "lxc.console.buffer.size", "4096")) {
lxc_error("%s\n", "Failed to set config item \"lxc.console.buffer.size\"");
goto on_error_put;
}
/* Set on-disk logfile. */
/* Set ringbuffer log file. */
if (!c->set_config_item(c, "lxc.console.buffer.logfile", "/tmp/console-buffer-log.log")) {
lxc_error("%s\n", "Failed to set config item \"lxc.console.buffer.logfile\"");
goto on_error_put;
}
/* Set console log file. */
if (!c->set_config_item(c, "lxc.console.logfile", "/tmp/console-log.log")) {
lxc_error("%s\n", "Failed to set config item \"lxc.console.logfile\"");
goto on_error_put;
......@@ -135,11 +141,17 @@ int main(int argc, char *argv[])
goto on_error_stop;
}
c->clear_config(c);
if (!c->load_config(c, NULL)) {
lxc_error("%s\n", "Failed to load config for container \"console-log\"");
goto on_error_stop;
}
if (!c->startl(c, 0, NULL)) {
lxc_error("%s\n", "Failed to start container \"console-log\" daemonized");
goto on_error_destroy;
}
do_unlink = true;
/* Leave some time for the container to write something to the log. */
sleep(2);
......@@ -158,31 +170,31 @@ int main(int argc, char *argv[])
*log.read_max, log.data);
}
logfd = open("/tmp/console-log.log", O_RDONLY);
logfd = open("/tmp/console-buffer-log.log", O_RDONLY);
if (logfd < 0) {
lxc_error("%s - Failed to open console log file "
"\"/tmp/console-log.log\"\n", strerror(errno));
lxc_error("%s - Failed to open console ringbuffer log file "
"\"/tmp/console-buffer-log.log\"\n", strerror(errno));
goto on_error_stop;
}
bytes = lxc_read_nointr(logfd, buf, 4096 + 1);
close(logfd);
if (bytes < 0 || ((uint64_t)bytes != *log.read_max)) {
lxc_error("%s - Failed to read console log file "
"\"/tmp/console-log.log\"\n", strerror(errno));
lxc_error("%s - Failed to read console ringbuffer log file "
"\"/tmp/console-buffer-log.log\"\n", strerror(errno));
goto on_error_stop;
}
ret = stat("/tmp/console-log.log", &st);
ret = stat("/tmp/console-buffer-log.log", &st_buffer_log_file);
if (ret < 0) {
lxc_error("%s - Failed to stat on-disk logfile\n", strerror(errno));
goto on_error_stop;
}
if ((uint64_t)st.st_size != *log.read_max) {
if ((uint64_t)st_buffer_log_file.st_size != *log.read_max) {
lxc_error("On-disk logfile size and used ringbuffer size do "
"not match: %" PRIu64 " != %" PRIu64 "\n",
(uint64_t)st.st_size, *log.read_max);
(uint64_t)st_buffer_log_file.st_size, *log.read_max);
goto on_error_stop;
}
......@@ -192,8 +204,86 @@ int main(int argc, char *argv[])
goto on_error_stop;
} else {
lxc_debug("Retrieved %" PRIu64 " bytes from console log and "
"console log file. Contents are: \"%s\" - \"%s\"\n",
*log.read_max, log.data, buf);
"console ringbuffer log file. Contents are: \"%s\" - "
"\"%s\"\n", *log.read_max, log.data, buf);
}
ret = stat("/tmp/console-log.log", &st_log_file);
if (ret < 0) {
lxc_error("%s - Failed to stat on-disk logfile\n", strerror(errno));
goto on_error_stop;
}
/* Turn on rotation for the console log file. */
if (!c->set_config_item(c, "lxc.console.rotate", "1")) {
lxc_error("%s\n", "Failed to set config item \"lxc.console.rotate\"");
goto on_error_put;
}
if (!c->stop(c)) {
lxc_error("%s\n", "Failed to stop container \"console-log\"");
goto on_error_stop;
}
if (!c->startl(c, 0, NULL)) {
lxc_error("%s\n", "Failed to start container \"console-log\" daemonized");
goto on_error_destroy;
}
/* Leave some time for the container to write something to the log. */
sleep(2);
/* The console log file size must be greater than the console log file
* size since we append to the latter and we truncated the former
* already.
*/
if (st_log_file.st_size <= st_buffer_log_file.st_size) {
lxc_error("%s - Console log file size was smaller than the "
"console buffer log file size: %zu < %zu\n",
strerror(errno), (size_t)st_log_file.st_size,
(size_t)st_buffer_log_file.st_size);
goto on_error_stop;
} else {
lxc_debug("Console log file size is %zu bytes and console "
"buffer log file size is %zu bytes\n",
(size_t)st_log_file.st_size,
(size_t)st_buffer_log_file.st_size);
}
ret = stat("/tmp/console-log.log", &st_log_file);
if (ret < 0) {
lxc_error("%s - Failed to stat on-disk logfile\n", strerror(errno));
goto on_error_stop;
}
log.read_max = &(uint64_t){0};
log.read = false;
log.write_logfile = false;
log.clear = true;
ret = c->console_log(c, &log);
if (ret < 0) {
lxc_error("%s - Failed to retrieve console log \n", strerror(-ret));
goto on_error_stop;
}
/* There should now be a rotated log file called
* "/tmp/console-log.log.1"
*/
ret = stat("/tmp/console-log.log.1", &st_log_file_old);
if (ret < 0) {
lxc_error("%s - Failed to stat on-disk logfile\n", strerror(errno));
goto on_error_stop;
}
/* The rotated log file should have the same size as before the
* rotation.
*/
if (st_log_file.st_size != st_log_file_old.st_size) {
lxc_error("%s - Console log file size changed during log "
"rotation: %zu != %zu\n",
strerror(errno), (size_t)st_log_file.st_size,
(size_t)st_log_file_old.st_size);
goto on_error_stop;
}
fret = 0;
......@@ -211,7 +301,13 @@ on_error_put:
if (do_unlink) {
ret = unlink("/tmp/console-log.log");
if (ret < 0)
lxc_error("%s - Failed to remove container log file\n", strerror(errno));
lxc_error("%s - Failed to remove container log file\n",
strerror(errno));
ret = unlink("/tmp/console-log.log.1");
if (ret < 0)
lxc_error("%s - Failed to remove container log file\n",
strerror(errno));
}
exit(fret);
}
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