]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Merge commit 'fc2b4b26' into thread-merge-2.16
authorMaria Matejka <mq@ucw.cz>
Fri, 29 Nov 2024 11:05:40 +0000 (12:05 +0100)
committerMaria Matejka <mq@ucw.cz>
Fri, 29 Nov 2024 11:05:40 +0000 (12:05 +0100)
Actually, completely rewritten the original patch as in v3, the logging
initialization is much more complex and requires allocation.

This way, to bootstrap properly, the logger has a pre-defined log target
to stderr.

1  2 
sysdep/unix/log.c

index 98642e9c3d7d9285aea92cebdb813557c205bf48,613a6aa54c914ddab7cd47fbbcd5293c571e9d98..9d77211bf059705f42020d729dfd308c21b9f70a
@@@ -42,16 -42,23 +42,16 @@@ _Thread_local uint this_thread_id
  
  #include <pthread.h>
  
 -static pthread_mutex_t log_mutex;
 -static inline void log_lock(void) { pthread_mutex_lock(&log_mutex); }
 -static inline void log_unlock(void) { pthread_mutex_unlock(&log_mutex); }
 +static DOMAIN(logging) log_domain;
 +#define log_lock()  LOCK_DOMAIN(logging, log_domain);
 +#define log_unlock()  UNLOCK_DOMAIN(logging, log_domain);
  
 -static pthread_t main_thread;
 -void main_thread_init(void) { main_thread = pthread_self(); }
 -static int main_thread_self(void) { return pthread_equal(pthread_self(), main_thread); }
 +static struct log_channel * _Atomic global_logs;
  
 -#else
 -
 -static inline void log_lock(void) {  }
 -static inline void log_unlock(void) {  }
 -void main_thread_init(void) { }
 -static int main_thread_self(void) { return 1; }
 -
 -#endif
 +/* Logging flags to validly prepare logging messages */
  
- static _Atomic uint logging_mask;
 +static _Atomic uint logging_flags;
++static _Atomic uint logging_mask = ~0U;
  
  #ifdef HAVE_SYSLOG_H
  #include <sys/syslog.h>
@@@ -178,87 -202,61 +178,98 @@@ log_rotate(struct log_channel *lc
   * in log(), so it should be written like *L_INFO.
   */
  void
 -log_commit(int class, buffer *buf)
 +log_commit(log_buffer *buf)
  {
 -  struct log_config *l;
 +  /* Store the last pointer */
 +  buf->pos[LBP__MAX] = buf->buf.pos;
  
 -  if (buf->pos == buf->end)
 -    strcpy(buf->end - 100, " ... <too long>");
 +  /* Append the too-long message if too long */
 +  if (buf->buf.pos == buf->buf.end)
 +#define TOO_LONG " ... <too long>"
 +    memcpy(buf->buf.end - sizeof TOO_LONG, TOO_LONG, sizeof TOO_LONG);
 +#undef TOO_LONG
  
 -  log_lock();
 -  WALK_LIST(l, *current_log_list)
++  struct log_channel *glogs = atomic_load_explicit(&global_logs, memory_order_acquire);
++  if (!glogs)
++  {
++    static struct log_channel initial_stderr_log = {
++      .rf = &rf_stderr,
++      .mask = ~0,
++      .prepare = BIT32_ALL(LBPP_TERMINAL, LBP_CLASS, LBP_MSG),
++    };
++
++    glogs = &initial_stderr_log;
++  }
++
 +  for (
-       struct log_channel *l = atomic_load_explicit(&global_logs, memory_order_acquire);
-       l;
++      struct log_channel *l = glogs; l;
 +      l = atomic_load_explicit(&l->next, memory_order_acquire)
 +      )
      {
 -      if (!(l->mask & (1 << class)))
 +      uint mask = atomic_load_explicit(&l->mask, memory_order_acquire);
 +      if (!(mask & (1 << buf->class)))
        continue;
 -      if (l->fh)
 +
 +      struct rfile *rf = atomic_load_explicit(&l->rf, memory_order_acquire);
 +      sock *sk = atomic_load_explicit(&l->udp_sk, memory_order_acquire);
 +
 +      if (rf || sk)
        {
 -        if (l->terminal_flag)
 -          fputs("bird: ", l->fh);
 -        else if (l->udp_flag)
 +        /* Construct the iovec */
 +        static char terminal_prefix[] = "bird: ",
 +                    newline[] = "\n";
 +        STATIC_ASSERT(sizeof newline == 2);
 +
 +        struct iovec iov[LBP__MAX+2];
 +        uint iov_count = 0;
 +        if (BIT32_TEST(&l->prepare, LBPP_TERMINAL))
 +          iov[iov_count++] = (struct iovec) {
 +            .iov_base = terminal_prefix,
 +            .iov_len = sizeof terminal_prefix - 1,
 +          };
 +
 +        for (uint p = 0; p < LBP__MAX; p++)
 +          if (BIT32_TEST(&l->prepare, p))
            {
 -            int pri = LOG_DAEMON | syslog_priorities[class];
 -            char tbuf[TM_DATETIME_BUFFER_SIZE];
 -            const char *hostname = (config && config->hostname) ? config->hostname : "<none>";
 -            const char *fmt = "%b %d %T.%6f";
 -            if (!tm_format_real_time(tbuf, sizeof(tbuf), fmt, current_real_time()))
 -              strcpy(tbuf, "<error>");
 -
 -            /* Legacy RFC 3164 format, but with us precision */
 -            fprintf(l->fh, "<%d>%s %s %s: ", pri, tbuf, hostname, bird_name);
 +            off_t sz = buf->pos[p+1] - buf->pos[p];
 +            if (sz > 0)
 +              iov[iov_count++] = (struct iovec) {
 +                .iov_base = buf->pos[p],
 +                .iov_len = sz,
 +              };
            }
 -        else
 -          {
 -            byte tbuf[TM_DATETIME_BUFFER_SIZE];
 -            const char *fmt = config ? config->tf_log.fmt1 : "%F %T.%3f";
 -            if (!tm_format_real_time(tbuf, sizeof(tbuf), fmt, current_real_time()))
 -              strcpy(tbuf, "<error>");
 -
 -            if (l->limit)
 -            {
 -              off_t msg_len = strlen(tbuf) + strlen(class_names[class]) +
 -                (buf->pos - buf->start) + 5;
  
 -              if (l->pos < 0)
 -                l->pos = log_size(l);
 +        if (rf)
 +        {
 +          iov[iov_count++] = (struct iovec) {
 +            .iov_base = newline,
 +            .iov_len = sizeof newline - 1,
 +          };
  
 -              if (l->pos + msg_len > l->limit)
 -                if (log_rotate(l) < 0)
 -                  continue;
 +          do {
 +            if (rf_writev(rf, iov, iov_count))
 +              break;
  
 -              l->pos += msg_len;
 +            log_lock();
 +            rf = atomic_load_explicit(&l->rf, memory_order_acquire);
 +            if (rf_writev(rf, iov, iov_count))
 +            {
 +              log_unlock();
 +              break;
              }
  
 -            fprintf(l->fh, "%s <%s> ", tbuf, class_names[class]);
 -          }
 -        fputs(buf->start, l->fh);
 -        fputc('\n', l->fh);
 -        fflush(l->fh);
 +            log_rotate(l);
 +            log_unlock();
 +
 +            rf = atomic_load_explicit(&l->rf, memory_order_relaxed);
 +          } while (!rf_writev(rf, iov, iov_count));
 +        }
 +        else if (sk)
 +        {
 +          while ((writev(sk->fd, iov, iov_count) < 0) && (errno == EINTR))
 +            ;
 +          /* FIXME: Silently ignoring write errors */
 +        }
        }
  #ifdef HAVE_SYSLOG_H
        else