4 #include <libdevmapper.h>
6 #include <linux/kdev_t.h>
13 #include "devmapper.h"
16 #define LOOPS_PER_SEC 5
19 dm_prereq (char * str, int x, int y, int z)
23 struct dm_versions *target;
24 struct dm_versions *last_target;
26 if (!(dmt = dm_task_create(DM_DEVICE_LIST_VERSIONS)))
29 dm_task_no_open_count(dmt);
31 if (!dm_task_run(dmt))
34 target = dm_task_get_versions(dmt);
36 /* Fetch targets and print 'em */
40 if (!strncmp(str, target->name, strlen(str)) &&
41 /* dummy prereq on multipath version */
42 target->version[0] >= x &&
43 target->version[1] >= y &&
44 target->version[2] >= z
48 target = (void *) target + target->next;
49 } while (last_target != target);
57 dm_simplecmd (int task, const char *name) {
61 if (!(dmt = dm_task_create (task)))
64 if (!dm_task_set_name (dmt, name))
67 dm_task_no_open_count(dmt);
69 r = dm_task_run (dmt);
72 dm_task_destroy (dmt);
77 dm_addmap (int task, const char *name, const char *target,
78 const char *params, unsigned long size) {
82 if (!(dmt = dm_task_create (task)))
85 if (!dm_task_set_name (dmt, name))
88 if (!dm_task_add_target (dmt, 0, size, target, params))
91 dm_task_no_open_count(dmt);
93 r = dm_task_run (dmt);
96 dm_task_destroy (dmt);
101 dm_map_present (char * str)
107 if (!(dmt = dm_task_create(DM_DEVICE_INFO)))
110 if (!dm_task_set_name(dmt, str))
113 dm_task_no_open_count(dmt);
115 if (!dm_task_run(dmt))
118 if (!dm_task_get_info(dmt, &info))
124 dm_task_destroy(dmt);
129 dm_get_map(char * name, unsigned long * size, char * outparams)
134 uint64_t start, length;
135 char *target_type = NULL;
138 if (!(dmt = dm_task_create(DM_DEVICE_TABLE)))
141 if (!dm_task_set_name(dmt, name))
144 dm_task_no_open_count(dmt);
146 if (!dm_task_run(dmt))
149 /* Fetch 1st target */
150 next = dm_get_next_target(dmt, next, &start, &length,
151 &target_type, ¶ms);
156 if (snprintf(outparams, PARAMS_SIZE, "%s", params) <= PARAMS_SIZE)
159 dm_task_destroy(dmt);
164 dm_get_status(char * name, char * outstatus)
169 uint64_t start, length;
173 if (!(dmt = dm_task_create(DM_DEVICE_STATUS)))
176 if (!dm_task_set_name(dmt, name))
179 dm_task_no_open_count(dmt);
181 if (!dm_task_run(dmt))
184 /* Fetch 1st target */
185 next = dm_get_next_target(dmt, next, &start, &length,
186 &target_type, &status);
188 if (snprintf(outstatus, PARAMS_SIZE, "%s", status) <= PARAMS_SIZE)
192 condlog(0, "%s: error getting map status string", name);
194 dm_task_destroy(dmt);
199 dm_type(char * name, char * type)
204 uint64_t start, length;
205 char *target_type = NULL;
208 if (!(dmt = dm_task_create(DM_DEVICE_TABLE)))
211 if (!dm_task_set_name(dmt, name))
214 dm_task_no_open_count(dmt);
216 if (!dm_task_run(dmt))
219 /* Fetch 1st target */
220 next = dm_get_next_target(dmt, next, &start, &length,
221 &target_type, ¶ms);
223 if (0 == strcmp(target_type, type))
227 dm_task_destroy(dmt);
232 dm_dev_t (char * mapname, char * dev_t, int len)
238 if (!(dmt = dm_task_create(DM_DEVICE_INFO)))
241 if (!dm_task_set_name(dmt, mapname))
244 if (!dm_task_run(dmt))
247 if (!dm_task_get_info(dmt, &info))
251 if (snprintf(dev_t, len, "%i:%i", info.major, info.minor) > len)
256 dm_task_destroy(dmt);
261 dm_get_opencount (char * mapname)
267 if (!(dmt = dm_task_create(DM_DEVICE_INFO)))
270 if (!dm_task_set_name(dmt, mapname))
273 if (!dm_task_run(dmt))
276 if (!dm_task_get_info(dmt, &info))
281 dm_task_destroy(dmt);
286 dm_get_minor (char * mapname)
292 if (!(dmt = dm_task_create(DM_DEVICE_INFO)))
295 if (!dm_task_set_name(dmt, mapname))
298 if (!dm_task_run(dmt))
301 if (!dm_task_get_info(dmt, &info))
306 dm_task_destroy(dmt);
311 dm_flush_map (char * mapname, char * type)
315 if (!dm_map_present(mapname))
318 if (!dm_type(mapname, type))
321 if (dm_remove_partmaps(mapname))
324 if (dm_get_opencount(mapname))
327 r = dm_simplecmd(DM_DEVICE_REMOVE, mapname);
330 condlog(4, "multipath map %s removed", mapname);
337 dm_flush_maps (char * type)
341 struct dm_names *names;
344 if (!(dmt = dm_task_create (DM_DEVICE_LIST)))
347 dm_task_no_open_count(dmt);
349 if (!dm_task_run (dmt))
352 if (!(names = dm_task_get_names (dmt)))
359 r += dm_flush_map(names->name, type);
361 names = (void *) names + next;
365 dm_task_destroy (dmt);
370 dm_fail_path(char * mapname, char * path)
376 if (!(dmt = dm_task_create(DM_DEVICE_TARGET_MSG)))
379 if (!dm_task_set_name(dmt, mapname))
382 if (!dm_task_set_sector(dmt, 0))
385 if (snprintf(str, 32, "fail_path %s\n", path) > 32)
388 if (!dm_task_set_message(dmt, str))
391 dm_task_no_open_count(dmt);
393 if (!dm_task_run(dmt))
398 dm_task_destroy(dmt);
403 dm_reinstate(char * mapname, char * path)
409 if (!(dmt = dm_task_create(DM_DEVICE_TARGET_MSG)))
412 if (!dm_task_set_name(dmt, mapname))
415 if (!dm_task_set_sector(dmt, 0))
418 if (snprintf(str, 32, "reinstate_path %s\n", path) > 32)
421 if (!dm_task_set_message(dmt, str))
424 dm_task_no_open_count(dmt);
426 if (!dm_task_run(dmt))
431 dm_task_destroy(dmt);
436 dm_groupmsg (char * msg, char * mapname, int index)
442 if (!(dmt = dm_task_create(DM_DEVICE_TARGET_MSG)))
445 if (!dm_task_set_name(dmt, mapname))
448 if (!dm_task_set_sector(dmt, 0))
451 snprintf(str, 24, "%s_group %i\n", msg, index);
453 if (!dm_task_set_message(dmt, str))
456 dm_task_no_open_count(dmt);
458 if (!dm_task_run(dmt))
461 condlog(3, "message %s 0 %s", mapname, str);
466 condlog(3, "message %s 0 %s failed", mapname, str);
468 dm_task_destroy(dmt);
474 dm_switchgroup(char * mapname, int index)
476 return dm_groupmsg("switch", mapname,index);
480 dm_enablegroup(char * mapname, int index)
482 return dm_groupmsg("enable", mapname,index);
486 dm_disablegroup(char * mapname, int index)
488 return dm_groupmsg("disable", mapname,index);
492 dm_get_maps (vector mp, char * type)
494 struct multipath * mpp;
497 struct dm_names *names;
503 if (!(dmt = dm_task_create(DM_DEVICE_LIST)))
506 dm_task_no_open_count(dmt);
508 if (!dm_task_run(dmt))
511 if (!(names = dm_task_get_names(dmt)))
515 r = 0; /* this is perfectly valid */
520 if (dm_type(names->name, type)) {
521 mpp = alloc_multipath();
526 if (dm_get_map(names->name, &mpp->size, mpp->params))
529 if (dm_get_status(names->name, mpp->status))
532 mpp->alias = MALLOC(strlen(names->name) + 1);
537 strncat(mpp->alias, names->name, strlen(names->name));
539 if (!vector_alloc_slot(mp))
542 vector_set_slot(mp, mpp);
546 names = (void *) names + next;
552 free_multipath(mpp, KEEP_PATHS);
554 dm_task_destroy (dmt);
559 dm_geteventnr (char *name)
564 if (!(dmt = dm_task_create(DM_DEVICE_INFO)))
567 if (!dm_task_set_name(dmt, name))
570 dm_task_no_open_count(dmt);
572 if (!dm_task_run(dmt))
575 if (!dm_task_get_info(dmt, &info)) {
586 dm_task_destroy(dmt);
588 return info.event_nr;
592 dm_mapname(int major, int minor)
597 int loop = MAX_WAIT * LOOPS_PER_SEC;
599 if (!(dmt = dm_task_create(DM_DEVICE_STATUS)))
602 if (!dm_task_set_major(dmt, major) ||
603 !dm_task_set_minor(dmt, minor))
606 dm_task_no_open_count(dmt);
609 * device map might not be ready when we get here from
613 r = dm_task_run(dmt);
618 usleep(1000 * 1000 / LOOPS_PER_SEC);
622 condlog(0, "%i:%i: timeout fetching map name", major, minor);
626 response = STRDUP((char *)dm_task_get_name(dmt));
627 dm_task_destroy(dmt);
630 dm_task_destroy(dmt);
631 condlog(0, "%i:%i: error fetching map name", major, minor);
636 dm_remove_partmaps (char * mapname)
639 struct dm_names *names;
641 char params[PARAMS_SIZE];
646 if (!(dmt = dm_task_create(DM_DEVICE_LIST)))
649 dm_task_no_open_count(dmt);
651 if (!dm_task_run(dmt))
654 if (!(names = dm_task_get_names(dmt)))
658 r = 0; /* this is perfectly valid */
662 if (dm_dev_t(mapname, &dev_t[0], 32))
668 * if devmap target is "linear"
670 dm_type(names->name, "linear") &&
673 * and the multipath mapname and the part mapname start
676 !strncmp(names->name, mapname, strlen(mapname)) &&
679 * and the opencount is 0 for us to allow removal
681 !dm_get_opencount(names->name) &&
684 * and we can fetch the map table from the kernel
686 !dm_get_map(names->name, &size, ¶ms[0]) &&
689 * and the table maps over the multipath map
691 strstr(params, dev_t)
694 * then it's a kpartx generated partition.
697 condlog(4, "partition map %s removed",
699 dm_simplecmd(DM_DEVICE_REMOVE, names->name);
703 names = (void *) names + next;
708 dm_task_destroy (dmt);