]> sourceware.org Git - dm.git/commitdiff
Change the multilog code to toggle between async and sync writes for all
authorAJ Lewis <alewis@redhat.com>
Wed, 25 May 2005 21:08:36 +0000 (21:08 +0000)
committerAJ Lewis <alewis@redhat.com>
Wed, 25 May 2005 21:08:36 +0000 (21:08 +0000)
log types.  This means the threaded_syslog type is no longer valid.  A new
fxn multilog_async is available to toggle between the two modes.  If an
app is compiled without pthreads and tries to use async logging, no logging
will occur while async is enabled.

dmeventd has been modified to use the new code

I'm not positive I like the way the async_logger code calls the log fxn,
but it works for now.  Suggestions for other ways to do it would be helpful

dmeventd/dmeventd.c
lib/event/dmeventd.c
multilog/.exported_symbols
multilog/async/Makefile.in
multilog/async/async_logger.c
multilog/async/async_logger.h
multilog/libmultilog.c
multilog/libmultilog.h
multilog/tests/test-multilog.c

index 2b732c82a9ac7ac37d1db7ebef9c2b44af6aab64..572bce074121983fd99c18dc34f95b6be00c3376 100644 (file)
@@ -33,6 +33,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <syslog.h>
 #include <sys/file.h>
 #include <sys/mman.h>
 #include <sys/types.h>
@@ -56,6 +57,7 @@
 #define        UNLINK_DSO(x)           UNLINK(x)
 #define        UNLINK_THREAD(x)        UNLINK(x)
 
+#define DAEMON_NAME  "dmeventd"
 
 /* Global mutex for list accesses. */
 static pthread_mutex_t mutex;
@@ -1016,7 +1018,7 @@ static void init_thread_signals(int hup)
 int main(void)
 {
        struct fifos fifos;
-
+       struct sys_log logdata = {DAEMON_NAME, LOG_DAEMON};
        /* Make sure, parent accepts HANGUP signal. */
        init_thread_signals(1);
 
@@ -1032,8 +1034,9 @@ int main(void)
                kill(getppid(), HANGUP);
 
                multilog_clear_logging();
-               multilog_add_type(threaded_syslog, NULL);
-               multilog_init_verbose(threaded_syslog, _LOG_DEBUG);
+               multilog_add_type(std_syslog, &logdata);
+               multilog_init_verbose(std_syslog, _LOG_DEBUG);
+               multilog_async(1);
 
                init_fifos(&fifos);
                pthread_mutex_init(&mutex, NULL);
index f21ffacf322866a012465e6723ba7d1638ed244f..315c7705875203b15163158d67152c01286dcba8 100644 (file)
@@ -33,6 +33,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <syslog.h>
 #include <sys/file.h>
 #include <sys/mman.h>
 #include <sys/types.h>
@@ -55,6 +56,7 @@
 #define        UNLINK_DSO(x)           UNLINK(x)
 #define        UNLINK_THREAD(x)        UNLINK(x)
 
+#define DAEMON_NAME "dmeventd"
 
 /* Global mutex for list accesses. */
 static pthread_mutex_t mutex;
@@ -985,6 +987,7 @@ void dmeventd(void)
 {
        int ret;
        struct fifos fifos;
+       struct sys_log logdata = {DAEMON_NAME, LOG_DAEMON};
 
        if ((ret = daemonize()))
                exit(ret);
@@ -998,8 +1001,9 @@ void dmeventd(void)
        init_thread_signals();
 
        multilog_clear_logging();
-       multilog_add_type(threaded_syslog, NULL);
-       multilog_init_verbose(threaded_syslog, _LOG_DEBUG);
+       multilog_add_type(std_syslog, &logdata);
+       multilog_init_verbose(std_syslog, _LOG_DEBUG);
+       multilog_async(1);
 
 
        if (!init_fifos(&fifos))
index 10f33c11254453ac624e7629e0dba2d1f1c9212f..3411c103d8913c813455d11b28f226d302522e97 100644 (file)
@@ -4,3 +4,5 @@ multilog_clear_logging
 multilog_del_type
 multilog_custom
 multilog_init_verbose
+multilog_async
+logit
index a4ba1bd4ea08f47d3fd218a96000f2c4c0c15236..f3881ec285fd55d7d21af0215337d34c2783f0dd 100644 (file)
@@ -26,6 +26,7 @@ else
   LIB_SHARED = libmultilog_async.so
 endif
 
+CFLAGS += -I..
 LDFLAGS += -ldl -ldevmapper -lpthread -L..
 
 include ../../make.tmpl
index 6dc1f15f0dfff9089cbfb77784002996d352fbb9..425908d0af7066a586e7e5a2386b28e3086c3689 100644 (file)
@@ -21,6 +21,7 @@
 #include <sys/select.h>
 #include "libmultilog.h"
 #include "async_logger.h"
+#include "multilog_internal.h"
 
 #include <unistd.h>
 
@@ -66,7 +67,7 @@ static int will_overrun(int read_pos, int write_pos,
  *
  * priority:file:line:msg
  */
-void write_to_buf(void *data, int priority, const char *file, int line,
+void write_to_buf(int priority, const char *file, int line,
                  const char *string)
 {
        char buf[CBUFSIZE];
@@ -224,7 +225,7 @@ static void finish_processing(void *arg)
                 * then how to we handle pthread_cond_signal?
                 */
                pthread_mutex_unlock(&cbuf.mutex);
-               syslog(priority, "%s", mybuf);
+               logit(priority, file, line, mybuf);
                pthread_mutex_lock(&cbuf.mutex);
        }
 
@@ -235,7 +236,7 @@ static void finish_processing(void *arg)
  * Handle logging to syslog through circular buffer so that syslog
  * blocking doesn't hold anyone up.
  */
-static void *process_syslog(void *arg)
+static void *process_log(void *arg)
 {
        char mybuf[CBUFSIZE] = {0};
        int priority;
@@ -253,9 +254,6 @@ static void *process_syslog(void *arg)
        cbuf.initialized = 1;
        pthread_cleanup_push(finish_processing, NULL);
 
-       /* FIXME: The program name needs to be variable. */
-       openlog("dmeventd", LOG_NDELAY | LOG_PID, LOG_DAEMON);
-
        while (1) {
                /* check write_pos & read_pos */
                if (cbuf.write_pos != cbuf.read_pos) {
@@ -270,7 +268,8 @@ static void *process_syslog(void *arg)
                         * so we don't block the writer threads.
                         */
                        pthread_mutex_unlock(&cbuf.mutex);
-                       syslog(priority, "%s", mybuf);
+                       logit(priority, file, line, mybuf);
+/*                     syslog(priority, "%s", mybuf);*/
                        pthread_mutex_lock(&cbuf.mutex);
                } else {
                        /*
@@ -284,7 +283,6 @@ static void *process_syslog(void *arg)
                }
         }
 
-       closelog();
        pthread_cleanup_pop(0);
 
        return NULL;
@@ -294,7 +292,11 @@ int start_syslog_thread(pthread_t *thread, long usecs)
 {
        struct timeval ts = {0, usecs};
 
-       pthread_create(thread, NULL, process_syslog, NULL);
+       /* FIXME: should i protect this with the mutex? */
+       if(cbuf.initialized)
+               return 1;
+
+       pthread_create(thread, NULL, process_log, NULL);
        select(0, NULL, NULL, NULL, &ts);
 
        /*
@@ -310,6 +312,7 @@ int stop_syslog_thread(pthread_t thread)
 {
        pthread_cancel(thread);
        pthread_join(thread, NULL);
-
+       /* FIXME: should i protect this with the mutex? */
+       cbuf.initialized = 0;
        return 1;
 }
index 77defcf4e0fe91503f030efbd5af39bf2a7f7f40..8e2050feccef2506cd9f904a43241539a1322a16 100644 (file)
@@ -15,7 +15,7 @@
 #ifndef LIB_CIRCBUF_H
 #define LIB_CIRCBUF_H
 
-void write_to_buf(void *data, int priority, const char *file, int line,
+void write_to_buf(int priority, const char *file, int line,
                  const char *string);
 int start_syslog_thread(pthread_t *thread, long usecs);
 int stop_syslog_thread(pthread_t thread);
index 3c888212fc0fb817137004eea7bdbf7ea1c4cd51..dbe4561298779f63a252a89d661117f19161a56f 100644 (file)
 #include <sys/select.h>
 #include "list.h"
 #include "libmultilog.h"
+#include "multilog_internal.h"
 
 #include <unistd.h>
 
 #define DEFAULT_VERBOSITY 4
 
 
-struct threaded_syslog_log {
+struct threaded_log {
        pthread_t thread;
        void *dlh;
+       int (*start_log) (pthread_t *t, long usecs);
+       int (*stop_log) (pthread_t t);
+       void (*log) (int priority, const char *file,
+                    int line, const char *string);
+       int enabled;
 };
 
 
@@ -43,7 +49,6 @@ struct custom_log {
 
 union log_info {
        FILE *logfile;
-       struct threaded_syslog_log threaded_syslog;
        struct custom_log cl;
 };
 
@@ -62,6 +67,8 @@ struct log_list {
 /* FIXME: probably shouldn't do it this way, but... */
 static LIST_INIT(logs);
 
+static struct threaded_log tl;
+
 /* locking for log accesss */
 static void* (*init_lock_fn)(void) = NULL;
 static int (*lock_fn)(void *) = NULL;
@@ -120,7 +127,7 @@ static int load_lock_syms(void)
        void *dlh;
 
        if (!(dlh = dlopen("libmultilog_pthread_lock.so", RTLD_NOW))) {
-               //fprintf(stderr, "%s\n", dlerror());
+               /* fprintf(stderr, "%s\n", dlerror()); */
                if(strstr(dlerror(), "undefined symbol: pthread")) {
                        fprintf(stderr, "pthread library not linked in - using nop locking\n");
                        init_lock_fn = init_nop_lock;
@@ -239,34 +246,52 @@ static void standard_log(void *data, int priority, const char *file, int line,
        };
 }
 
-static int start_threaded_syslog(struct log_list *logl)
+static int start_threaded_log(void)
 {
-       void (*log_fxn) (void *data, int priority, const char *file, int line,
-                        const char *string);
-       int (*start_syslog) (pthread_t *t, long usecs);
-       int (*stop_syslog) (pthread_t t);
-       struct log_data *logdata = &logl->data;
+       /*
+        * We set this immediately so that even if the threaded
+        * logging can't load, we don't log in a blocking manner - the
+        * non-blocking behavior overrides the fact that we won't see
+        * any logs if the async logging can't load
+        */
+       tl.enabled = 1;
 
-       if (!(logdata->info.threaded_syslog.dlh = dlopen("libmultilog_async.so", RTLD_NOW))) {
+       if (!(tl.dlh = dlopen("libmultilog_async.so", RTLD_NOW))) {
                fprintf(stderr, "%s\n", dlerror());
                return 0;
        }
 
-       log_fxn = dlsym(logdata->info.threaded_syslog.dlh, "write_to_buf");
-       start_syslog = dlsym(logdata->info.threaded_syslog.dlh, "start_syslog_thread");
-       stop_syslog = dlsym(logl->data.info.threaded_syslog.dlh, "stop_syslog_thread");
+       tl.start_log = dlsym(tl.dlh, "start_syslog_thread");
+       tl.stop_log = dlsym(tl.dlh, "stop_syslog_thread");
+       tl.log = dlsym(tl.dlh, "write_to_buf");
 
-       if (!log_fxn || !start_syslog || !stop_syslog) {
-               dlclose(logdata->info.threaded_syslog.dlh);
+       if (!tl.start_log || !tl.stop_log || !tl.log) {
+               fprintf(stderr, "Unable to load all fxns\n");
+               dlclose(tl.dlh);
+               tl.dlh = NULL;
                return 0;
        }
 
        /* FIXME: the timeout here probably can be tweaked */
        /* FIXME: Probably want to do something if this fails */
-       if (start_syslog(&(logdata->info.threaded_syslog.thread), 100000))
-               logl->log = log_fxn;
+       if (tl.start_log(&(tl.thread), 100000)) {
+               return 1;
+       }
+       fprintf(stderr, "Bleh!\n");
+       return 0;
+}
 
-       return logl->log ? 1 : 0;
+static int stop_threaded_log(void)
+{
+       if(tl.enabled) {
+               tl.enabled = 0;
+               if(tl.dlh) {
+                       tl.stop_log(tl.thread);
+                       dlclose(tl.dlh);
+                       tl.dlh = NULL;
+               }
+       }
+       return 1;
 }
 
 int multilog_add_type(enum log_type type, void *data)
@@ -328,20 +353,12 @@ int multilog_add_type(enum log_type type, void *data)
        case std_syslog: {
                struct sys_log *sld = data;
                /* FIXME: pass in the name and facility */
-               init_sys_log(sld->ident, sld->facility);
+               if(sld) {
+                       init_sys_log(sld->ident, sld->facility);
+               }
                logl->log = sys_log;
                break;
        }
-       case threaded_syslog:
-               if (!start_threaded_syslog(logl)) {
-                       lock_list(lock_handle);
-                       list_del(&logl->list);
-                       unlock_list(lock_handle);
-                       free(logl);
-                       return 0;
-               }
-
-               break;
        case custom:
                /* Caller should use multilog_custom to set their
                 * logging fxn */
@@ -384,14 +401,6 @@ void multilog_del_type(enum log_type type)
        unlock_list(lock_handle);
 
        if (ll) {
-               if (ll->type == threaded_syslog) {
-                       int (*stop_syslog) (pthread_t t);
-                       stop_syslog = dlsym(logl->data.info.threaded_syslog.dlh, "stop_syslog_thread");
-                       if(stop_syslog)
-                               stop_syslog(ll->data.info.threaded_syslog.thread);
-
-                       dlclose(ll->data.info.threaded_syslog.dlh);
-               }
                if (ll->type == custom) {
                        if(ll->data.info.cl.destructor) {
                                ll->data.info.cl.destructor(ll->data.info.cl.custom);
@@ -441,25 +450,21 @@ void multilog(int priority, const char *file, int line, const char *format, ...)
 {
        /* FIXME: stack allocation of large buffer. */
        char buf[4096];
-       struct log_list *logl;
 
        va_list args;
        va_start(args, format);
        vsnprintf(buf, 4096, format, args);
        va_end(args);
 
-       lock_list(lock_handle);
-
-       list_iterate_items(logl, &logs) {
-               /* Custom logging types do just get the custom data
-                * they setup initially - multilog doesn't do any
-                * handling of custom loggers data */
-               if(logl->type == custom)
-                       logl->log(logl->data.info.cl.custom, priority, file, line, buf);
-               else
-                       logl->log(&logl->data, priority, file, line, buf);
+       if(tl.enabled) {
+               /* send to async code */
+               if(tl.dlh) {
+                       tl.log(priority, file, line, buf);
+               }
        }
-       unlock_list(lock_handle);
+       else
+               /* Log directly */
+               logit(priority, file, line, buf);
 
 }
 
@@ -478,3 +483,33 @@ void multilog_init_verbose(enum log_type type, int level)
 
        unlock_list(lock_handle);
 }
+
+/* Toggle asynchronous logging */
+int multilog_async(int enabled)
+{
+       if(enabled)
+               return start_threaded_log();
+       else
+               return stop_threaded_log();
+}
+
+
+/* Internal function */
+void logit(int priority, const char *file, int line, char *buf)
+{
+       struct log_list *logl;
+
+       lock_list(lock_handle);
+
+       list_iterate_items(logl, &logs) {
+               /* Custom logging types do just get the custom data
+                * they setup initially - multilog doesn't do any
+                * handling of custom loggers data */
+               if(logl->type == custom)
+                       logl->log(logl->data.info.cl.custom, priority, file, line, buf);
+               else
+                       logl->log(&logl->data, priority, file, line, buf);
+       }
+       unlock_list(lock_handle);
+
+}
index affbf048b0dc0b5f5deca2a07c943bfcb6d66730..266e518640cc039b31c232d6c787331b55426410 100644 (file)
@@ -40,7 +40,6 @@ enum log_type {
        standard = 1,
        logfile,
        std_syslog,
-       threaded_syslog,
        custom,
 };
 
@@ -71,6 +70,14 @@ void multilog_custom(multilog_fn fn, void (*destroy_fn)(void *data), void *data)
  */
 void multilog_init_verbose(enum log_type type, int level);
 
+/*
+ * Turn on or shut off asyncronous logging.  Regardless of whether
+ * async logging has been enabled or not, libmultilogger uses the
+ * logging types registered via multilog_add_type
+ */
+int multilog_async(int enabled);
+
+
 #undef plog
 #undef log_error
 #undef log_print
index 09a2d478e7178fa2fdc7733645e7e15b43b77dd5..5543310974aee37d7e9e233818f526ed65e02f7e 100644 (file)
@@ -7,8 +7,9 @@
 int main(int argc, char **argv)
 {
        int i;
+       struct sys_log logdat= {"test-multilog", 3};
 
-       if (!multilog_add_type(threaded_syslog, NULL))
+       if (!multilog_add_type(std_syslog, &logdat))
                fprintf(stderr, "Unable to add threaded syslog logging\n");
 
        multilog_add_type(standard, NULL);
@@ -20,6 +21,8 @@ int main(int argc, char **argv)
 
                if (i == 5)
                        multilog_del_type(standard);
+               if (i == 10)
+                       multilog_async(1);
        }
 
        log_debug("Testing debug");
@@ -37,10 +40,11 @@ int main(int argc, char **argv)
        multilog_add_type(standard, NULL);
 
        log_err("Test of errors5");
+       multilog_async(0);
        log_err("Test of errors6");
 
        multilog_del_type(standard);
-       multilog_del_type(threaded_syslog);
+       multilog_del_type(std_syslog);
 
        exit(EXIT_SUCCESS);
 }
This page took 0.046361 seconds and 5 git commands to generate.