From 75a5936924e2c65cf1f344946fe7c8a9d40ff2d9 Mon Sep 17 00:00:00 2001 From: Maria Matejka Date: Thu, 24 Aug 2023 15:38:44 +0200 Subject: [PATCH] Logging limit enforcement moved into the rfile structure --- sysdep/unix/config.Y | 4 ++-- sysdep/unix/io.c | 20 +++++++++++++++----- sysdep/unix/log.c | 28 ++++++++++++++++------------ sysdep/unix/unix.h | 4 ++-- 4 files changed, 35 insertions(+), 21 deletions(-) diff --git a/sysdep/unix/config.Y b/sysdep/unix/config.Y index 49aa8582..a9feec02 100644 --- a/sysdep/unix/config.Y +++ b/sysdep/unix/config.Y @@ -52,7 +52,7 @@ log_file: text log_limit { if (!parse_and_exit) { - this_log->rf = rf_open(new_config->pool, $1, RF_APPEND); + this_log->rf = rf_open(new_config->pool, $1, RF_APPEND, this_log->limit); if (!this_log->rf) cf_error("Unable to open log file '%s': %m", $1); } this_log->filename = $1; @@ -91,7 +91,7 @@ mrtdump_base: | MRTDUMP text ';' { if (!parse_and_exit) { - struct rfile *f = rf_open(new_config->pool, $2, RF_APPEND); + struct rfile *f = rf_open(new_config->pool, $2, RF_APPEND, 0); if (!f) cf_error("Unable to open MRTDump file '%s': %m", $2); new_config->mrtdump_file = f; } diff --git a/sysdep/unix/io.c b/sysdep/unix/io.c index ff6f96af..faf759a5 100644 --- a/sysdep/unix/io.c +++ b/sysdep/unix/io.c @@ -67,6 +67,7 @@ struct rfile { resource r; struct stat stat; int fd; + off_t limit; _Atomic off_t pos; }; @@ -126,7 +127,7 @@ rf_stat(struct rfile *r) } struct rfile * -rf_open(pool *p, const char *name, enum rf_mode mode) +rf_open(pool *p, const char *name, enum rf_mode mode, off_t limit) { int fd = rf_open_get_fd(name, mode); @@ -135,6 +136,7 @@ rf_open(pool *p, const char *name, enum rf_mode mode) struct rfile *r = ralloc(p, &rf_class); r->fd = fd; + r->limit = limit; switch (mode) { @@ -168,12 +170,20 @@ rf_same(struct rfile *a, struct rfile *b) (a->stat.st_ino == b->stat.st_ino); } -void +int rf_write(struct rfile *r, const void *buf, size_t count) { - while ((write(r->fd, buf, count) < 0) && (errno == EINTR)) - ; - atomic_fetch_add_explicit(&r->pos, count, memory_order_relaxed); + if (r->limit && (atomic_fetch_add_explicit(&r->pos, count, memory_order_relaxed) + (off_t) count > r->limit)) + { + atomic_fetch_sub_explicit(&r->pos, count, memory_order_relaxed); + return 0; + } + else + { + while ((write(r->fd, buf, count) < 0) && (errno == EINTR)) + ; + return 1; + } } diff --git a/sysdep/unix/log.c b/sysdep/unix/log.c index 87df4fc6..0c89ebd6 100644 --- a/sysdep/unix/log.c +++ b/sysdep/unix/log.c @@ -149,7 +149,7 @@ log_rotate(struct log_channel *lc) if ((rename(lc->filename, lc->backup) < 0) && (unlink(lc->filename) < 0)) return lts_request(lc, NULL, "Log Rotate Failed"); - struct rfile *rf = rf_open(log_pool, lc->filename, RF_APPEND); + struct rfile *rf = rf_open(log_pool, lc->filename, RF_APPEND, lc->limit); if (!rf) return lts_request(lc, NULL, "Log Rotate Failed"); @@ -196,19 +196,23 @@ log_commit(log_buffer *buf) *buf->buf.pos = '\n'; byte *begin = l->terminal ? buf->buf.start : buf->tm_pos; off_t msg_len = buf->buf.pos - begin + 1; - if (l->limit && (rf_size(rf) + msg_len > l->limit)) + do { + if (rf_write(rf, buf->tm_pos, msg_len)) + break; + + log_lock(); + rf = atomic_load_explicit(&l->rf, memory_order_acquire); + if (rf_write(rf, buf->tm_pos, msg_len)) { - log_lock(); - rf = atomic_load_explicit(&l->rf, memory_order_acquire); - if (rf_size(rf) + msg_len > l->limit) - { - log_rotate(l); - rf = atomic_load_explicit(&l->rf, memory_order_relaxed); - } log_unlock(); + break; } - rf_write(l->rf, buf->tm_pos, msg_len); + log_rotate(l); + log_unlock(); + + rf = atomic_load_explicit(&l->rf, memory_order_relaxed); + } while (!rf_write(rf, buf->tm_pos, msg_len)); } #ifdef HAVE_SYSLOG_H else @@ -470,7 +474,7 @@ log_switch(int initial, list *logs, const char *new_syslog_name) rmove(l->rf, log_pool); else if (l->filename) { - l->rf = rf_open(log_pool, l->filename, RF_APPEND); + l->rf = rf_open(log_pool, l->filename, RF_APPEND, l->limit); erf = l->rf ? 0 : errno; } log_unlock(); @@ -663,7 +667,7 @@ log_init_debug(char *f) dbg_rf = NULL; else if (!*f) dbg_rf = &rf_stderr; - else if (!(dbg_rf = rf_open(&root_pool, f, RF_APPEND))) + else if (!(dbg_rf = rf_open(&root_pool, f, RF_APPEND, 0))) { /* Cannot use die() nor log() here, logging is not yet initialized */ fprintf(stderr, "bird: Unable to open debug file %s: %s\n", f, strerror(errno)); diff --git a/sysdep/unix/unix.h b/sysdep/unix/unix.h index e73778ec..f193a8db 100644 --- a/sysdep/unix/unix.h +++ b/sysdep/unix/unix.h @@ -119,10 +119,10 @@ enum rf_mode { RF_APPEND, }; -struct rfile *rf_open(struct pool *, const char *name, enum rf_mode mode); +struct rfile *rf_open(struct pool *, const char *name, enum rf_mode mode, off_t limit); off_t rf_size(struct rfile *); int rf_same(struct rfile *, struct rfile *); -void rf_write(struct rfile *, const void *, size_t); +int rf_write(struct rfile *, const void *, size_t); extern struct rfile rf_stderr;