4 #include <libdevmapper.h>
6 #include <linux/kdev_t.h>
15 #define LOOPS_PER_SEC 5
18 dm_prereq (char * str, int x, int y, int z)
22 struct dm_versions *target;
23 struct dm_versions *last_target;
25 if (!(dmt = dm_task_create(DM_DEVICE_LIST_VERSIONS)))
28 dm_task_no_open_count(dmt);
30 if (!dm_task_run(dmt))
33 target = dm_task_get_versions(dmt);
35 /* Fetch targets and print 'em */
39 if (!strncmp(str, target->name, strlen(str)) &&
40 /* dummy prereq on multipath version */
41 target->version[0] >= x &&
42 target->version[1] >= y &&
43 target->version[2] >= z
47 target = (void *) target + target->next;
48 } while (last_target != target);
56 dm_simplecmd (int task, const char *name) {
60 if (!(dmt = dm_task_create (task)))
63 if (!dm_task_set_name (dmt, name))
66 dm_task_no_open_count(dmt);
68 r = dm_task_run (dmt);
71 dm_task_destroy (dmt);
76 dm_addmap (int task, const char *name, const char *target,
77 const char *params, unsigned long size) {
81 if (!(dmt = dm_task_create (task)))
84 if (!dm_task_set_name (dmt, name))
87 if (!dm_task_add_target (dmt, 0, size, target, params))
90 dm_task_no_open_count(dmt);
92 r = dm_task_run (dmt);
95 dm_task_destroy (dmt);
100 dm_map_present (char * str)
106 if (!(dmt = dm_task_create(DM_DEVICE_INFO)))
109 if (!dm_task_set_name(dmt, str))
112 dm_task_no_open_count(dmt);
114 if (!dm_task_run(dmt))
117 if (!dm_task_get_info(dmt, &info))
123 dm_task_destroy(dmt);
128 dm_get_map(char * name, unsigned long * size, char * outparams)
133 uint64_t start, length;
134 char *target_type = NULL;
137 if (!(dmt = dm_task_create(DM_DEVICE_TABLE)))
140 if (!dm_task_set_name(dmt, name))
143 dm_task_no_open_count(dmt);
145 if (!dm_task_run(dmt))
148 /* Fetch 1st target */
149 next = dm_get_next_target(dmt, next, &start, &length,
150 &target_type, ¶ms);
155 if (snprintf(outparams, PARAMS_SIZE, "%s", params) <= PARAMS_SIZE)
158 dm_task_destroy(dmt);
163 dm_get_status(char * name, char * outstatus)
168 uint64_t start, length;
172 if (!(dmt = dm_task_create(DM_DEVICE_STATUS)))
175 if (!dm_task_set_name(dmt, name))
178 dm_task_no_open_count(dmt);
180 if (!dm_task_run(dmt))
183 /* Fetch 1st target */
184 next = dm_get_next_target(dmt, next, &start, &length,
185 &target_type, &status);
187 if (snprintf(outstatus, PARAMS_SIZE, "%s", status) <= PARAMS_SIZE)
190 dm_task_destroy(dmt);
195 dm_type(char * name, char * type)
200 uint64_t start, length;
201 char *target_type = NULL;
204 if (!(dmt = dm_task_create(DM_DEVICE_TABLE)))
207 if (!dm_task_set_name(dmt, name))
210 dm_task_no_open_count(dmt);
212 if (!dm_task_run(dmt))
215 /* Fetch 1st target */
216 next = dm_get_next_target(dmt, next, &start, &length,
217 &target_type, ¶ms);
219 if (0 == strcmp(target_type, type))
223 dm_task_destroy(dmt);
228 dm_get_opencount (char * mapname)
234 if (!(dmt = dm_task_create(DM_DEVICE_INFO)))
237 if (!dm_task_set_name(dmt, mapname))
240 if (!dm_task_run(dmt))
243 if (!dm_task_get_info(dmt, &info))
248 dm_task_destroy(dmt);
253 dm_get_minor (char * mapname)
259 if (!(dmt = dm_task_create(DM_DEVICE_INFO)))
262 if (!dm_task_set_name(dmt, mapname))
265 if (!dm_task_run(dmt))
268 if (!dm_task_get_info(dmt, &info))
273 dm_task_destroy(dmt);
278 dm_flush_maps (char * type)
282 struct dm_names *names;
285 if (!(dmt = dm_task_create (DM_DEVICE_LIST)))
288 dm_task_no_open_count(dmt);
290 if (!dm_task_run (dmt))
293 if (!(names = dm_task_get_names (dmt)))
300 if (dm_type(names->name, type) &&
301 dm_get_opencount(names->name) == 0 &&
302 !dm_simplecmd(DM_DEVICE_REMOVE, names->name))
306 names = (void *) names + next;
310 dm_task_destroy (dmt);
315 dm_fail_path(char * mapname, char * path)
321 if (!(dmt = dm_task_create(DM_DEVICE_TARGET_MSG)))
324 if (!dm_task_set_name(dmt, mapname))
327 if (!dm_task_set_sector(dmt, 0))
330 if (snprintf(str, 32, "fail_path %s\n", path) > 32)
333 if (!dm_task_set_message(dmt, str))
336 dm_task_no_open_count(dmt);
338 if (!dm_task_run(dmt))
343 dm_task_destroy(dmt);
348 dm_reinstate(char * mapname, char * path)
354 if (!(dmt = dm_task_create(DM_DEVICE_TARGET_MSG)))
357 if (!dm_task_set_name(dmt, mapname))
360 if (!dm_task_set_sector(dmt, 0))
363 if (snprintf(str, 32, "reinstate_path %s\n", path) > 32)
366 if (!dm_task_set_message(dmt, str))
369 dm_task_no_open_count(dmt);
371 if (!dm_task_run(dmt))
376 dm_task_destroy(dmt);
381 dm_switchgroup(char * mapname, int index)
387 if (!(dmt = dm_task_create(DM_DEVICE_TARGET_MSG)))
390 if (!dm_task_set_name(dmt, mapname))
393 if (!dm_task_set_sector(dmt, 0))
396 snprintf(str, 24, "switch_group %i\n", index);
397 condlog(3, "message %s 0 %s", mapname, str);
399 if (!dm_task_set_message(dmt, str))
402 dm_task_no_open_count(dmt);
404 if (!dm_task_run(dmt))
410 dm_task_destroy(dmt);
416 dm_get_maps (vector mp, char * type)
418 struct multipath * mpp;
421 struct dm_names *names;
427 if (!(dmt = dm_task_create(DM_DEVICE_LIST)))
430 dm_task_no_open_count(dmt);
432 if (!dm_task_run(dmt))
435 if (!(names = dm_task_get_names(dmt)))
439 r = 0; /* this is perfectly valid */
444 if (dm_type(names->name, type)) {
445 mpp = alloc_multipath();
450 if (dm_get_map(names->name, &mpp->size, mpp->params))
453 if (dm_get_status(names->name, mpp->status))
456 mpp->alias = MALLOC(strlen(names->name) + 1);
461 strncat(mpp->alias, names->name, strlen(names->name));
463 if (!vector_alloc_slot(mp))
466 vector_set_slot(mp, mpp);
470 names = (void *) names + next;
476 free_multipath(mpp, KEEP_PATHS);
478 dm_task_destroy (dmt);
483 dm_geteventnr (char *name)
488 if (!(dmt = dm_task_create(DM_DEVICE_INFO)))
491 if (!dm_task_set_name(dmt, name))
494 dm_task_no_open_count(dmt);
496 if (!dm_task_run(dmt))
499 if (!dm_task_get_info(dmt, &info)) {
510 dm_task_destroy(dmt);
512 return info.event_nr;
516 dm_mapname(int major, int minor, char *type)
520 uint64_t start, length;
521 char *target_type = NULL;
524 int loop = MAX_WAIT * LOOPS_PER_SEC;
526 if (!(dmt = dm_task_create(DM_DEVICE_STATUS)))
529 if (!dm_task_set_major(dmt, major) ||
530 !dm_task_set_minor(dmt, minor))
533 dm_task_no_open_count(dmt);
536 * device map might not be ready when we get here from
540 r = dm_task_run(dmt);
545 usleep(1000 * 1000 / LOOPS_PER_SEC);
555 next = dm_get_next_target(dmt, next, &start, &length,
556 &target_type, ¶ms);
557 if (target_type && strcmp(target_type, type))
562 dm_task_destroy(dmt);
563 return strdup(dm_task_get_name(dmt));
565 dm_task_destroy(dmt);