@@ -668,7 +668,12 @@ int dm_find_part(const char *parent, const char *delim, int part,
if (dm_type(tmp, "linear") != 1)
goto out;
- if (dm_devn(parent, &major, &minor))
+ /*
+ * Try nondm uuid first. That way we avoid confusing
+ * a device name with a device mapper name.
+ */
+ if (!nondm_parse_uuid(parent_uuid, &major, &minor) &&
+ dm_devn(parent, &major, &minor))
goto out;
snprintf(dev_t, sizeof(dev_t), "%d:%d", major, minor);
@@ -693,3 +698,40 @@ out:
free((void*)tmp);
return r;
}
+
+char *nondm_create_uuid(dev_t devt)
+{
+#define NONDM_UUID_BUFLEN (34 + sizeof(NONDM_UUID_PREFIX) + \
+ sizeof(NONDM_UUID_SUFFIX))
+ static char uuid_buf[NONDM_UUID_BUFLEN];
+ snprintf(uuid_buf, sizeof(uuid_buf), "%s_%u:%u_%s",
+ NONDM_UUID_PREFIX, major(devt), minor(devt),
+ NONDM_UUID_SUFFIX);
+ uuid_buf[NONDM_UUID_BUFLEN-1] = '\0';
+ return uuid_buf;
+}
+
+int nondm_parse_uuid(const char *uuid, int *major, int *minor)
+{
+ const char *p;
+ char *e;
+ int ma, mi;
+
+ if (strncmp(uuid, NONDM_UUID_PREFIX "_", sizeof(NONDM_UUID_PREFIX)))
+ return 0;
+ p = uuid + sizeof(NONDM_UUID_PREFIX);
+ ma = strtoul(p, &e, 10);
+ if (e == p || *e != ':')
+ return 0;
+ p = e + 1;
+ mi = strtoul(p, &e, 10);
+ if (e == p || *e != '_')
+ return 0;
+ p = e + 1;
+ if (strcmp(p, NONDM_UUID_SUFFIX))
+ return 0;
+
+ *major = ma;
+ *minor = mi;
+ return 1;
+}
@@ -22,4 +22,17 @@ int dm_find_part(const char *parent, const char *delim, int part,
const char *parent_uuid,
char *name, size_t namesiz, char **part_uuid, int verbose);
+/*
+ * UUID format for partitions created on non-DM devices
+ * ${UUID_PREFIX}devnode_${MAJOR}:${MINOR}_${NONDM_UUID_SUFFIX}"
+ * where ${UUID_PREFIX} is "part${PARTNO}-" (see devmapper.c).
+ *
+ * The suffix should be sufficiently unique to avoid incidental conflicts;
+ * the value below is a base64-encoded random number.
+ * The UUID format shouldn't be changed between kpartx releases.
+ */
+#define NONDM_UUID_PREFIX "devnode"
+#define NONDM_UUID_SUFFIX "Wh5pYvM"
+char *nondm_create_uuid(dev_t devt);
+int nondm_parse_uuid(const char *uuid, int *major, int *minor);
#endif /* _KPARTX_DEVMAPPER_H */
@@ -60,31 +60,6 @@ struct pt {
int ptct = 0;
int udev_sync = 1;
-/*
- * UUID format for partitions created on non-DM devices
- * ${UUID_PREFIX}devnode_${MAJOR}:${MINOR}_${NONDM_UUID_SUFFIX}"
- * where ${UUID_PREFIX} is "part${PARTNO}-" (see devmapper.c).
- *
- * The suffix should be sufficiently unique to avoid incidental conflicts;
- * the value below is a base64-encoded random number.
- * The UUID format shouldn't be changed between kpartx releases.
- */
-#define NONDM_UUID_PREFIX "devnode"
-#define NONDM_UUID_SUFFIX "Wh5pYvM"
-
-static char *
-nondm_create_uuid(dev_t devt)
-{
-#define NONDM_UUID_BUFLEN (34 + sizeof(NONDM_UUID_PREFIX) + \
- sizeof(NONDM_UUID_SUFFIX))
- static char uuid_buf[NONDM_UUID_BUFLEN];
- snprintf(uuid_buf, sizeof(uuid_buf), "%s_%u:%u_%s",
- NONDM_UUID_PREFIX, major(devt), minor(devt),
- NONDM_UUID_SUFFIX);
- uuid_buf[NONDM_UUID_BUFLEN-1] = '\0';
- return uuid_buf;
-}
-
static void
addpts(char *t, ptreader f)
{
Fix a pathological issue that I discovered with test-kpartx. When a dm device is named like a device node (e.g. dm name "loop1"), kpartx would erroneously pick the dm device if asked to work on partitions on the other device. Fortunately we can use the UUID scheme created earlier to see whether or not the device is a dm device. Signed-off-by: Martin Wilck <mwilck@suse.com> --- kpartx/devmapper.c | 44 +++++++++++++++++++++++++++++++++++++++++++- kpartx/devmapper.h | 13 +++++++++++++ kpartx/kpartx.c | 25 ------------------------- 3 files changed, 56 insertions(+), 26 deletions(-)