]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Logging limit enforcement moved into the rfile structure
authorMaria Matejka <mq@ucw.cz>
Thu, 24 Aug 2023 13:38:44 +0000 (15:38 +0200)
committerMaria Matejka <mq@ucw.cz>
Sun, 24 Sep 2023 18:43:04 +0000 (20:43 +0200)
sysdep/unix/config.Y
sysdep/unix/io.c
sysdep/unix/log.c
sysdep/unix/unix.h

index 49aa858264a7fa9fb47fe394ddd0c93401a8582d..a9feec0216686fa916e72891a5a1d238a546b07f 100644 (file)
@@ -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;
      }
index ff6f96af4a5821fe3388ef2d3b9f38bd7d8fe4e7..faf759a580979dd82a5fa976264e5726bba28249 100644 (file)
@@ -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;
+  }
 }
 
 
index 87df4fc64c54cfc6807dcea794818b1b74a8ecd7..0c89ebd65a700556426e8e6f92f5a9d9dd2cd89d 100644 (file)
@@ -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));
index e73778ec4d4c45f6d5dfb51693da6b0b7e9af9dd..f193a8db8f467b6fdaa818096b30063c73f82aa2 100644 (file)
@@ -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;