summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/canonicalize.h1
-rw-r--r--lib/canonicalize.c48
-rw-r--r--shlibs/blkid/src/devname.c27
3 files changed, 47 insertions, 29 deletions
diff --git a/include/canonicalize.h b/include/canonicalize.h
index b04510c7..f26df18c 100644
--- a/include/canonicalize.h
+++ b/include/canonicalize.h
@@ -4,5 +4,6 @@
#include "c.h" /* for PATH_MAX */
extern char *canonicalize_path(const char *path);
+extern char *canonicalize_dm_name(const char *ptname);
#endif /* CANONICALIZE_H */
diff --git a/lib/canonicalize.c b/lib/canonicalize.c
index b888fbb8..e54cf0c0 100644
--- a/lib/canonicalize.c
+++ b/lib/canonicalize.c
@@ -20,6 +20,9 @@
*
* TODO: use canonicalize_file_name() when exist in glibc
*/
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
@@ -136,17 +139,54 @@ myrealpath(const char *path, char *resolved_path, int maxreslth) {
return NULL;
}
+/*
+ * Converts private "dm-N" names to "/dev/mapper/<name>"
+ *
+ * Since 2.6.29 (patch 784aae735d9b0bba3f8b9faef4c8b30df3bf0128) kernel sysfs
+ * provides the real DM device names in /sys/block/<ptname>/dm/name
+ */
char *
-canonicalize_path(const char *path) {
+canonicalize_dm_name(const char *ptname)
+{
+ FILE *f;
+ size_t sz;
+ char path[256], name[256], *res = NULL;
+
+ snprintf(path, sizeof(path), "/sys/block/%s/dm/name", ptname);
+ if (!(f = fopen(path, "r")))
+ return NULL;
+
+ /* read "<name>\n" from sysfs */
+ if (fgets(name, sizeof(name), f) && (sz = strlen(name)) > 1) {
+ name[sz - 1] = '\0';
+ snprintf(path, sizeof(path), "/dev/mapper/%s", name);
+ res = strdup(path);
+ }
+ fclose(f);
+ return res;
+}
+
+char *
+canonicalize_path(const char *path)
+{
char canonical[PATH_MAX+2];
+ char *p;
if (path == NULL)
return NULL;
- if (myrealpath (path, canonical, PATH_MAX+1))
- return strdup(canonical);
+ if (!myrealpath(path, canonical, PATH_MAX+1))
+ return strdup(path);
+
+
+ p = strrchr(canonical, '/');
+ if (p && strncmp(p, "/dm-", 4) == 0 && isdigit(*(p + 4))) {
+ p = canonicalize_dm_name(p+1);
+ if (p)
+ return p;
+ }
- return strdup(path);
+ return strdup(canonical);
}
diff --git a/shlibs/blkid/src/devname.c b/shlibs/blkid/src/devname.c
index fe0d1b33..d048c722 100644
--- a/shlibs/blkid/src/devname.c
+++ b/shlibs/blkid/src/devname.c
@@ -38,6 +38,7 @@
#include <time.h>
#include "blkidP.h"
+#include "canonicalize.h" /* $(top_srcdir)/include */
/*
* Find a dev struct in the cache by device name, if available.
@@ -153,30 +154,6 @@ static int is_dm_leaf(const char *devname)
}
/*
- * Since 2.6.29 (patch 784aae735d9b0bba3f8b9faef4c8b30df3bf0128) kernel sysfs
- * provides the real DM device names in /sys/block/<ptname>/dm/name
- */
-static char *get_dm_name(const char *ptname)
-{
- FILE *f;
- size_t sz;
- char path[256], name[256], *res = NULL;
-
- snprintf(path, sizeof(path), "/sys/block/%s/dm/name", ptname);
- if ((f = fopen(path, "r")) == NULL)
- return NULL;
-
- /* read "<name>\n" from sysfs */
- if (fgets(name, sizeof(name), f) && (sz = strlen(name)) > 1) {
- name[sz - 1] = '\0';
- snprintf(path, sizeof(path), "/dev/mapper/%s", name);
- res = blkid_strdup(path);
- }
- fclose(f);
- return res;
-}
-
-/*
* Probe a single block device to add to the device cache.
*/
static void probe_one(blkid_cache cache, const char *ptname,
@@ -207,7 +184,7 @@ static void probe_one(blkid_cache cache, const char *ptname,
* to standard /dev/mapper/<name>.
*/
if (!strncmp(ptname, "dm-", 3) && isdigit(ptname[3])) {
- devname = get_dm_name(ptname);
+ devname = canonicalize_dm_name(ptname);
if (!devname)
blkid__scan_dir("/dev/mapper", devno, 0, &devname);
if (devname)