[Ocfs2-tools-devel] [PATCH 1/1] ocfs2/mount: mount command should convert mapper dm devname to canonical form

Tariq Saeed tariq.x.saeed at oracle.com
Mon Jan 27 12:31:41 PST 2014


Orabug: 17801902

The kernel commit 784aae735d9b0bba3f8b9faef4c8b30df3bf0128 required a patch
in the mount command to convert mapper device name of the form dm-<digit> to
canonical. For example, for the blk dev /dev/dm-0, /sys/block/dm-0/dm/name contains
the canonical name ocfs2-tmpdir, and /dev/mapper/ocfs2-tmpdir -> ../dm-0.
The fix was made in the generic mount (see util-linux-ng-2.17.2-12.14) but
not ported to ocfs2. This patch ports that fix to ocfs2-tools-1.8.0-11.

Signed-off-by: Tariq Saseed <tariq.x.saeed at oracle.com>
Signed-off-by: Srinivas Eeda <srinivas.eeda at oracle.com>
---
 mount.ocfs2/mount.ocfs2.c |    5 +++--
 mount.ocfs2/sundries.c    |   45 +++++++++++++++++++++++++++++++++++++++++----
 2 files changed, 44 insertions(+), 6 deletions(-)

diff --git a/mount.ocfs2/mount.ocfs2.c b/mount.ocfs2/mount.ocfs2.c
index f2ca5cb..2fa2c2f 100644
--- a/mount.ocfs2/mount.ocfs2.c
+++ b/mount.ocfs2/mount.ocfs2.c
@@ -312,6 +312,7 @@ int main(int argc, char **argv)
 	int clustered = 1;
 	int group_join = 0;
 	struct stat statbuf;
+	const char *spec;
 
 	initialize_ocfs_error_table();
 	initialize_o2dl_error_table();
@@ -414,8 +415,8 @@ int main(int argc, char **argv)
 		}
 		group_join = 1;
 	}
-
-	ret = mount(mo.dev, mo.dir, OCFS2_FS_NAME, mo.flags & ~MS_NOSYS,
+	spec = canonicalize(mo.dev);
+	ret = mount(spec, mo.dir, OCFS2_FS_NAME, mo.flags & ~MS_NOSYS,
 		    mo.xtra_opts);
 	if (ret) {
 		ret = errno;
diff --git a/mount.ocfs2/sundries.c b/mount.ocfs2/sundries.c
index bc59d64..2e1b95a 100644
--- a/mount.ocfs2/sundries.c
+++ b/mount.ocfs2/sundries.c
@@ -223,6 +223,37 @@ matching_opts (const char *options, const char *test_opts) {
      return 1;
 }
 
+/*
+ * 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_dm_name(const char *ptname)
+{
+	FILE	*f;
+	size_t	sz;
+	char	path[256], name[256], *res = NULL;
+	int	err;
+
+	snprintf(path, sizeof(path), "/sys/block/%s/dm/name", ptname);
+	f = fopen(path, "r");
+	if (!f)
+		return NULL;
+
+	/* read "<name>\n" from sysfs */
+	err = fgets(name, sizeof(name), f);
+	sz = strlen(name);
+	if (!err && sz > 1) {
+		name[sz - 1] = '\0';
+		snprintf(path, sizeof(path), "/dev/mapper/%s", name);
+		res = strdup(path);
+	}
+	fclose(f);
+	return res;
+}
+
 /* Make a canonical pathname from PATH.  Returns a freshly malloced string.
    It is up the *caller* to ensure that the PATH is sensible.  i.e.
    canonicalize ("/dev/fd0/.") returns "/dev/fd0" even though ``/dev/fd0/.''
@@ -231,6 +262,7 @@ matching_opts (const char *options, const char *test_opts) {
 char *
 canonicalize (const char *path) {
 	char canonical[PATH_MAX+2];
+	char *p;
 
 	if (path == NULL)
 		return NULL;
@@ -241,8 +273,13 @@ canonicalize (const char *path) {
 	    streq(path, "devpts"))
 		return xstrdup(path);
 #endif
-	if (myrealpath (path, canonical, PATH_MAX+1))
-		return xstrdup(canonical);
-
-	return xstrdup(path);
+	if (!myrealpath(path, canonical, PATH_MAX+1))
+		return xstrdup(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 xstrdup(canonical);
 }
-- 
1.7.1




More information about the Ocfs2-tools-devel mailing list