Add missing includes for remember_wwid
[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 pthread_t log_thr;
18
19 pthread_mutex_t logq_lock;
20 pthread_mutex_t logev_lock;
21 pthread_cond_t logev_cond;
22
23 int logq_running;
24
25 static void
26 sigusr1 (int sig)
27 {
28         pthread_mutex_lock(&logq_lock);
29         log_reset("multipathd");
30         pthread_mutex_unlock(&logq_lock);
31 }
32
33 void log_safe (int prio, const char * fmt, va_list ap)
34 {
35         sigset_t old;
36
37         if (log_thr == (pthread_t)0) {
38                 syslog(prio, fmt, ap);
39                 return;
40         }
41
42         block_signal(SIGUSR1, &old);
43         block_signal(SIGHUP, NULL);
44
45         pthread_mutex_lock(&logq_lock);
46         log_enqueue(prio, fmt, ap);
47         pthread_mutex_unlock(&logq_lock);
48
49         pthread_mutex_lock(&logev_lock);
50         pthread_cond_signal(&logev_cond);
51         pthread_mutex_unlock(&logev_lock);
52
53         pthread_sigmask(SIG_SETMASK, &old, NULL);
54 }
55
56 void log_thread_flush (void)
57 {
58         int empty;
59
60         do {
61                 pthread_mutex_lock(&logq_lock);
62                 empty = log_dequeue(la->buff);
63                 pthread_mutex_unlock(&logq_lock);
64                 if (!empty)
65                         log_syslog(la->buff);
66         } while (empty == 0);
67 }
68
69 static void flush_logqueue (void)
70 {
71         int empty;
72
73         do {
74                 pthread_mutex_lock(&logq_lock);
75                 empty = log_dequeue(la->buff);
76                 pthread_mutex_unlock(&logq_lock);
77                 if (!empty)
78                         log_syslog(la->buff);
79         } while (empty == 0);
80 }
81
82 static void * log_thread (void * et)
83 {
84         struct sigaction sig;
85         int running;
86
87         sig.sa_handler = sigusr1;
88         sigemptyset(&sig.sa_mask);
89         sig.sa_flags = 0;
90         if (sigaction(SIGUSR1, &sig, NULL) < 0)
91                 logdbg(stderr, "Cannot set signal handler");
92
93         pthread_mutex_lock(&logev_lock);
94         logq_running = 1;
95         pthread_mutex_unlock(&logev_lock);
96
97         mlockall(MCL_CURRENT | MCL_FUTURE);
98         logdbg(stderr,"enter log_thread\n");
99
100         while (1) {
101                 pthread_mutex_lock(&logev_lock);
102                 pthread_cond_wait(&logev_cond, &logev_lock);
103                 running = logq_running;
104                 pthread_mutex_unlock(&logev_lock);
105                 if (!running)
106                         break;
107                 log_thread_flush();
108         }
109         return NULL;
110 }
111
112 void log_thread_start (pthread_attr_t *attr)
113 {
114         logdbg(stderr,"enter log_thread_start\n");
115
116         pthread_mutex_init(&logq_lock, NULL);
117         pthread_mutex_init(&logev_lock, NULL);
118         pthread_cond_init(&logev_cond, NULL);
119
120         if (log_init("multipathd", 0)) {
121                 fprintf(stderr,"can't initialize log buffer\n");
122                 exit(1);
123         }
124         if (pthread_create(&log_thr, attr, log_thread, NULL)) {
125                 fprintf(stderr,"can't start log thread\n");
126                 exit(1);
127         }
128
129         return;
130 }
131
132 void log_thread_stop (void)
133 {
134         logdbg(stderr,"enter log_thread_stop\n");
135
136         pthread_mutex_lock(&logev_lock);
137         logq_running = 0;
138         pthread_cond_signal(&logev_cond);
139         pthread_mutex_unlock(&logev_lock);
140
141         pthread_mutex_lock(&logq_lock);
142         pthread_cancel(log_thr);
143         pthread_mutex_unlock(&logq_lock);
144         pthread_join(log_thr, NULL);
145         log_thr = (pthread_t)0;
146
147         flush_logqueue();
148
149         pthread_mutex_destroy(&logq_lock);
150         pthread_mutex_destroy(&logev_lock);
151         pthread_cond_destroy(&logev_cond);
152
153         log_close();
154 }
155