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
8 #include <libdevmapper.h>
13 #include <sys/ioctl.h>
14 #include <sys/types.h>
17 #include <linux/dm-ioctl.h>
22 #include "structs_vec.h"
23 #include "devmapper.h"
29 #ifndef DM_DEV_ARM_POLL
30 #define DM_DEV_ARM_POLL _IOWR(DM_IOCTL, DM_DEV_SET_GEOMETRY_CMD + 1, struct dm_ioctl)
42 enum event_actions action;
45 struct dmevent_waiter {
49 pthread_mutex_t events_lock;
52 static struct dmevent_waiter *waiter;
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.
57 static const unsigned int DM_VERSION_FOR_ARM_POLL[] = {4, 37, 0};
59 int dmevent_poll_supported(void)
63 if (libmp_get_version(DM_KERNEL_VERSION, v))
66 if (VERSION_GE(v, DM_VERSION_FOR_ARM_POLL))
72 int init_dmevent_waiter(struct vectors *vecs)
75 condlog(0, "can't create waiter structure. invalid vectors");
78 waiter = (struct dmevent_waiter *)malloc(sizeof(struct dmevent_waiter));
80 condlog(0, "failed to allocate waiter structure");
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");
89 waiter->fd = open("/dev/mapper/control", O_RDWR);
91 condlog(0, "failed to open /dev/mapper/control for waiter");
94 pthread_mutex_init(&waiter->events_lock, NULL);
99 vector_free(waiter->events);
107 void cleanup_dmevent_waiter(void)
109 struct dev_event *dev_evt;
114 pthread_mutex_destroy(&waiter->events_lock);
116 vector_foreach_slot(waiter->events, dev_evt, i)
118 vector_free(waiter->events);
123 static int arm_dm_event_poll(int fd)
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 */
133 dmi.data_start = offsetof(struct dm_ioctl, data);
134 dmi.data_size = sizeof(dmi);
135 return ioctl(fd, DM_DEV_ARM_POLL, &dmi);
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
142 static uint32_t dm_event_nr(struct dm_names *n)
144 return *(uint32_t *)(((uintptr_t)(strchr(n->name, 0) + 1) + 7) & ~7);
147 static int dm_get_events(void)
150 struct dm_names *names;
151 struct dev_event *dev_evt;
154 if (!(dmt = libmp_dm_task_create(DM_DEVICE_LIST)))
157 dm_task_no_open_count(dmt);
159 if (!libmp_dm_task_run(dmt)) {
160 dm_log_error(3, DM_DEVICE_LIST, dmt);
164 if (!(names = dm_task_get_names(dmt)))
167 pthread_mutex_lock(&waiter->events_lock);
168 vector_foreach_slot(waiter->events, dev_evt, i)
169 dev_evt->action = EVENT_REMOVE;
173 /* Don't delete device if dm_is_mpath() fails without
174 * checking the device type */
175 if (dm_is_mpath(names->name) == 0)
178 event_nr = dm_event_nr(names);
179 vector_foreach_slot(waiter->events, dev_evt, i) {
180 if (!strcmp(dev_evt->name, names->name)) {
181 if (event_nr != dev_evt->evt_nr) {
182 dev_evt->evt_nr = event_nr;
183 dev_evt->action = EVENT_UPDATE;
185 dev_evt->action = EVENT_NOTHING;
192 names = (void *)names + names->next;
194 pthread_mutex_unlock(&waiter->events_lock);
195 dm_task_destroy(dmt);
199 dm_task_destroy(dmt);
203 /* You must call __setup_multipath() after calling this function, to
204 * deal with any events that came in before the device was added */
205 int watch_dmevents(char *name)
208 struct dev_event *dev_evt, *old_dev_evt;
211 /* We know that this is a multipath device, so only fail if
212 * device-mapper tells us that we're wrong */
213 if (dm_is_mpath(name) == 0) {
214 condlog(0, "%s: not a multipath device. can't watch events",
219 if ((event_nr = dm_geteventnr(name)) < 0)
222 dev_evt = (struct dev_event *)malloc(sizeof(struct dev_event));
224 condlog(0, "%s: can't allocate event waiter structure", name);
228 strlcpy(dev_evt->name, name, WWID_SIZE);
229 dev_evt->evt_nr = event_nr;
230 dev_evt->action = EVENT_NOTHING;
232 pthread_mutex_lock(&waiter->events_lock);
233 vector_foreach_slot(waiter->events, old_dev_evt, i){
234 if (!strcmp(dev_evt->name, old_dev_evt->name)) {
235 /* caller will be updating this device */
236 old_dev_evt->evt_nr = event_nr;
237 old_dev_evt->action = EVENT_NOTHING;
238 pthread_mutex_unlock(&waiter->events_lock);
239 condlog(2, "%s: already waiting for events on device",
245 if (!vector_alloc_slot(waiter->events)) {
246 pthread_mutex_unlock(&waiter->events_lock);
250 vector_set_slot(waiter->events, dev_evt);
251 pthread_mutex_unlock(&waiter->events_lock);
255 void unwatch_all_dmevents(void)
257 struct dev_event *dev_evt;
262 pthread_mutex_lock(&waiter->events_lock);
263 vector_foreach_slot(waiter->events, dev_evt, i)
265 vector_reset(waiter->events);
266 pthread_mutex_unlock(&waiter->events_lock);
269 static void unwatch_dmevents(char *name)
271 struct dev_event *dev_evt;
274 pthread_mutex_lock(&waiter->events_lock);
275 vector_foreach_slot(waiter->events, dev_evt, i) {
276 if (!strcmp(dev_evt->name, name)) {
277 vector_del_slot(waiter->events, i);
282 pthread_mutex_unlock(&waiter->events_lock);
286 * returns the reschedule delay
287 * negative means *stop*
290 /* poll, arm, update, return */
291 static int dmevent_loop (void)
295 struct dev_event *dev_evt;
299 r = poll(&pfd, 1, -1);
301 condlog(0, "failed polling for dm events: %s", strerror(errno));
302 /* sleep 1s and hope things get better */
306 if (arm_dm_event_poll(waiter->fd) != 0) {
307 condlog(0, "Cannot re-arm event polling: %s", strerror(errno));
308 /* sleep 1s and hope things get better */
312 if (dm_get_events() != 0) {
313 condlog(0, "failed getting dm events: %s", strerror(errno));
314 /* sleep 1s and hope things get better */
324 struct dev_event curr_dev;
326 pthread_mutex_lock(&waiter->events_lock);
327 vector_foreach_slot(waiter->events, dev_evt, i) {
328 if (dev_evt->action != EVENT_NOTHING) {
330 if (dev_evt->action == EVENT_REMOVE) {
331 vector_del_slot(waiter->events, i);
334 dev_evt->action = EVENT_NOTHING;
339 pthread_mutex_unlock(&waiter->events_lock);
343 condlog(3, "%s: devmap event #%i", curr_dev.name,
349 * 1) a table reload, which means our mpp structure is
350 * obsolete : refresh it through update_multipath()
351 * 2) a path failed by DM : mark as such through
353 * 3) map has gone away : stop the thread.
354 * 4) a path reinstate : nothing to do
355 * 5) a switch group : nothing to do
357 pthread_cleanup_push(cleanup_lock, &waiter->vecs->lock);
358 lock(&waiter->vecs->lock);
359 pthread_testcancel();
361 if (curr_dev.action == EVENT_REMOVE)
362 remove_map_by_alias(curr_dev.name, waiter->vecs);
364 r = update_multipath(waiter->vecs, curr_dev.name, 1);
365 pthread_cleanup_pop(1);
368 condlog(2, "%s: stopped watching dmevents",
370 unwatch_dmevents(curr_dev.name);
373 condlog(0, "dmevent waiter thread unexpectedly quit");
374 return -1; /* never reach there */
377 static void rcu_unregister(__attribute__((unused)) void *param)
379 rcu_unregister_thread();
382 void *wait_dmevents (__attribute__((unused)) void *unused)
388 condlog(0, "dmevents waiter not intialized");
392 pthread_cleanup_push(rcu_unregister, NULL);
393 rcu_register_thread();
394 mlockall(MCL_CURRENT | MCL_FUTURE);
405 pthread_cleanup_pop(1);