multipathd: fix reservation_key check
[multipath-tools/.git] / libmultipath / log_pthread.c
1 /*
2  * Copyright (c) 2005 Christophe Varoqui
3  */
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <stdarg.h>
7 #include <syslog.h>
8 #include <pthread.h>
9 #include <sys/mman.h>
10
11 #include "memory.h"
12
13 #include "log_pthread.h"
14 #include "log.h"
15 #include "lock.h"
16
17 static pthread_t log_thr;
18
19 static pthread_mutex_t logq_lock;
20 static pthread_mutex_t logev_lock;
21 static pthread_cond_t logev_cond;
22
23 static int logq_running;
24 static int log_messages_pending;
25
26 void log_safe (int prio, const char * fmt, va_list ap)
27 {
28         if (log_thr == (pthread_t)0) {
29                 vsyslog(prio, fmt, ap);
30                 return;
31         }
32
33         pthread_mutex_lock(&logq_lock);
34         log_enqueue(prio, fmt, ap);
35         pthread_mutex_unlock(&logq_lock);
36
37         pthread_mutex_lock(&logev_lock);
38         log_messages_pending = 1;
39         pthread_cond_signal(&logev_cond);
40         pthread_mutex_unlock(&logev_lock);
41 }
42
43 static void flush_logqueue (void)
44 {
45         int empty;
46
47         do {
48                 pthread_mutex_lock(&logq_lock);
49                 empty = log_dequeue(la->buff);
50                 pthread_mutex_unlock(&logq_lock);
51                 if (!empty)
52                         log_syslog(la->buff);
53         } while (empty == 0);
54 }
55
56 static void * log_thread (void * et)
57 {
58         int running;
59
60         pthread_mutex_lock(&logev_lock);
61         logq_running = 1;
62         pthread_mutex_unlock(&logev_lock);
63
64         mlockall(MCL_CURRENT | MCL_FUTURE);
65         logdbg(stderr,"enter log_thread\n");
66
67         while (1) {
68                 pthread_mutex_lock(&logev_lock);
69                 if (logq_running && !log_messages_pending)
70                         pthread_cond_wait(&logev_cond, &logev_lock);
71                 log_messages_pending = 0;
72                 running = logq_running;
73                 pthread_mutex_unlock(&logev_lock);
74                 if (!running)
75                         break;
76                 flush_logqueue();
77         }
78         return NULL;
79 }
80
81 void log_thread_start (pthread_attr_t *attr)
82 {
83         logdbg(stderr,"enter log_thread_start\n");
84
85         pthread_mutex_init(&logq_lock, NULL);
86         pthread_mutex_init(&logev_lock, NULL);
87         pthread_cond_init(&logev_cond, NULL);
88
89         if (log_init("multipathd", 0)) {
90                 fprintf(stderr,"can't initialize log buffer\n");
91                 exit(1);
92         }
93         if (pthread_create(&log_thr, attr, log_thread, NULL)) {
94                 fprintf(stderr,"can't start log thread\n");
95                 exit(1);
96         }
97
98         return;
99 }
100
101 void log_thread_reset (void)
102 {
103         logdbg(stderr,"resetting log\n");
104
105         pthread_mutex_lock(&logq_lock);
106         log_reset("multipathd");
107         pthread_mutex_unlock(&logq_lock);
108 }
109
110 void log_thread_stop (void)
111 {
112         logdbg(stderr,"enter log_thread_stop\n");
113
114         pthread_mutex_lock(&logev_lock);
115         logq_running = 0;
116         pthread_cond_signal(&logev_cond);
117         pthread_mutex_unlock(&logev_lock);
118
119         pthread_mutex_lock(&logq_lock);
120         pthread_cancel(log_thr);
121         pthread_mutex_unlock(&logq_lock);
122         pthread_join(log_thr, NULL);
123         log_thr = (pthread_t)0;
124
125         flush_logqueue();
126
127         pthread_mutex_destroy(&logq_lock);
128         pthread_mutex_destroy(&logev_lock);
129         pthread_cond_destroy(&logev_cond);
130
131         log_close();
132 }