Skip to content

Commit

Permalink
logging: Respect log-size-max immediately after open
Browse files Browse the repository at this point in the history
When a container keeps restarting, conmon restarts and opens the log
file with O_APPEND every single time, resetting bytes_written to 0
with a non-empty file.
If the container fails before writting log-size-max bytes then the
log keeps growing indefinitely, potentially using up all the available
space.

This should be kept in check: initialize bytes_written to the file's
current size, so that it can be reset if required (it's possible that
the file gets re-open before the first write if it was already above the
limit, but that should almost never happen in practice)

In order to make this simpler make bytes written global variables

Signed-off-by: Dominique Martinet <[email protected]>
  • Loading branch information
martinetd committed Dec 7, 2023
1 parent 951229b commit a03d1a7
Showing 1 changed file with 19 additions and 8 deletions.
27 changes: 19 additions & 8 deletions src/ctr_logging.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "cli.h"
#include "config.h"
#include <string.h>
#include <sys/stat.h>

// if the systemd development files were found, we can log to systemd
#ifdef USE_JOURNALD
Expand Down Expand Up @@ -40,6 +41,8 @@ static int64_t log_global_size_max = -1;
/* k8s log file parameters */
static int k8s_log_fd = -1;
static char *k8s_log_path = NULL;
static int64_t k8s_bytes_written;
static int64_t k8s_total_bytes_written;

/* journald log file parameters */
// short ID length
Expand Down Expand Up @@ -114,6 +117,15 @@ void configure_log_drivers(gchar **log_drivers, int64_t log_size_max_, int64_t l
if (k8s_log_fd < 0)
pexit("Failed to open log file");

struct stat statbuf;
if (fstat(k8s_log_fd, &statbuf) == 0) {
k8s_bytes_written = statbuf.st_size;
} else {
nwarnf("Could not stat log file %s, assuming 0 size", k8s_log_path);
k8s_bytes_written = 0;
}
k8s_total_bytes_written = k8s_bytes_written;

if (!use_journald_logging && tag)
nexit("k8s-file doesn't support --log-tag");
}
Expand Down Expand Up @@ -336,9 +348,7 @@ static int write_journald(int pipe, char *buf, ssize_t buflen)
static int write_k8s_log(stdpipe_t pipe, const char *buf, ssize_t buflen)
{
writev_buffer_t bufv = {0};
static int64_t bytes_written = 0;
int64_t bytes_to_be_written = 0;
static int64_t total_bytes_written = 0;

/*
* Use the same timestamp for every line of the log in this buffer.
Expand All @@ -363,17 +373,15 @@ static int write_k8s_log(stdpipe_t pipe, const char *buf, ssize_t buflen)
}

/* If the caller specified a global max, enforce it before writing */
if (log_global_size_max > 0 && total_bytes_written >= log_global_size_max)
if (log_global_size_max > 0 && k8s_total_bytes_written >= log_global_size_max)
break;

/*
* We re-open the log file if writing out the bytes will exceed the max
* log size. We also reset the state so that the new file is started with
* a timestamp.
*/
if ((log_size_max > 0) && (bytes_written + bytes_to_be_written) > log_size_max) {
bytes_written = 0;

if ((log_size_max > 0) && (k8s_bytes_written + bytes_to_be_written) > log_size_max) {
if (writev_buffer_flush(k8s_log_fd, &bufv) < 0) {
nwarn("failed to flush buffer to log");
/*
Expand Down Expand Up @@ -418,8 +426,8 @@ static int write_k8s_log(stdpipe_t pipe, const char *buf, ssize_t buflen)
}
}

bytes_written += bytes_to_be_written;
total_bytes_written += bytes_to_be_written;
k8s_bytes_written += bytes_to_be_written;
k8s_total_bytes_written += bytes_to_be_written;
next:
/* Update the head of the buffer remaining to output. */
buf += line_len;
Expand Down Expand Up @@ -606,6 +614,9 @@ static void reopen_k8s_file(void)
/* Close the current k8s_log_fd */
close(k8s_log_fd);

/* Open with O_TRUNC: reset bytes written */
k8s_bytes_written = 0;

/* Open the log path file again */
k8s_log_fd = open(k8s_log_path_tmp, O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC, 0600);
if (k8s_log_fd < 0)
Expand Down

0 comments on commit a03d1a7

Please sign in to comment.