31e64a7e9488ba341e8ca919570f1f3eb5b08dc4
[multipath-tools/.git] / multipathd / dmevents.c
1 /*
2  * Copyright (c) 2004, 2005 Christophe Varoqui
3  * Copyright (c) 2005 Kiyoshi Ueda, NEC
4  * Copyright (c) 2005 Edward Goggin, EMC
5  * Copyright (c) 2005, 2018 Benjamin Marzinski, Redhat
6  */
7 #include <unistd.h>
8 #include <libdevmapper.h>
9 #include <sys/mman.h>
10 #include <pthread.h>
11 #include <urcu.h>
12 #include <poll.h>
13 #include <sys/ioctl.h>
14 #include <sys/types.h>
15 #include <sys/stat.h>
16 #include <fcntl.h>
17 #include <linux/dm-ioctl.h>
18 #include <errno.h>
19
20 #include "vector.h"
21 #include "structs.h"
22 #include "structs_vec.h"
23 #include "devmapper.h"
24 #include "debug.h"
25 #include "main.h"
26 #include "dmevents.h"
27 #include "util.h"
28
29 #ifndef DM_DEV_ARM_POLL
30 #define DM_DEV_ARM_POLL _IOWR(DM_IOCTL, DM_DEV_SET_GEOMETRY_CMD + 1, struct dm_ioctl)
31 #endif
32
33 enum event_actions {
34         EVENT_NOTHING,
35         EVENT_REMOVE,
36         EVENT_UPDATE,
37 };
38
39 struct dev_event {
40         char name[WWID_SIZE];
41         uint32_t evt_nr;
42         enum event_actions action;
43 };
44
45 struct dmevent_waiter {
46         int fd;
47         struct vectors *vecs;
48         vector events;
49         pthread_mutex_t events_lock;
50 };
51
52 static struct dmevent_waiter *waiter;
53 /*
54  * DM_VERSION_MINOR hasn't been updated when DM_DEV_ARM_POLL
55  * was added in kernel 4.13. 4.37.0 (4.14) has it, safely.
56  */
57 static const unsigned int DM_VERSION_FOR_ARM_POLL[] = {4, 37, 0};
58
59 int dmevent_poll_supported(void)
60 {
61         unsigned int v[3];
62
63         if (dm_drv_version(v))
64                 return 0;
65
66         if (VERSION_GE(v, DM_VERSION_FOR_ARM_POLL))
67                 return 1;
68         return 0;
69 }
70
71
72 int init_dmevent_waiter(struct vectors *vecs)
73 {
74         if (!vecs) {
75                 condlog(0, "can't create waiter structure. invalid vectors");
76                 goto fail;
77         }
78         waiter = (struct dmevent_waiter *)malloc(sizeof(struct dmevent_waiter));
79         if (!waiter) {
80                 condlog(0, "failed to allocate waiter structure");
81                 goto fail;
82         }
83         memset(waiter, 0, sizeof(struct dmevent_waiter));
84         waiter->events = vector_alloc();
85         if (!waiter->events) {
86                 condlog(0, "failed to allocate waiter events vector");
87                 goto fail_waiter;
88         }
89         waiter->fd = open("/dev/mapper/control", O_RDWR);
90         if (waiter->fd < 0) {
91                 condlog(0, "failed to open /dev/mapper/control for waiter");
92                 goto fail_events;
93         }
94         pthread_mutex_init(&waiter->events_lock, NULL);
95         waiter->vecs = vecs;
96
97         return 0;
98 fail_events:
99         vector_free(waiter->events);
100 fail_waiter:
101         free(waiter);
102 fail:
103         waiter = NULL;
104         return -1;
105 }
106
107 void cleanup_dmevent_waiter(void)
108 {
109         struct dev_event *dev_evt;
110         int i;
111
112         if (!waiter)
113                 return;
114         pthread_mutex_destroy(&waiter->events_lock);
115         close(waiter->fd);
116         vector_foreach_slot(waiter->events, dev_evt, i)
117                 free(dev_evt);
118         vector_free(waiter->events);
119         free(waiter);
120         waiter = NULL;
121 }
122
123 static int arm_dm_event_poll(int fd)
124 {
125         struct dm_ioctl dmi;
126         memset(&dmi, 0, sizeof(dmi));
127         dmi.version[0] = DM_VERSION_FOR_ARM_POLL[0];
128         dmi.version[1] = DM_VERSION_FOR_ARM_POLL[1];
129         dmi.version[2] = DM_VERSION_FOR_ARM_POLL[2];
130         /* This flag currently does nothing. It simply exists to
131          * duplicate the behavior of libdevmapper */
132         dmi.flags = 0x4;
133         dmi.data_start = offsetof(struct dm_ioctl, data);
134         dmi.data_size = sizeof(dmi);
135         return ioctl(fd, DM_DEV_ARM_POLL, &dmi);
136 }
137
138 /*
139  * As of version 4.37.0 device-mapper stores the event number in the
140  * dm_names structure after the name, when DM_DEVICE_LIST is called
141  */
142 static uint32_t dm_event_nr(struct dm_names *n)
143 {
144         return *(uint32_t *)(((uintptr_t)(strchr(n->name, 0) + 1) + 7) & ~7);
145 }
146
147 static int dm_get_events(void)
148 {
149         struct dm_task *dmt;
150         struct dm_names *names;
151         struct dev_event *dev_evt;
152         int i;
153
154         if (!(dmt = libmp_dm_task_create(DM_DEVICE_LIST)))
155                 return -1;
156
157         dm_task_no_open_count(dmt);
158
159         if (!dm_task_run(dmt))
160                 goto fail;
161
162         if (!(names = dm_task_get_names(dmt)))
163                 goto fail;
164
165         pthread_mutex_lock(&waiter->events_lock);
166         vector_foreach_slot(waiter->events, dev_evt, i)
167                 dev_evt->action = EVENT_REMOVE;
168         while (names->dev) {
169                 uint32_t event_nr;
170
171                 if (!dm_is_mpath(names->name))
172                         goto next;
173
174                 event_nr = dm_event_nr(names);
175                 vector_foreach_slot(waiter->events, dev_evt, i) {
176                         if (!strcmp(dev_evt->name, names->name)) {
177                                 if (event_nr != dev_evt->evt_nr) {
178                                         dev_evt->evt_nr = event_nr;
179                                         dev_evt->action = EVENT_UPDATE;
180                                 } else
181                                         dev_evt->action = EVENT_NOTHING;
182                                 break;
183                         }
184                 }
185 next:
186                 if (!names->next)
187                         break;
188                 names = (void *)names + names->next;
189         }
190         pthread_mutex_unlock(&waiter->events_lock);
191         dm_task_destroy(dmt);
192         return 0;
193
194 fail:
195         dm_task_destroy(dmt);
196         return -1;
197 }
198
199 /* You must call __setup_multipath() after calling this function, to
200  * deal with any events that came in before the device was added */
201 int watch_dmevents(char *name)
202 {
203         int event_nr;
204         struct dev_event *dev_evt, *old_dev_evt;
205         int i;
206
207         if (!dm_is_mpath(name)) {
208                 condlog(0, "%s: not a multipath device. can't watch events",
209                         name);
210                 return -1;
211         }
212
213         if ((event_nr = dm_geteventnr(name)) < 0)
214                 return -1;
215
216         dev_evt = (struct dev_event *)malloc(sizeof(struct dev_event));
217         if (!dev_evt) {
218                 condlog(0, "%s: can't allocate event waiter structure", name);
219                 return -1;
220         }
221
222         strlcpy(dev_evt->name, name, WWID_SIZE);
223         dev_evt->evt_nr = event_nr;
224         dev_evt->action = EVENT_NOTHING;
225
226         pthread_mutex_lock(&waiter->events_lock);
227         vector_foreach_slot(waiter->events, old_dev_evt, i){
228                 if (!strcmp(dev_evt->name, old_dev_evt->name)) {
229                         /* caller will be updating this device */
230                         old_dev_evt->evt_nr = event_nr;
231                         old_dev_evt->action = EVENT_NOTHING;
232                         pthread_mutex_unlock(&waiter->events_lock);
233                         condlog(2, "%s: already waiting for events on device",
234                                 name);
235                         free(dev_evt);
236                         return 0;
237                 }
238         }
239         if (!vector_alloc_slot(waiter->events)) {
240                 pthread_mutex_unlock(&waiter->events_lock);
241                 free(dev_evt);
242                 return -1;
243         }
244         vector_set_slot(waiter->events, dev_evt);
245         pthread_mutex_unlock(&waiter->events_lock);
246         return 0;
247 }
248
249 void unwatch_all_dmevents(void)
250 {
251         struct dev_event *dev_evt;
252         int i;
253
254         pthread_mutex_lock(&waiter->events_lock);
255         vector_foreach_slot(waiter->events, dev_evt, i)
256                 free(dev_evt);
257         vector_reset(waiter->events);
258         pthread_mutex_unlock(&waiter->events_lock);
259 }
260
261 static void unwatch_dmevents(char *name)
262 {
263         struct dev_event *dev_evt;
264         int i;
265
266         pthread_mutex_lock(&waiter->events_lock);
267         vector_foreach_slot(waiter->events, dev_evt, i) {
268                 if (!strcmp(dev_evt->name, name)) {
269                         vector_del_slot(waiter->events, i);
270                         free(dev_evt);
271                         break;
272                 }
273         }
274         pthread_mutex_unlock(&waiter->events_lock);
275 }
276
277 /*
278  * returns the reschedule delay
279  * negative means *stop*
280  */
281
282 /* poll, arm, update, return */
283 static int dmevent_loop (void)
284 {
285         int r, i = 0;
286         struct pollfd pfd;
287         struct dev_event *dev_evt;
288
289         pfd.fd = waiter->fd;
290         pfd.events = POLLIN;
291         r = poll(&pfd, 1, -1);
292         if (r <= 0) {
293                 condlog(0, "failed polling for dm events: %s", strerror(errno));
294                 /* sleep 1s and hope things get better */
295                 return 1;
296         }
297
298         if (arm_dm_event_poll(waiter->fd) != 0) {
299                 condlog(0, "Cannot re-arm event polling: %s", strerror(errno));
300                 /* sleep 1s and hope things get better */
301                 return 1;
302         }
303
304         if (dm_get_events() != 0) {
305                 condlog(0, "failed getting dm events: %s", strerror(errno));
306                 /* sleep 1s and hope things get better */
307                 return 1;
308         }
309
310         /*
311          * upon event ...
312          */
313
314         while (1) {
315                 int done = 1;
316                 struct dev_event curr_dev;
317
318                 pthread_mutex_lock(&waiter->events_lock);
319                 vector_foreach_slot(waiter->events, dev_evt, i) {
320                         if (dev_evt->action != EVENT_NOTHING) {
321                                 curr_dev = *dev_evt;
322                                 if (dev_evt->action == EVENT_REMOVE) {
323                                         vector_del_slot(waiter->events, i);
324                                         free(dev_evt);
325                                 } else
326                                         dev_evt->action = EVENT_NOTHING;
327                                 done = 0;
328                                 break;
329                         }
330                 }
331                 pthread_mutex_unlock(&waiter->events_lock);
332                 if (done)
333                         return 1;
334
335                 condlog(3, "%s: devmap event #%i", curr_dev.name,
336                         curr_dev.evt_nr);
337
338                 /*
339                  * event might be :
340                  *
341                  * 1) a table reload, which means our mpp structure is
342                  *    obsolete : refresh it through update_multipath()
343                  * 2) a path failed by DM : mark as such through
344                  *    update_multipath()
345                  * 3) map has gone away : stop the thread.
346                  * 4) a path reinstate : nothing to do
347                  * 5) a switch group : nothing to do
348                  */
349                 pthread_cleanup_push(cleanup_lock, &waiter->vecs->lock);
350                 lock(&waiter->vecs->lock);
351                 pthread_testcancel();
352                 r = 0;
353                 if (curr_dev.action == EVENT_REMOVE)
354                         remove_map_by_alias(curr_dev.name, waiter->vecs, 1);
355                 else
356                         r = update_multipath(waiter->vecs, curr_dev.name, 1);
357                 pthread_cleanup_pop(1);
358
359                 if (r) {
360                         condlog(2, "%s: stopped watching dmevents",
361                                 curr_dev.name);
362                         unwatch_dmevents(curr_dev.name);
363                 }
364         }
365         condlog(0, "dmevent waiter thread unexpectedly quit");
366         return -1; /* never reach there */
367 }
368
369 static void rcu_unregister(void *param)
370 {
371         rcu_unregister_thread();
372 }
373
374 void *wait_dmevents (void *unused)
375 {
376         int r;
377
378
379         if (!waiter) {
380                 condlog(0, "dmevents waiter not intialized");
381                 return NULL;
382         }
383
384         pthread_cleanup_push(rcu_unregister, NULL);
385         rcu_register_thread();
386         mlockall(MCL_CURRENT | MCL_FUTURE);
387
388         while (1) {
389                 r = dmevent_loop();
390
391                 if (r < 0)
392                         break;
393
394                 sleep(r);
395         }
396
397         pthread_cleanup_pop(1);
398         return NULL;
399 }