0433b49142af68a4a52f7abd99949138546f684c
[multipath-tools/.git] / libmultipath / devmapper.c
1 /*
2  * snippets copied from device-mapper dmsetup.c
3  * Copyright (c) 2004, 2005 Christophe Varoqui
4  * Copyright (c) 2005 Kiyoshi Ueda, NEC
5  * Copyright (c) 2005 Patrick Caulfield, Redhat
6  */
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <stdarg.h>
10 #include <string.h>
11 #include <libdevmapper.h>
12 #include <ctype.h>
13 #include <unistd.h>
14 #include <errno.h>
15 #include <sys/sysmacros.h>
16
17 #include "checkers.h"
18 #include "vector.h"
19 #include "structs.h"
20 #include "debug.h"
21 #include "memory.h"
22 #include "devmapper.h"
23 #include "sysfs.h"
24 #include "config.h"
25 #include "wwids.h"
26
27 #include "log_pthread.h"
28 #include <sys/types.h>
29 #include <time.h>
30
31 #define MAX_WAIT 5
32 #define LOOPS_PER_SEC 5
33
34 static int dm_conf_verbosity;
35
36 #ifdef LIBDM_API_DEFERRED
37 static int dm_cancel_remove_partmaps(const char * mapname);
38 #endif
39
40 static int do_foreach_partmaps(const char * mapname,
41                                int (*partmap_func)(const char *, void *),
42                                void *data);
43
44 #ifndef LIBDM_API_COOKIE
45 static inline int dm_task_set_cookie(struct dm_task *dmt, uint32_t *c, int a)
46 {
47         return 1;
48 }
49
50 void dm_udev_wait(unsigned int c)
51 {
52 }
53
54 void dm_udev_set_sync_support(int c)
55 {
56 }
57
58 #endif
59
60 static void
61 dm_write_log (int level, const char *file, int line, const char *f, ...)
62 {
63         va_list ap;
64         int thres;
65
66         if (level > 6)
67                 level = 6;
68
69         thres = dm_conf_verbosity;
70         if (thres <= 3 || level > thres)
71                 return;
72
73         va_start(ap, f);
74         if (logsink < 1) {
75                 if (logsink == 0) {
76                         time_t t = time(NULL);
77                         struct tm *tb = localtime(&t);
78                         char buff[16];
79
80                         strftime(buff, sizeof(buff), "%b %d %H:%M:%S", tb);
81                         buff[sizeof(buff)-1] = '\0';
82
83                         fprintf(stderr, "%s | ", buff);
84                 }
85                 fprintf(stderr, "libdevmapper: %s(%i): ", file, line);
86                 vfprintf(stderr, f, ap);
87                 fprintf(stderr, "\n");
88         } else {
89                 condlog(level, "libdevmapper: %s(%i): ", file, line);
90                 log_safe(level + 3, f, ap);
91         }
92         va_end(ap);
93
94         return;
95 }
96
97 void dm_init(int v)
98 {
99         dm_conf_verbosity = v;
100         dm_log_init(&dm_write_log);
101         dm_log_init_verbose(v + 3);
102 }
103
104 static int
105 dm_lib_prereq (void)
106 {
107         char version[64];
108         int v[3];
109 #if defined(LIBDM_API_DEFERRED)
110         int minv[3] = {1, 2, 89};
111 #elif defined(DM_SUBSYSTEM_UDEV_FLAG0)
112         int minv[3] = {1, 2, 82};
113 #elif defined(LIBDM_API_COOKIE)
114         int minv[3] = {1, 2, 38};
115 #else
116         int minv[3] = {1, 2, 8};
117 #endif
118
119         dm_get_library_version(version, sizeof(version));
120         condlog(3, "libdevmapper version %s", version);
121         if (sscanf(version, "%d.%d.%d ", &v[0], &v[1], &v[2]) != 3) {
122                 condlog(0, "invalid libdevmapper version %s", version);
123                 return 1;
124         }
125
126         if VERSION_GE(v, minv)
127                 return 0;
128         condlog(0, "libdevmapper version must be >= %d.%.2d.%.2d",
129                 minv[0], minv[1], minv[2]);
130         return 1;
131 }
132
133 int
134 dm_drv_version(unsigned int *v)
135 {
136         char buff[64];
137
138         v[0] = 0;
139         v[1] = 0;
140         v[2] = 0;
141
142         if (!dm_driver_version(buff, sizeof(buff))) {
143                 condlog(0, "cannot get kernel dm version");
144                 return 1;
145         }
146         if (sscanf(buff, "%u.%u.%u ", &v[0], &v[1], &v[2]) != 3) {
147                 condlog(0, "invalid kernel dm version '%s'", buff);
148                 return 1;
149         }
150         return 0;
151 }
152
153 int
154 dm_tgt_version (unsigned int * version, char * str)
155 {
156         int r = 2;
157         struct dm_task *dmt;
158         struct dm_versions *target;
159         struct dm_versions *last_target;
160         unsigned int *v;
161
162         version[0] = 0;
163         version[1] = 0;
164         version[2] = 0;
165
166         if (!(dmt = dm_task_create(DM_DEVICE_LIST_VERSIONS)))
167                 return 1;
168
169         dm_task_no_open_count(dmt);
170
171         if (!dm_task_run(dmt)) {
172                 condlog(0, "Can not communicate with kernel DM");
173                 goto out;
174         }
175         target = dm_task_get_versions(dmt);
176
177         do {
178                 last_target = target;
179                 if (!strncmp(str, target->name, strlen(str))) {
180                         r = 1;
181                         break;
182                 }
183                 target = (void *) target + target->next;
184         } while (last_target != target);
185
186         if (r == 2) {
187                 condlog(0, "DM %s kernel driver not loaded", str);
188                 goto out;
189         }
190         v = target->version;
191         version[0] = v[0];
192         version[1] = v[1];
193         version[2] = v[2];
194         r = 0;
195 out:
196         dm_task_destroy(dmt);
197         return r;
198 }
199
200 static int
201 dm_tgt_prereq (unsigned int *ver)
202 {
203         unsigned int minv[3] = {1, 0, 3};
204         unsigned int version[3] = {0, 0, 0};
205         unsigned int * v = version;
206
207         if (dm_tgt_version(v, TGT_MPATH)) {
208                 /* in doubt return not capable */
209                 return 1;
210         }
211
212         /* test request based multipath capability */
213         condlog(3, "DM multipath kernel driver v%u.%u.%u",
214                 v[0], v[1], v[2]);
215
216         if (VERSION_GE(v, minv)) {
217                 ver[0] = v[0];
218                 ver[1] = v[1];
219                 ver[2] = v[2];
220                 return 0;
221         }
222
223         condlog(0, "DM multipath kernel driver must be >= v%u.%u.%u",
224                 minv[0], minv[1], minv[2]);
225         return 1;
226 }
227
228 static int dm_prereq(unsigned int *v)
229 {
230         if (dm_lib_prereq())
231                 return 1;
232         return dm_tgt_prereq(v);
233 }
234
235 static int libmp_dm_udev_sync = 0;
236
237 void libmp_udev_set_sync_support(int on)
238 {
239         libmp_dm_udev_sync = !!on;
240 }
241
242 void libmp_dm_init(void)
243 {
244         struct config *conf;
245         int verbosity;
246         unsigned int version[3];
247
248         if (dm_prereq(version))
249                 exit(1);
250         conf = get_multipath_config();
251         verbosity = conf->verbosity;
252         memcpy(conf->version, version, sizeof(version));
253         put_multipath_config(conf);
254         dm_init(verbosity);
255         dm_udev_set_sync_support(libmp_dm_udev_sync);
256 }
257
258 struct dm_task*
259 libmp_dm_task_create(int task)
260 {
261         static pthread_once_t dm_initialized = PTHREAD_ONCE_INIT;
262
263         pthread_once(&dm_initialized, libmp_dm_init);
264         return dm_task_create(task);
265 }
266
267 #define do_deferred(x) ((x) == DEFERRED_REMOVE_ON || (x) == DEFERRED_REMOVE_IN_PROGRESS)
268
269 static int
270 dm_simplecmd (int task, const char *name, int no_flush, int need_sync, uint16_t udev_flags, int deferred_remove) {
271         int r = 0;
272         int udev_wait_flag = ((need_sync || udev_flags) &&
273                               (task == DM_DEVICE_RESUME ||
274                                task == DM_DEVICE_REMOVE));
275         uint32_t cookie = 0;
276         struct dm_task *dmt;
277
278         if (!(dmt = libmp_dm_task_create (task)))
279                 return 0;
280
281         if (!dm_task_set_name (dmt, name))
282                 goto out;
283
284         dm_task_no_open_count(dmt);
285         dm_task_skip_lockfs(dmt);       /* for DM_DEVICE_RESUME */
286 #ifdef LIBDM_API_FLUSH
287         if (no_flush)
288                 dm_task_no_flush(dmt);          /* for DM_DEVICE_SUSPEND/RESUME */
289 #endif
290 #ifdef LIBDM_API_DEFERRED
291         if (do_deferred(deferred_remove))
292                 dm_task_deferred_remove(dmt);
293 #endif
294         if (udev_wait_flag &&
295             !dm_task_set_cookie(dmt, &cookie,
296                                 DM_UDEV_DISABLE_LIBRARY_FALLBACK | udev_flags))
297                 goto out;
298
299         r = dm_task_run (dmt);
300
301         if (udev_wait_flag)
302                         dm_udev_wait(cookie);
303 out:
304         dm_task_destroy (dmt);
305         return r;
306 }
307
308 int dm_simplecmd_flush (int task, const char *name, uint16_t udev_flags)
309 {
310         return dm_simplecmd(task, name, 0, 1, udev_flags, 0);
311 }
312
313 int dm_simplecmd_noflush (int task, const char *name, uint16_t udev_flags)
314 {
315         return dm_simplecmd(task, name, 1, 1, udev_flags, 0);
316 }
317
318 static int
319 dm_device_remove (const char *name, int needsync, int deferred_remove) {
320         return dm_simplecmd(DM_DEVICE_REMOVE, name, 0, needsync, 0,
321                             deferred_remove);
322 }
323
324 static int
325 dm_addmap (int task, const char *target, struct multipath *mpp,
326            char * params, int ro, uint16_t udev_flags) {
327         int r = 0;
328         struct dm_task *dmt;
329         char *prefixed_uuid = NULL;
330         uint32_t cookie = 0;
331
332         /* Need to add this here to allow 0 to be passed in udev_flags */
333         udev_flags |= DM_UDEV_DISABLE_LIBRARY_FALLBACK;
334
335         if (!(dmt = libmp_dm_task_create (task)))
336                 return 0;
337
338         if (!dm_task_set_name (dmt, mpp->alias))
339                 goto addout;
340
341         if (!dm_task_add_target (dmt, 0, mpp->size, target, params))
342                 goto addout;
343
344         if (ro)
345                 dm_task_set_ro(dmt);
346
347         if (task == DM_DEVICE_CREATE) {
348                 if (strlen(mpp->wwid) > 0) {
349                         prefixed_uuid = MALLOC(UUID_PREFIX_LEN +
350                                                strlen(mpp->wwid) + 1);
351                         if (!prefixed_uuid) {
352                                 condlog(0, "cannot create prefixed uuid : %s",
353                                         strerror(errno));
354                                 goto addout;
355                         }
356                         sprintf(prefixed_uuid, UUID_PREFIX "%s", mpp->wwid);
357                         if (!dm_task_set_uuid(dmt, prefixed_uuid))
358                                 goto freeout;
359                 }
360                 dm_task_skip_lockfs(dmt);
361 #ifdef LIBDM_API_FLUSH
362                 dm_task_no_flush(dmt);
363 #endif
364         }
365
366         if (mpp->attribute_flags & (1 << ATTR_MODE) &&
367             !dm_task_set_mode(dmt, mpp->mode))
368                 goto freeout;
369         if (mpp->attribute_flags & (1 << ATTR_UID) &&
370             !dm_task_set_uid(dmt, mpp->uid))
371                 goto freeout;
372         if (mpp->attribute_flags & (1 << ATTR_GID) &&
373             !dm_task_set_gid(dmt, mpp->gid))
374                 goto freeout;
375         condlog(4, "%s: %s [0 %llu %s %s]", mpp->alias,
376                 task == DM_DEVICE_RELOAD ? "reload" : "addmap", mpp->size,
377                 target, params);
378
379         dm_task_no_open_count(dmt);
380
381         if (task == DM_DEVICE_CREATE &&
382             !dm_task_set_cookie(dmt, &cookie, udev_flags))
383                 goto freeout;
384
385         r = dm_task_run (dmt);
386
387         if (task == DM_DEVICE_CREATE)
388                         dm_udev_wait(cookie);
389 freeout:
390         if (prefixed_uuid)
391                 FREE(prefixed_uuid);
392
393 addout:
394         dm_task_destroy (dmt);
395
396         return r;
397 }
398
399 static uint16_t build_udev_flags(const struct multipath *mpp, int reload)
400 {
401         /* DM_UDEV_DISABLE_LIBRARY_FALLBACK is added in dm_addmap */
402         return  (mpp->skip_kpartx == SKIP_KPARTX_ON ?
403                  MPATH_UDEV_NO_KPARTX_FLAG : 0) |
404                 ((mpp->nr_active == 0 || mpp->ghost_delay_tick > 0)?
405                  MPATH_UDEV_NO_PATHS_FLAG : 0) |
406                 (reload && !mpp->force_udev_reload ?
407                  MPATH_UDEV_RELOAD_FLAG : 0);
408 }
409
410 int dm_addmap_create (struct multipath *mpp, char * params)
411 {
412         int ro;
413         uint16_t udev_flags = build_udev_flags(mpp, 0);
414
415         for (ro = 0; ro <= 1; ro++) {
416                 int err;
417
418                 if (dm_addmap(DM_DEVICE_CREATE, TGT_MPATH, mpp, params, ro,
419                               udev_flags)) {
420                         if (unmark_failed_wwid(mpp->wwid) ==
421                             WWID_FAILED_CHANGED)
422                                 mpp->needs_paths_uevent = 1;
423                         return 1;
424                 }
425                 /*
426                  * DM_DEVICE_CREATE is actually DM_DEV_CREATE + DM_TABLE_LOAD.
427                  * Failing the second part leaves an empty map. Clean it up.
428                  */
429                 err = errno;
430                 if (dm_map_present(mpp->alias)) {
431                         condlog(3, "%s: failed to load map (a path might be in use)", mpp->alias);
432                         dm_flush_map_nosync(mpp->alias);
433                 }
434                 if (err != EROFS) {
435                         condlog(3, "%s: failed to load map, error %d",
436                                 mpp->alias, err);
437                         break;
438                 }
439         }
440         if (mark_failed_wwid(mpp->wwid) == WWID_FAILED_CHANGED)
441                 mpp->needs_paths_uevent = 1;
442         return 0;
443 }
444
445 #define ADDMAP_RW 0
446 #define ADDMAP_RO 1
447
448 int dm_addmap_reload(struct multipath *mpp, char *params, int flush)
449 {
450         int r = 0;
451         uint16_t udev_flags = build_udev_flags(mpp, 1);
452
453         /*
454          * DM_DEVICE_RELOAD cannot wait on a cookie, as
455          * the cookie will only ever be released after an
456          * DM_DEVICE_RESUME. So call DM_DEVICE_RESUME
457          * after each successful call to DM_DEVICE_RELOAD.
458          */
459         if (!mpp->force_readonly)
460                 r = dm_addmap(DM_DEVICE_RELOAD, TGT_MPATH, mpp, params,
461                               ADDMAP_RW, 0);
462         if (!r) {
463                 if (!mpp->force_readonly && errno != EROFS)
464                         return 0;
465                 r = dm_addmap(DM_DEVICE_RELOAD, TGT_MPATH, mpp,
466                               params, ADDMAP_RO, 0);
467         }
468         if (r)
469                 r = dm_simplecmd(DM_DEVICE_RESUME, mpp->alias, !flush,
470                                  1, udev_flags, 0);
471         if (r)
472                 return r;
473
474         /* If the resume failed, dm will leave the device suspended, and
475          * drop the new table, so doing a second resume will try using
476          * the original table */
477         if (dm_is_suspended(mpp->alias))
478                 dm_simplecmd(DM_DEVICE_RESUME, mpp->alias, !flush, 1,
479                              udev_flags, 0);
480         return 0;
481 }
482
483 static int
484 do_get_info(const char *name, struct dm_info *info)
485 {
486         int r = -1;
487         struct dm_task *dmt;
488
489         if (!(dmt = libmp_dm_task_create(DM_DEVICE_INFO)))
490                 return r;
491
492         if (!dm_task_set_name(dmt, name))
493                 goto out;
494
495         dm_task_no_open_count(dmt);
496
497         if (!dm_task_run(dmt))
498                 goto out;
499
500         if (!dm_task_get_info(dmt, info))
501                 goto out;
502
503         if (!info->exists)
504                 goto out;
505
506         r = 0;
507 out:
508         dm_task_destroy(dmt);
509         return r;
510 }
511
512 int dm_map_present(const char * str)
513 {
514         struct dm_info info;
515
516         return (do_get_info(str, &info) == 0);
517 }
518
519 int dm_get_map(const char *name, unsigned long long *size, char *outparams)
520 {
521         int r = 1;
522         struct dm_task *dmt;
523         uint64_t start, length;
524         char *target_type = NULL;
525         char *params = NULL;
526
527         if (!(dmt = libmp_dm_task_create(DM_DEVICE_TABLE)))
528                 return 1;
529
530         if (!dm_task_set_name(dmt, name))
531                 goto out;
532
533         dm_task_no_open_count(dmt);
534
535         if (!dm_task_run(dmt))
536                 goto out;
537
538         /* Fetch 1st target */
539         dm_get_next_target(dmt, NULL, &start, &length,
540                            &target_type, &params);
541
542         if (size)
543                 *size = length;
544
545         if (!outparams) {
546                 r = 0;
547                 goto out;
548         }
549         if (snprintf(outparams, PARAMS_SIZE, "%s", params) <= PARAMS_SIZE)
550                 r = 0;
551 out:
552         dm_task_destroy(dmt);
553         return r;
554 }
555
556 static int
557 dm_get_prefixed_uuid(const char *name, char *uuid)
558 {
559         struct dm_task *dmt;
560         const char *uuidtmp;
561         int r = 1;
562
563         dmt = libmp_dm_task_create(DM_DEVICE_INFO);
564         if (!dmt)
565                 return 1;
566
567         if (!dm_task_set_name (dmt, name))
568                 goto uuidout;
569
570         if (!dm_task_run(dmt))
571                 goto uuidout;
572
573         uuidtmp = dm_task_get_uuid(dmt);
574         if (uuidtmp)
575                 strcpy(uuid, uuidtmp);
576         else
577                 uuid[0] = '\0';
578
579         r = 0;
580 uuidout:
581         dm_task_destroy(dmt);
582         return r;
583 }
584
585 int dm_get_uuid(const char *name, char *uuid)
586 {
587         if (dm_get_prefixed_uuid(name, uuid))
588                 return 1;
589
590         if (!strncmp(uuid, UUID_PREFIX, UUID_PREFIX_LEN))
591                 memmove(uuid, uuid + UUID_PREFIX_LEN,
592                         strlen(uuid + UUID_PREFIX_LEN) + 1);
593         return 0;
594 }
595
596 static int
597 is_mpath_part(const char *part_name, const char *map_name)
598 {
599         char *p;
600         char part_uuid[WWID_SIZE], map_uuid[WWID_SIZE];
601
602         if (dm_get_prefixed_uuid(part_name, part_uuid))
603                 return 0;
604
605         if (dm_get_prefixed_uuid(map_name, map_uuid))
606                 return 0;
607
608         if (strncmp(part_uuid, "part", 4) != 0)
609                 return 0;
610
611         p = strstr(part_uuid, UUID_PREFIX);
612         if (p && !strcmp(p, map_uuid))
613                 return 1;
614
615         return 0;
616 }
617
618 int dm_get_status(const char *name, char *outstatus)
619 {
620         int r = 1;
621         struct dm_task *dmt;
622         uint64_t start, length;
623         char *target_type = NULL;
624         char *status = NULL;
625
626         if (!(dmt = libmp_dm_task_create(DM_DEVICE_STATUS)))
627                 return 1;
628
629         if (!dm_task_set_name(dmt, name))
630                 goto out;
631
632         dm_task_no_open_count(dmt);
633
634         if (!dm_task_run(dmt))
635                 goto out;
636
637         /* Fetch 1st target */
638         dm_get_next_target(dmt, NULL, &start, &length,
639                            &target_type, &status);
640         if (!status) {
641                 condlog(2, "get null status.");
642                 goto out;
643         }
644
645         if (snprintf(outstatus, PARAMS_SIZE, "%s", status) <= PARAMS_SIZE)
646                 r = 0;
647 out:
648         if (r)
649                 condlog(0, "%s: error getting map status string", name);
650
651         dm_task_destroy(dmt);
652         return r;
653 }
654
655 /*
656  * returns:
657  *    1 : match
658  *    0 : no match
659  *   -1 : empty map, or more than 1 target
660  */
661 int dm_type(const char *name, char *type)
662 {
663         int r = 0;
664         struct dm_task *dmt;
665         uint64_t start, length;
666         char *target_type = NULL;
667         char *params;
668
669         if (!(dmt = libmp_dm_task_create(DM_DEVICE_TABLE)))
670                 return 0;
671
672         if (!dm_task_set_name(dmt, name))
673                 goto out;
674
675         dm_task_no_open_count(dmt);
676
677         if (!dm_task_run(dmt))
678                 goto out;
679
680         /* Fetch 1st target */
681         if (dm_get_next_target(dmt, NULL, &start, &length,
682                                &target_type, &params) != NULL)
683                 /* multiple targets */
684                 r = -1;
685         else if (!target_type)
686                 r = -1;
687         else if (!strcmp(target_type, type))
688                 r = 1;
689
690 out:
691         dm_task_destroy(dmt);
692         return r;
693 }
694
695 int dm_is_mpath(const char *name)
696 {
697         int r = 0;
698         struct dm_task *dmt;
699         struct dm_info info;
700         uint64_t start, length;
701         char *target_type = NULL;
702         char *params;
703         const char *uuid;
704
705         if (!(dmt = libmp_dm_task_create(DM_DEVICE_TABLE)))
706                 return 0;
707
708         if (!dm_task_set_name(dmt, name))
709                 goto out;
710
711         dm_task_no_open_count(dmt);
712
713         if (!dm_task_run(dmt))
714                 goto out;
715
716         if (!dm_task_get_info(dmt, &info) || !info.exists)
717                 goto out;
718
719         uuid = dm_task_get_uuid(dmt);
720
721         if (!uuid || strncmp(uuid, UUID_PREFIX, UUID_PREFIX_LEN) != 0)
722                 goto out;
723
724         /* Fetch 1st target */
725         dm_get_next_target(dmt, NULL, &start, &length, &target_type, &params);
726
727         if (!target_type || strcmp(target_type, TGT_MPATH) != 0)
728                 goto out;
729
730         r = 1;
731 out:
732         dm_task_destroy(dmt);
733         return r;
734 }
735
736 static int
737 dm_dev_t (const char * mapname, char * dev_t, int len)
738 {
739         struct dm_info info;
740
741         if (do_get_info(mapname, &info) != 0)
742                 return 1;
743
744         if (snprintf(dev_t, len, "%i:%i", info.major, info.minor) > len)
745                 return 1;
746
747         return 0;
748 }
749
750 int
751 dm_get_opencount (const char * mapname)
752 {
753         int r = -1;
754         struct dm_task *dmt;
755         struct dm_info info;
756
757         if (!(dmt = libmp_dm_task_create(DM_DEVICE_INFO)))
758                 return 0;
759
760         if (!dm_task_set_name(dmt, mapname))
761                 goto out;
762
763         if (!dm_task_run(dmt))
764                 goto out;
765
766         if (!dm_task_get_info(dmt, &info))
767                 goto out;
768
769         if (!info.exists)
770                 goto out;
771
772         r = info.open_count;
773 out:
774         dm_task_destroy(dmt);
775         return r;
776 }
777
778 int
779 dm_get_major_minor(const char *name, int *major, int *minor)
780 {
781         struct dm_info info;
782
783         if (do_get_info(name, &info) != 0)
784                 return -1;
785
786         *major = info.major;
787         *minor = info.minor;
788         return 0;
789 }
790
791 static int
792 has_partmap(const char *name, void *data)
793 {
794         return 1;
795 }
796
797 static int
798 partmap_in_use(const char *name, void *data)
799 {
800         int part_count, *ret_count = (int *)data;
801         int open_count = dm_get_opencount(name);
802
803         if (ret_count)
804                 (*ret_count)++;
805         part_count = 0;
806         if (open_count) {
807                 if (do_foreach_partmaps(name, partmap_in_use, &part_count))
808                         return 1;
809                 if (open_count != part_count) {
810                         condlog(2, "%s: map in use", name);
811                         return 1;
812                 }
813         }
814         return 0;
815 }
816
817 int _dm_flush_map (const char * mapname, int need_sync, int deferred_remove,
818                    int need_suspend, int retries)
819 {
820         int r;
821         int queue_if_no_path = 0;
822         int udev_flags = 0;
823         unsigned long long mapsize;
824         char params[PARAMS_SIZE] = {0};
825
826         if (!dm_is_mpath(mapname))
827                 return 0; /* nothing to do */
828
829         /* if the device currently has no partitions, do not
830            run kpartx on it if you fail to delete it */
831         if (do_foreach_partmaps(mapname, has_partmap, NULL) == 0)
832                 udev_flags |= MPATH_UDEV_NO_KPARTX_FLAG;
833
834         /* If you aren't doing a deferred remove, make sure that no
835          * devices are in use */
836         if (!do_deferred(deferred_remove) && partmap_in_use(mapname, NULL))
837                         return 1;
838
839         if (need_suspend &&
840             !dm_get_map(mapname, &mapsize, params) &&
841             strstr(params, "queue_if_no_path")) {
842                 if (!dm_queue_if_no_path(mapname, 0))
843                         queue_if_no_path = 1;
844                 else
845                         /* Leave queue_if_no_path alone if unset failed */
846                         queue_if_no_path = -1;
847         }
848
849         if (dm_remove_partmaps(mapname, need_sync, deferred_remove))
850                 return 1;
851
852         if (!do_deferred(deferred_remove) && dm_get_opencount(mapname)) {
853                 condlog(2, "%s: map in use", mapname);
854                 return 1;
855         }
856
857         do {
858                 if (need_suspend && queue_if_no_path != -1)
859                         dm_simplecmd_flush(DM_DEVICE_SUSPEND, mapname, 0);
860
861                 r = dm_device_remove(mapname, need_sync, deferred_remove);
862
863                 if (r) {
864                         if (do_deferred(deferred_remove)
865                             && dm_map_present(mapname)) {
866                                 condlog(4, "multipath map %s remove deferred",
867                                         mapname);
868                                 return 2;
869                         }
870                         condlog(4, "multipath map %s removed", mapname);
871                         return 0;
872                 } else {
873                         condlog(2, "failed to remove multipath map %s",
874                                 mapname);
875                         if (need_suspend && queue_if_no_path != -1) {
876                                 dm_simplecmd_noflush(DM_DEVICE_RESUME,
877                                                      mapname, udev_flags);
878                         }
879                 }
880                 if (retries)
881                         sleep(1);
882         } while (retries-- > 0);
883
884         if (queue_if_no_path == 1)
885                 dm_queue_if_no_path(mapname, 1);
886
887         return 1;
888 }
889
890 #ifdef LIBDM_API_DEFERRED
891
892 int
893 dm_flush_map_nopaths(const char * mapname, int deferred_remove)
894 {
895         return _dm_flush_map(mapname, 1, deferred_remove, 0, 0);
896 }
897
898 #else
899
900 int
901 dm_flush_map_nopaths(const char * mapname, int deferred_remove)
902 {
903         return _dm_flush_map(mapname, 1, 0, 0, 0);
904 }
905
906 #endif
907
908 int dm_flush_maps (int retries)
909 {
910         int r = 0;
911         struct dm_task *dmt;
912         struct dm_names *names;
913         unsigned next = 0;
914
915         if (!(dmt = libmp_dm_task_create (DM_DEVICE_LIST)))
916                 return 0;
917
918         dm_task_no_open_count(dmt);
919
920         if (!dm_task_run (dmt))
921                 goto out;
922
923         if (!(names = dm_task_get_names (dmt)))
924                 goto out;
925
926         if (!names->dev)
927                 goto out;
928
929         do {
930                 r |= dm_suspend_and_flush_map(names->name, retries);
931                 next = names->next;
932                 names = (void *) names + next;
933         } while (next);
934
935 out:
936         dm_task_destroy (dmt);
937         return r;
938 }
939
940 int
941 dm_message(const char * mapname, char * message)
942 {
943         int r = 1;
944         struct dm_task *dmt;
945
946         if (!(dmt = libmp_dm_task_create(DM_DEVICE_TARGET_MSG)))
947                 return 1;
948
949         if (!dm_task_set_name(dmt, mapname))
950                 goto out;
951
952         if (!dm_task_set_sector(dmt, 0))
953                 goto out;
954
955         if (!dm_task_set_message(dmt, message))
956                 goto out;
957
958         dm_task_no_open_count(dmt);
959
960         if (!dm_task_run(dmt))
961                 goto out;
962
963         r = 0;
964 out:
965         if (r)
966                 condlog(0, "DM message failed [%s]", message);
967
968         dm_task_destroy(dmt);
969         return r;
970 }
971
972 int
973 dm_fail_path(const char * mapname, char * path)
974 {
975         char message[32];
976
977         if (snprintf(message, 32, "fail_path %s", path) > 32)
978                 return 1;
979
980         return dm_message(mapname, message);
981 }
982
983 int
984 dm_reinstate_path(const char * mapname, char * path)
985 {
986         char message[32];
987
988         if (snprintf(message, 32, "reinstate_path %s", path) > 32)
989                 return 1;
990
991         return dm_message(mapname, message);
992 }
993
994 int
995 dm_queue_if_no_path(const char *mapname, int enable)
996 {
997         char *message;
998
999         if (enable)
1000                 message = "queue_if_no_path";
1001         else
1002                 message = "fail_if_no_path";
1003
1004         return dm_message(mapname, message);
1005 }
1006
1007 static int
1008 dm_groupmsg (const char * msg, const char * mapname, int index)
1009 {
1010         char message[32];
1011
1012         if (snprintf(message, 32, "%s_group %i", msg, index) > 32)
1013                 return 1;
1014
1015         return dm_message(mapname, message);
1016 }
1017
1018 int
1019 dm_switchgroup(const char * mapname, int index)
1020 {
1021         return dm_groupmsg("switch", mapname, index);
1022 }
1023
1024 int
1025 dm_enablegroup(const char * mapname, int index)
1026 {
1027         return dm_groupmsg("enable", mapname, index);
1028 }
1029
1030 int
1031 dm_disablegroup(const char * mapname, int index)
1032 {
1033         return dm_groupmsg("disable", mapname, index);
1034 }
1035
1036 struct multipath *dm_get_multipath(const char *name)
1037 {
1038         struct multipath *mpp = NULL;
1039
1040         mpp = alloc_multipath();
1041         if (!mpp)
1042                 return NULL;
1043
1044         mpp->alias = STRDUP(name);
1045
1046         if (!mpp->alias)
1047                 goto out;
1048
1049         if (dm_get_map(name, &mpp->size, NULL))
1050                 goto out;
1051
1052         dm_get_uuid(name, mpp->wwid);
1053         dm_get_info(name, &mpp->dmi);
1054
1055         return mpp;
1056 out:
1057         free_multipath(mpp, KEEP_PATHS);
1058         return NULL;
1059 }
1060
1061 int
1062 dm_get_maps (vector mp)
1063 {
1064         struct multipath * mpp;
1065         int r = 1;
1066         struct dm_task *dmt;
1067         struct dm_names *names;
1068         unsigned next = 0;
1069
1070         if (!mp)
1071                 return 1;
1072
1073         if (!(dmt = libmp_dm_task_create(DM_DEVICE_LIST)))
1074                 return 1;
1075
1076         dm_task_no_open_count(dmt);
1077
1078         if (!dm_task_run(dmt))
1079                 goto out;
1080
1081         if (!(names = dm_task_get_names(dmt)))
1082                 goto out;
1083
1084         if (!names->dev) {
1085                 r = 0; /* this is perfectly valid */
1086                 goto out;
1087         }
1088
1089         do {
1090                 if (!dm_is_mpath(names->name))
1091                         goto next;
1092
1093                 mpp = dm_get_multipath(names->name);
1094                 if (!mpp)
1095                         goto out;
1096
1097                 if (!vector_alloc_slot(mp))
1098                         goto out;
1099
1100                 vector_set_slot(mp, mpp);
1101                 mpp = NULL;
1102 next:
1103                 next = names->next;
1104                 names = (void *) names + next;
1105         } while (next);
1106
1107         r = 0;
1108         goto out;
1109 out:
1110         dm_task_destroy (dmt);
1111         return r;
1112 }
1113
1114 int
1115 dm_geteventnr (const char *name)
1116 {
1117         struct dm_info info;
1118
1119         if (do_get_info(name, &info) != 0)
1120                 return -1;
1121
1122         return info.event_nr;
1123 }
1124
1125 int
1126 dm_is_suspended(const char *name)
1127 {
1128         struct dm_info info;
1129
1130         if (do_get_info(name, &info) != 0)
1131                 return -1;
1132
1133         return info.suspended;
1134 }
1135
1136 char *
1137 dm_mapname(int major, int minor)
1138 {
1139         char * response = NULL;
1140         const char *map;
1141         struct dm_task *dmt;
1142         int r;
1143         int loop = MAX_WAIT * LOOPS_PER_SEC;
1144
1145         if (!(dmt = libmp_dm_task_create(DM_DEVICE_STATUS)))
1146                 return NULL;
1147
1148         if (!dm_task_set_major(dmt, major) ||
1149             !dm_task_set_minor(dmt, minor))
1150                 goto bad;
1151
1152         dm_task_no_open_count(dmt);
1153
1154         /*
1155          * device map might not be ready when we get here from
1156          * daemon uev_trigger -> uev_add_map
1157          */
1158         while (--loop) {
1159                 r = dm_task_run(dmt);
1160
1161                 if (r)
1162                         break;
1163
1164                 usleep(1000 * 1000 / LOOPS_PER_SEC);
1165         }
1166
1167         if (!r) {
1168                 condlog(0, "%i:%i: timeout fetching map name", major, minor);
1169                 goto bad;
1170         }
1171
1172         map = dm_task_get_name(dmt);
1173         if (map && strlen(map))
1174                 response = STRDUP((const char *)dm_task_get_name(dmt));
1175
1176         dm_task_destroy(dmt);
1177         return response;
1178 bad:
1179         dm_task_destroy(dmt);
1180         condlog(0, "%i:%i: error fetching map name", major, minor);
1181         return NULL;
1182 }
1183
1184 static int
1185 do_foreach_partmaps (const char * mapname,
1186                      int (*partmap_func)(const char *, void *),
1187                      void *data)
1188 {
1189         struct dm_task *dmt;
1190         struct dm_names *names;
1191         unsigned next = 0;
1192         char params[PARAMS_SIZE];
1193         unsigned long long size;
1194         char dev_t[32];
1195         int r = 1;
1196         char *p;
1197
1198         if (!(dmt = libmp_dm_task_create(DM_DEVICE_LIST)))
1199                 return 1;
1200
1201         dm_task_no_open_count(dmt);
1202
1203         if (!dm_task_run(dmt))
1204                 goto out;
1205
1206         if (!(names = dm_task_get_names(dmt)))
1207                 goto out;
1208
1209         if (!names->dev) {
1210                 r = 0; /* this is perfectly valid */
1211                 goto out;
1212         }
1213
1214         if (dm_dev_t(mapname, &dev_t[0], 32))
1215                 goto out;
1216
1217         do {
1218                 if (
1219                     /*
1220                      * if there is only a single "linear" target
1221                      */
1222                     (dm_type(names->name, TGT_PART) == 1) &&
1223
1224                     /*
1225                      * and the uuid of the target is a partition of the
1226                      * uuid of the multipath device
1227                      */
1228                     is_mpath_part(names->name, mapname) &&
1229
1230                     /*
1231                      * and we can fetch the map table from the kernel
1232                      */
1233                     !dm_get_map(names->name, &size, &params[0]) &&
1234
1235                     /*
1236                      * and the table maps over the multipath map
1237                      */
1238                     (p = strstr(params, dev_t)) &&
1239                     !isdigit(*(p + strlen(dev_t)))
1240                    ) {
1241                         if (partmap_func(names->name, data) != 0)
1242                                 goto out;
1243                 }
1244
1245                 next = names->next;
1246                 names = (void *) names + next;
1247         } while (next);
1248
1249         r = 0;
1250 out:
1251         dm_task_destroy (dmt);
1252         return r;
1253 }
1254
1255 struct remove_data {
1256         int need_sync;
1257         int deferred_remove;
1258 };
1259
1260 static int
1261 remove_partmap(const char *name, void *data)
1262 {
1263         struct remove_data *rd = (struct remove_data *)data;
1264
1265         if (dm_get_opencount(name)) {
1266                 dm_remove_partmaps(name, rd->need_sync, rd->deferred_remove);
1267                 if (!do_deferred(rd->deferred_remove) &&
1268                     dm_get_opencount(name)) {
1269                         condlog(2, "%s: map in use", name);
1270                         return 1;
1271                 }
1272         }
1273         condlog(4, "partition map %s removed", name);
1274         dm_device_remove(name, rd->need_sync, rd->deferred_remove);
1275         return 0;
1276 }
1277
1278 int
1279 dm_remove_partmaps (const char * mapname, int need_sync, int deferred_remove)
1280 {
1281         struct remove_data rd = { need_sync, deferred_remove };
1282         return do_foreach_partmaps(mapname, remove_partmap, &rd);
1283 }
1284
1285 #ifdef LIBDM_API_DEFERRED
1286
1287 static int
1288 cancel_remove_partmap (const char *name, void *unused)
1289 {
1290         if (dm_get_opencount(name))
1291                 dm_cancel_remove_partmaps(name);
1292         if (dm_message(name, "@cancel_deferred_remove") != 0)
1293                 condlog(0, "%s: can't cancel deferred remove: %s", name,
1294                         strerror(errno));
1295         return 0;
1296 }
1297
1298 static int
1299 dm_get_deferred_remove (const char * mapname)
1300 {
1301         struct dm_info info;
1302
1303         if (do_get_info(mapname, &info) != 0)
1304                 return -1;
1305
1306         return info.deferred_remove;
1307 }
1308
1309 static int
1310 dm_cancel_remove_partmaps(const char * mapname) {
1311         return do_foreach_partmaps(mapname, cancel_remove_partmap, NULL);
1312 }
1313
1314 int
1315 dm_cancel_deferred_remove (struct multipath *mpp)
1316 {
1317         int r = 0;
1318
1319         if (!dm_get_deferred_remove(mpp->alias))
1320                 return 0;
1321         if (mpp->deferred_remove == DEFERRED_REMOVE_IN_PROGRESS)
1322                 mpp->deferred_remove = DEFERRED_REMOVE_ON;
1323
1324         dm_cancel_remove_partmaps(mpp->alias);
1325         r = dm_message(mpp->alias, "@cancel_deferred_remove");
1326         if (r)
1327                 condlog(0, "%s: can't cancel deferred remove: %s", mpp->alias,
1328                                 strerror(errno));
1329         else
1330                 condlog(2, "%s: canceled deferred remove", mpp->alias);
1331         return r;
1332 }
1333
1334 #else
1335
1336 int
1337 dm_cancel_deferred_remove (struct multipath *mpp)
1338 {
1339         return 0;
1340 }
1341
1342 #endif
1343
1344 static struct dm_info *
1345 alloc_dminfo (void)
1346 {
1347         return MALLOC(sizeof(struct dm_info));
1348 }
1349
1350 int
1351 dm_get_info (const char * mapname, struct dm_info ** dmi)
1352 {
1353         if (!mapname)
1354                 return 1;
1355
1356         if (!*dmi)
1357                 *dmi = alloc_dminfo();
1358
1359         if (!*dmi)
1360                 return 1;
1361
1362         if (do_get_info(mapname, *dmi) != 0) {
1363                 memset(*dmi, 0, sizeof(struct dm_info));
1364                 FREE(*dmi);
1365                 *dmi = NULL;
1366                 return 1;
1367         }
1368         return 0;
1369 }
1370
1371 struct rename_data {
1372         const char *old;
1373         char *new;
1374         char *delim;
1375 };
1376
1377 static int
1378 rename_partmap (const char *name, void *data)
1379 {
1380         char buff[PARAMS_SIZE];
1381         int offset;
1382         struct rename_data *rd = (struct rename_data *)data;
1383
1384         if (strncmp(name, rd->old, strlen(rd->old)) != 0)
1385                 return 0;
1386         for (offset = strlen(rd->old); name[offset] && !(isdigit(name[offset])); offset++); /* do nothing */
1387         snprintf(buff, PARAMS_SIZE, "%s%s%s", rd->new, rd->delim,
1388                  name + offset);
1389         dm_rename(name, buff, rd->delim, SKIP_KPARTX_OFF);
1390         condlog(4, "partition map %s renamed", name);
1391         return 0;
1392 }
1393
1394 int
1395 dm_rename_partmaps (const char * old, char * new, char *delim)
1396 {
1397         struct rename_data rd;
1398
1399         rd.old = old;
1400         rd.new = new;
1401
1402         if (delim)
1403                 rd.delim = delim;
1404         else {
1405                 if (isdigit(new[strlen(new)-1]))
1406                         rd.delim = "p";
1407                 else
1408                         rd.delim = "";
1409         }
1410         return do_foreach_partmaps(old, rename_partmap, &rd);
1411 }
1412
1413 int
1414 dm_rename (const char * old, char * new, char *delim, int skip_kpartx)
1415 {
1416         int r = 0;
1417         struct dm_task *dmt;
1418         uint32_t cookie = 0;
1419         uint16_t udev_flags = DM_UDEV_DISABLE_LIBRARY_FALLBACK | ((skip_kpartx == SKIP_KPARTX_ON)? MPATH_UDEV_NO_KPARTX_FLAG : 0);
1420
1421         if (dm_rename_partmaps(old, new, delim))
1422                 return r;
1423
1424         if (!(dmt = libmp_dm_task_create(DM_DEVICE_RENAME)))
1425                 return r;
1426
1427         if (!dm_task_set_name(dmt, old))
1428                 goto out;
1429
1430         if (!dm_task_set_newname(dmt, new))
1431                 goto out;
1432
1433         dm_task_no_open_count(dmt);
1434
1435         if (!dm_task_set_cookie(dmt, &cookie, udev_flags))
1436                 goto out;
1437         r = dm_task_run(dmt);
1438
1439         dm_udev_wait(cookie);
1440
1441 out:
1442         dm_task_destroy(dmt);
1443
1444         return r;
1445 }
1446
1447 void dm_reassign_deps(char *table, const char *dep, const char *newdep)
1448 {
1449         char *n, *newtable;
1450         const char *p;
1451
1452         newtable = strdup(table);
1453         if (!newtable)
1454                 return;
1455         p = strstr(newtable, dep);
1456         n = table + (p - newtable);
1457         strcpy(n, newdep);
1458         n += strlen(newdep);
1459         p += strlen(dep);
1460         strcat(n, p);
1461         FREE(newtable);
1462 }
1463
1464 int dm_reassign_table(const char *name, char *old, char *new)
1465 {
1466         int r = 0, modified = 0;
1467         uint64_t start, length;
1468         struct dm_task *dmt, *reload_dmt;
1469         char *target, *params = NULL;
1470         char *buff;
1471         void *next = NULL;
1472
1473         if (!(dmt = libmp_dm_task_create(DM_DEVICE_TABLE)))
1474                 return 0;
1475
1476         if (!dm_task_set_name(dmt, name))
1477                 goto out;
1478
1479         dm_task_no_open_count(dmt);
1480
1481         if (!dm_task_run(dmt))
1482                 goto out;
1483         if (!(reload_dmt = libmp_dm_task_create(DM_DEVICE_RELOAD)))
1484                 goto out;
1485         if (!dm_task_set_name(reload_dmt, name))
1486                 goto out_reload;
1487
1488         do {
1489                 next = dm_get_next_target(dmt, next, &start, &length,
1490                                           &target, &params);
1491                 buff = strdup(params);
1492                 if (!buff) {
1493                         condlog(3, "%s: failed to replace target %s, "
1494                                 "out of memory", name, target);
1495                         goto out_reload;
1496                 }
1497                 if (strcmp(target, TGT_MPATH) && strstr(params, old)) {
1498                         condlog(3, "%s: replace target %s %s",
1499                                 name, target, buff);
1500                         dm_reassign_deps(buff, old, new);
1501                         condlog(3, "%s: with target %s %s",
1502                                 name, target, buff);
1503                         modified++;
1504                 }
1505                 dm_task_add_target(reload_dmt, start, length, target, buff);
1506                 free(buff);
1507         } while (next);
1508
1509         if (modified) {
1510                 dm_task_no_open_count(reload_dmt);
1511
1512                 if (!dm_task_run(reload_dmt)) {
1513                         condlog(3, "%s: failed to reassign targets", name);
1514                         goto out_reload;
1515                 }
1516                 dm_simplecmd_noflush(DM_DEVICE_RESUME, name,
1517                                      MPATH_UDEV_RELOAD_FLAG);
1518         }
1519         r = 1;
1520
1521 out_reload:
1522         dm_task_destroy(reload_dmt);
1523 out:
1524         dm_task_destroy(dmt);
1525         return r;
1526 }
1527
1528
1529 /*
1530  * Reassign existing device-mapper table(s) to not use
1531  * the block devices but point to the multipathed
1532  * device instead
1533  */
1534 int dm_reassign(const char *mapname)
1535 {
1536         struct dm_deps *deps;
1537         struct dm_task *dmt;
1538         struct dm_info info;
1539         char dev_t[32], dm_dep[32];
1540         int r = 0, i;
1541
1542         if (dm_dev_t(mapname, &dev_t[0], 32)) {
1543                 condlog(3, "%s: failed to get device number", mapname);
1544                 return 1;
1545         }
1546
1547         if (!(dmt = libmp_dm_task_create(DM_DEVICE_DEPS))) {
1548                 condlog(3, "%s: couldn't make dm task", mapname);
1549                 return 0;
1550         }
1551
1552         if (!dm_task_set_name(dmt, mapname))
1553                 goto out;
1554
1555         dm_task_no_open_count(dmt);
1556
1557         if (!dm_task_run(dmt))
1558                 goto out;
1559
1560         if (!dm_task_get_info(dmt, &info))
1561                 goto out;
1562
1563         if (!(deps = dm_task_get_deps(dmt)))
1564                 goto out;
1565
1566         if (!info.exists)
1567                 goto out;
1568
1569         for (i = 0; i < deps->count; i++) {
1570                 sprintf(dm_dep, "%d:%d",
1571                         major(deps->device[i]),
1572                         minor(deps->device[i]));
1573                 sysfs_check_holders(dm_dep, dev_t);
1574         }
1575
1576         r = 1;
1577 out:
1578         dm_task_destroy (dmt);
1579         return r;
1580 }
1581
1582 int dm_setgeometry(struct multipath *mpp)
1583 {
1584         struct dm_task *dmt;
1585         struct path *pp;
1586         char heads[4], sectors[4];
1587         char cylinders[10], start[32];
1588         int r = 0;
1589
1590         if (!mpp)
1591                 return 1;
1592
1593         pp = first_path(mpp);
1594         if (!pp) {
1595                 condlog(3, "%s: no path for geometry", mpp->alias);
1596                 return 1;
1597         }
1598         if (pp->geom.cylinders == 0 ||
1599             pp->geom.heads == 0 ||
1600             pp->geom.sectors == 0) {
1601                 condlog(3, "%s: invalid geometry on %s", mpp->alias, pp->dev);
1602                 return 1;
1603         }
1604
1605         if (!(dmt = libmp_dm_task_create(DM_DEVICE_SET_GEOMETRY)))
1606                 return 0;
1607
1608         if (!dm_task_set_name(dmt, mpp->alias))
1609                 goto out;
1610
1611         dm_task_no_open_count(dmt);
1612
1613         /* What a sick interface ... */
1614         snprintf(heads, 4, "%u", pp->geom.heads);
1615         snprintf(sectors, 4, "%u", pp->geom.sectors);
1616         snprintf(cylinders, 10, "%u", pp->geom.cylinders);
1617         snprintf(start, 32, "%lu", pp->geom.start);
1618         if (!dm_task_set_geometry(dmt, cylinders, heads, sectors, start)) {
1619                 condlog(3, "%s: Failed to set geometry", mpp->alias);
1620                 goto out;
1621         }
1622
1623         r = dm_task_run(dmt);
1624 out:
1625         dm_task_destroy(dmt);
1626
1627         return r;
1628 }