multipathd: fix reservation_key check
[multipath-tools/.git] / libmultipath / log_pthread.c
index 8909440..bb35dfc 100644 (file)
@@ -4,23 +4,40 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdarg.h>
+#include <syslog.h>
 #include <pthread.h>
 #include <sys/mman.h>
 
-#include <memory.h>
+#include "memory.h"
 
 #include "log_pthread.h"
 #include "log.h"
+#include "lock.h"
+
+static pthread_t log_thr;
+
+static pthread_mutex_t logq_lock;
+static pthread_mutex_t logev_lock;
+static pthread_cond_t logev_cond;
+
+static int logq_running;
+static int log_messages_pending;
 
 void log_safe (int prio, const char * fmt, va_list ap)
 {
-       pthread_mutex_lock(logq_lock);
+       if (log_thr == (pthread_t)0) {
+               vsyslog(prio, fmt, ap);
+               return;
+       }
+
+       pthread_mutex_lock(&logq_lock);
        log_enqueue(prio, fmt, ap);
-       pthread_mutex_unlock(logq_lock);
+       pthread_mutex_unlock(&logq_lock);
 
-       pthread_mutex_lock(logev_lock);
-       pthread_cond_signal(logev_cond);
-       pthread_mutex_unlock(logev_lock);
+       pthread_mutex_lock(&logev_lock);
+       log_messages_pending = 1;
+       pthread_cond_signal(&logev_cond);
+       pthread_mutex_unlock(&logev_lock);
 }
 
 static void flush_logqueue (void)
@@ -28,9 +45,9 @@ static void flush_logqueue (void)
        int empty;
 
        do {
-               pthread_mutex_lock(logq_lock);
+               pthread_mutex_lock(&logq_lock);
                empty = log_dequeue(la->buff);
-               pthread_mutex_unlock(logq_lock);
+               pthread_mutex_unlock(&logq_lock);
                if (!empty)
                        log_syslog(la->buff);
        } while (empty == 0);
@@ -38,57 +55,78 @@ static void flush_logqueue (void)
 
 static void * log_thread (void * et)
 {
+       int running;
+
+       pthread_mutex_lock(&logev_lock);
+       logq_running = 1;
+       pthread_mutex_unlock(&logev_lock);
+
        mlockall(MCL_CURRENT | MCL_FUTURE);
        logdbg(stderr,"enter log_thread\n");
 
        while (1) {
-               pthread_mutex_lock(logev_lock);
-               pthread_cond_wait(logev_cond, logev_lock);
-               pthread_mutex_unlock(logev_lock);
-
+               pthread_mutex_lock(&logev_lock);
+               if (logq_running && !log_messages_pending)
+                       pthread_cond_wait(&logev_cond, &logev_lock);
+               log_messages_pending = 0;
+               running = logq_running;
+               pthread_mutex_unlock(&logev_lock);
+               if (!running)
+                       break;
                flush_logqueue();
        }
+       return NULL;
 }
 
-void log_thread_start (void)
+void log_thread_start (pthread_attr_t *attr)
 {
-       pthread_attr_t attr;
-       
        logdbg(stderr,"enter log_thread_start\n");
 
-       logq_lock = (pthread_mutex_t *) malloc(sizeof(pthread_mutex_t));
-       logev_lock = (pthread_mutex_t *) malloc(sizeof(pthread_mutex_t));
-       logev_cond = (pthread_cond_t *) malloc(sizeof(pthread_cond_t));
-       
-       pthread_mutex_init(logq_lock, NULL);
-       pthread_mutex_init(logev_lock, NULL);
-       pthread_cond_init(logev_cond, NULL);
-       
-       pthread_attr_init(&attr);
-       pthread_attr_setstacksize(&attr, 64 * 1024);
+       pthread_mutex_init(&logq_lock, NULL);
+       pthread_mutex_init(&logev_lock, NULL);
+       pthread_cond_init(&logev_cond, NULL);
 
        if (log_init("multipathd", 0)) {
                fprintf(stderr,"can't initialize log buffer\n");
                exit(1);
        }
-       pthread_create(&log_thr, &attr, log_thread, NULL);
+       if (pthread_create(&log_thr, attr, log_thread, NULL)) {
+               fprintf(stderr,"can't start log thread\n");
+               exit(1);
+       }
 
        return;
 }
 
+void log_thread_reset (void)
+{
+       logdbg(stderr,"resetting log\n");
+
+       pthread_mutex_lock(&logq_lock);
+       log_reset("multipathd");
+       pthread_mutex_unlock(&logq_lock);
+}
+
 void log_thread_stop (void)
 {
        logdbg(stderr,"enter log_thread_stop\n");
 
-       pthread_mutex_lock(logq_lock);
+       pthread_mutex_lock(&logev_lock);
+       logq_running = 0;
+       pthread_cond_signal(&logev_cond);
+       pthread_mutex_unlock(&logev_lock);
+
+       pthread_mutex_lock(&logq_lock);
        pthread_cancel(log_thr);
-       pthread_mutex_unlock(logq_lock);
+       pthread_mutex_unlock(&logq_lock);
+       pthread_join(log_thr, NULL);
+       log_thr = (pthread_t)0;
 
        flush_logqueue();
 
-       pthread_mutex_destroy(logq_lock);
-       pthread_mutex_destroy(logev_lock);
-       pthread_cond_destroy(logev_cond);
+       pthread_mutex_destroy(&logq_lock);
+       pthread_mutex_destroy(&logev_lock);
+       pthread_cond_destroy(&logev_cond);
 
-       free_logarea();
-}      
+       log_close();
+}