[dm-devel] patch for adding new multipath mapped devices
egoggin at emc.com
egoggin at emc.com
Mon Jul 17 19:29:20 UTC 2006
Chrisophe,
This patch tries to deal with the fact that neither a dm mapped device's
name nor any of its targets are necessarily available at the time
hotplug/udev announces the existence of the mapped device. Since my attempt
to patch this in the kernel was rejected 8 or so months ago, this patch
tries to deal with these badly ordered events by simply inserting delays
when thought justified. The scope of the existing delay in dm_mapname() is
changed to incorporate the retrieval of the mapped
device's name and a new function dm_map_target_present() is created which
will delay until at least one target exists for a named map.
Without both of these changes, it is hit-or-miss whether or not
multipathd(8) will correctly learn about a dm multipath mapped device newly
added by multipath(8).
diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c
index c0765ae..081e25c 100644
--- a/libmultipath/devmapper.c
+++ b/libmultipath/devmapper.c
@@ -183,6 +183,41 @@ out:
}
extern int
+dm_map_target_present (char * str)
+{
+ int r = 0;
+ struct dm_task *dmt;
+ struct dm_info info;
+ int loop = MAX_WAIT * LOOPS_PER_SEC;
+
+ if (!(dmt = dm_task_create(DM_DEVICE_INFO)))
+ return 0;
+
+ if (!dm_task_set_name(dmt, str))
+ goto out;
+
+ dm_task_no_open_count(dmt);
+
+ while (--loop) {
+ dm_shut_log();
+ if (!dm_task_run(dmt))
+ goto out;
+ dm_restore_log();
+
+ if (!dm_task_get_info(dmt, &info))
+ goto out;
+
+ if (info.target_count) {
+ r = 1;
+ break;
+ }
+ }
+out:
+ dm_task_destroy(dmt);
+ return r;
+}
+
+extern int
dm_get_map(char * name, unsigned long long * size, char * outparams)
{
int r = 1;
@@ -725,21 +760,21 @@ dm_mapname(int major, int minor)
r = dm_task_run(dmt);
dm_restore_log();
- if (r)
+ if (!r) {
+ condlog(0, "%i:%i: timeout fetching map name",
+ major, minor);
+ goto bad;
+ }
+
+ map = dm_task_get_name(dmt);
+ if (map && strlen(map))
+ response = STRDUP((char *)dm_task_get_name(dmt));
+ if (response)
break;
usleep(1000 * 1000 / LOOPS_PER_SEC);
}
- if (!r) {
- condlog(0, "%i:%i: timeout fetching map name", major,
minor);
- goto bad;
- }
-
- map = dm_task_get_name(dmt);
- if (map && strlen(map))
- response = STRDUP((char *)dm_task_get_name(dmt));
-
dm_task_destroy(dmt);
return response;
bad:
diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h
index c7879a7..e11c037 100644
--- a/libmultipath/devmapper.h
+++ b/libmultipath/devmapper.h
@@ -5,6 +5,7 @@ int dm_simplecmd (int, const char *);
int dm_addmap (int, const char *, const char *, const char *,
unsigned long long, const char *uuid);
int dm_map_present (char *);
+int dm_map_target_present (char *);
int dm_get_map(char *, unsigned long long *, char *);
int dm_get_status(char *, char *);
int dm_type(char *, char *);
diff --git a/multipathd/main.c b/multipathd/main.c
index 91a1597..48a69b9 100644
--- a/multipathd/main.c
+++ b/multipathd/main.c
@@ -234,7 +234,7 @@ ev_add_map (char * devname, struct vecto
if (!alias)
return 1;
- map_present = dm_map_present(alias);
+ map_present = dm_map_target_present(alias);
if (map_present && dm_type(alias, DEFAULT_TARGET) <= 0) {
condlog(4, "%s: not a multipath map", alias);
More information about the dm-devel
mailing list