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)
191 dm_task_destroy(dmt);
196 dm_type(char * name, char * type)
201 uint64_t start, length;
202 char *target_type = NULL;
205 if (!(dmt = dm_task_create(DM_DEVICE_TABLE)))
208 if (!dm_task_set_name(dmt, name))
211 dm_task_no_open_count(dmt);
213 if (!dm_task_run(dmt))
216 /* Fetch 1st target */
217 next = dm_get_next_target(dmt, next, &start, &length,
218 &target_type, ¶ms);
220 if (0 == strcmp(target_type, type))
224 dm_task_destroy(dmt);
229 dm_dev_t (char * mapname, char * dev_t, int len)
235 if (!(dmt = dm_task_create(DM_DEVICE_INFO)))
238 if (!dm_task_set_name(dmt, mapname))
241 if (!dm_task_run(dmt))
244 if (!dm_task_get_info(dmt, &info))
248 if (snprintf(dev_t, len, "%i:%i", info.major, info.minor) > len)
253 dm_task_destroy(dmt);
258 dm_get_opencount (char * mapname)
264 if (!(dmt = dm_task_create(DM_DEVICE_INFO)))
267 if (!dm_task_set_name(dmt, mapname))
270 if (!dm_task_run(dmt))
273 if (!dm_task_get_info(dmt, &info))
278 dm_task_destroy(dmt);
283 dm_get_minor (char * mapname)
289 if (!(dmt = dm_task_create(DM_DEVICE_INFO)))
292 if (!dm_task_set_name(dmt, mapname))
295 if (!dm_task_run(dmt))
298 if (!dm_task_get_info(dmt, &info))
303 dm_task_destroy(dmt);
308 dm_flush_map (char * mapname, char * type)
312 if (!dm_map_present(mapname))
315 if (!dm_type(mapname, type))
318 if (dm_remove_partmaps(mapname))
321 if (dm_get_opencount(mapname))
324 r = dm_simplecmd(DM_DEVICE_REMOVE, mapname);
327 condlog(4, "multipath map %s removed", mapname);
334 dm_flush_maps (char * type)
338 struct dm_names *names;
341 if (!(dmt = dm_task_create (DM_DEVICE_LIST)))
344 dm_task_no_open_count(dmt);
346 if (!dm_task_run (dmt))
349 if (!(names = dm_task_get_names (dmt)))
356 r += dm_flush_map(names->name, type);
358 names = (void *) names + next;
362 dm_task_destroy (dmt);
367 dm_fail_path(char * mapname, char * path)
373 if (!(dmt = dm_task_create(DM_DEVICE_TARGET_MSG)))
376 if (!dm_task_set_name(dmt, mapname))
379 if (!dm_task_set_sector(dmt, 0))
382 if (snprintf(str, 32, "fail_path %s\n", path) > 32)
385 if (!dm_task_set_message(dmt, str))
388 dm_task_no_open_count(dmt);
390 if (!dm_task_run(dmt))
395 dm_task_destroy(dmt);
400 dm_reinstate(char * mapname, char * path)
406 if (!(dmt = dm_task_create(DM_DEVICE_TARGET_MSG)))
409 if (!dm_task_set_name(dmt, mapname))
412 if (!dm_task_set_sector(dmt, 0))
415 if (snprintf(str, 32, "reinstate_path %s\n", path) > 32)
418 if (!dm_task_set_message(dmt, str))
421 dm_task_no_open_count(dmt);
423 if (!dm_task_run(dmt))
428 dm_task_destroy(dmt);
433 dm_groupmsg (char * msg, char * mapname, int index)
439 if (!(dmt = dm_task_create(DM_DEVICE_TARGET_MSG)))
442 if (!dm_task_set_name(dmt, mapname))
445 if (!dm_task_set_sector(dmt, 0))
448 snprintf(str, 24, "%s_group %i\n", msg, index);
449 condlog(3, "message %s 0 %s", mapname, str);
451 if (!dm_task_set_message(dmt, str))
454 dm_task_no_open_count(dmt);
456 if (!dm_task_run(dmt))
462 dm_task_destroy(dmt);
468 dm_switchgroup(char * mapname, int index)
470 return dm_groupmsg("switch", mapname,index);
474 dm_enablegroup(char * mapname, int index)
476 return dm_groupmsg("enable", mapname,index);
480 dm_disablegroup(char * mapname, int index)
482 return dm_groupmsg("disable", mapname,index);
486 dm_get_maps (vector mp, char * type)
488 struct multipath * mpp;
491 struct dm_names *names;
497 if (!(dmt = dm_task_create(DM_DEVICE_LIST)))
500 dm_task_no_open_count(dmt);
502 if (!dm_task_run(dmt))
505 if (!(names = dm_task_get_names(dmt)))
509 r = 0; /* this is perfectly valid */
514 if (dm_type(names->name, type)) {
515 mpp = alloc_multipath();
520 if (dm_get_map(names->name, &mpp->size, mpp->params))
523 if (dm_get_status(names->name, mpp->status))
526 mpp->alias = MALLOC(strlen(names->name) + 1);
531 strncat(mpp->alias, names->name, strlen(names->name));
533 if (!vector_alloc_slot(mp))
536 vector_set_slot(mp, mpp);
540 names = (void *) names + next;
546 free_multipath(mpp, KEEP_PATHS);
548 dm_task_destroy (dmt);
553 dm_geteventnr (char *name)
558 if (!(dmt = dm_task_create(DM_DEVICE_INFO)))
561 if (!dm_task_set_name(dmt, name))
564 dm_task_no_open_count(dmt);
566 if (!dm_task_run(dmt))
569 if (!dm_task_get_info(dmt, &info)) {
580 dm_task_destroy(dmt);
582 return info.event_nr;
586 dm_mapname(int major, int minor, char *type)
590 uint64_t start, length;
591 char *target_type = NULL;
594 int loop = MAX_WAIT * LOOPS_PER_SEC;
596 if (!(dmt = dm_task_create(DM_DEVICE_STATUS)))
599 if (!dm_task_set_major(dmt, major) ||
600 !dm_task_set_minor(dmt, minor))
603 dm_task_no_open_count(dmt);
606 * device map might not be ready when we get here from
610 r = dm_task_run(dmt);
615 usleep(1000 * 1000 / LOOPS_PER_SEC);
625 next = dm_get_next_target(dmt, next, &start, &length,
626 &target_type, ¶ms);
627 if (target_type && strcmp(target_type, type))
632 dm_task_destroy(dmt);
633 return strdup(dm_task_get_name(dmt));
635 dm_task_destroy(dmt);
640 dm_remove_partmaps (char * mapname)
643 struct dm_names *names;
645 char params[PARAMS_SIZE];
650 if (!(dmt = dm_task_create(DM_DEVICE_LIST)))
653 dm_task_no_open_count(dmt);
655 if (!dm_task_run(dmt))
658 if (!(names = dm_task_get_names(dmt)))
662 r = 0; /* this is perfectly valid */
666 if (dm_dev_t(mapname, &dev_t[0], 32))
672 * if devmap target is "linear"
674 dm_type(names->name, "linear") &&
677 * and the multipath mapname and the part mapname start
680 !strncmp(names->name, mapname, strlen(mapname)) &&
683 * and the opencount is 0 for us to allow removal
685 !dm_get_opencount(names->name) &&
688 * and we can fetch the map table from the kernel
690 !dm_get_map(names->name, &size, ¶ms[0]) &&
693 * and the table maps over the multipath map
695 strstr(params, dev_t)
698 * then it's a kpartx generated partition.
701 condlog(4, "partition map %s removed",
703 dm_simplecmd(DM_DEVICE_REMOVE, names->name);
707 names = (void *) names + next;
712 dm_task_destroy (dmt);