Tizen 2.1 base
[external/device-mapper.git] / daemons / dmeventd / plugins / lvm2 / dmeventd_lvm.c
1 /*
2  * Copyright (C) 2010 Red Hat, Inc. All rights reserved.
3  *
4  * This file is part of LVM2.
5  *
6  * This copyrighted material is made available to anyone wishing to use,
7  * modify, copy, or redistribute it subject to the terms and conditions
8  * of the GNU Lesser General Public License v.2.1.
9  *
10  * You should have received a copy of the GNU Lesser General Public License
11  * along with this program; if not, write to the Free Software Foundation,
12  * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
13  */
14
15 #include "lib.h"
16 #include "log.h"
17
18 #include "lvm2cmd.h"
19 #include "errors.h"
20 #include "libdevmapper-event.h"
21 #include "dmeventd_lvm.h"
22
23 #include <pthread.h>
24 #include <syslog.h>
25
26 extern int dmeventd_debug;
27
28 /*
29  * register_device() is called first and performs initialisation.
30  * Only one device may be registered or unregistered at a time.
31  */
32 static pthread_mutex_t _register_mutex = PTHREAD_MUTEX_INITIALIZER;
33
34 /*
35  * Number of active registrations.
36  */
37 static int _register_count = 0;
38 static struct dm_pool *_mem_pool = NULL;
39 static void *_lvm_handle = NULL;
40
41 /*
42  * Currently only one event can be processed at a time.
43  */
44 static pthread_mutex_t _event_mutex = PTHREAD_MUTEX_INITIALIZER;
45
46 /*
47  * FIXME Do not pass things directly to syslog, rather use the existing logging
48  * facilities to sort logging ... however that mechanism needs to be somehow
49  * configurable and we don't have that option yet
50  */
51 static void _temporary_log_fn(int level,
52                               const char *file __attribute__((unused)),
53                               int line __attribute__((unused)),
54                               int dm_errno __attribute__((unused)),
55                               const char *message)
56 {
57         level &= ~(_LOG_STDERR | _LOG_ONCE);
58
59         switch (level) {
60         case _LOG_DEBUG:
61                 if (dmeventd_debug >= 3)
62                         syslog(LOG_DEBUG, "%s", message);
63                 break;
64         case _LOG_INFO:
65                 if (dmeventd_debug >= 2)
66                         syslog(LOG_INFO, "%s", message);
67                 break;
68         case _LOG_NOTICE:
69                 if (dmeventd_debug >= 1)
70                         syslog(LOG_NOTICE, "%s", message);
71                 break;
72         case _LOG_WARN:
73                 syslog(LOG_WARNING, "%s", message);
74                 break;
75         case _LOG_ERR:
76                 syslog(LOG_ERR, "%s", message);
77                 break;
78         default:
79                 syslog(LOG_CRIT, "%s", message);
80         }
81 }
82
83 void dmeventd_lvm2_lock(void)
84 {
85         if (pthread_mutex_trylock(&_event_mutex)) {
86                 syslog(LOG_NOTICE, "Another thread is handling an event. Waiting...");
87                 pthread_mutex_lock(&_event_mutex);
88         }
89 }
90
91 void dmeventd_lvm2_unlock(void)
92 {
93         pthread_mutex_unlock(&_event_mutex);
94 }
95
96 int dmeventd_lvm2_init(void)
97 {
98         int r = 0;
99
100         pthread_mutex_lock(&_register_mutex);
101
102         /*
103          * Need some space for allocations.  1024 should be more
104          * than enough for what we need (device mapper name splitting)
105          */
106         if (!_mem_pool && !(_mem_pool = dm_pool_create("mirror_dso", 1024)))
107                 goto out;
108
109         if (!_lvm_handle) {
110                 lvm2_log_fn(_temporary_log_fn);
111                 if (!(_lvm_handle = lvm2_init())) {
112                         dm_pool_destroy(_mem_pool);
113                         _mem_pool = NULL;
114                         goto out;
115                 }
116                 /* FIXME Temporary: move to dmeventd core */
117                 lvm2_run(_lvm_handle, "_memlock_inc");
118         }
119
120         _register_count++;
121         r = 1;
122
123 out:
124         pthread_mutex_unlock(&_register_mutex);
125         return r;
126 }
127
128 void dmeventd_lvm2_exit(void)
129 {
130         pthread_mutex_lock(&_register_mutex);
131
132         if (!--_register_count) {
133                 lvm2_run(_lvm_handle, "_memlock_dec");
134                 dm_pool_destroy(_mem_pool);
135                 _mem_pool = NULL;
136                 lvm2_exit(_lvm_handle);
137                 _lvm_handle = NULL;
138         }
139
140         pthread_mutex_unlock(&_register_mutex);
141 }
142
143 struct dm_pool *dmeventd_lvm2_pool(void)
144 {
145         return _mem_pool;
146 }
147
148 int dmeventd_lvm2_run(const char *cmdline)
149 {
150         return lvm2_run(_lvm_handle, cmdline);
151 }
152