cluster: STABLE3 - gfs2: Fix handling of mount points with spaces

Lon Hohberger lon at fedoraproject.org
Tue Apr 27 14:16:52 UTC 2010


Gitweb:        http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=f89866864bad9e2cc4f60e4f44dde888829fac19
Commit:        f89866864bad9e2cc4f60e4f44dde888829fac19
Parent:        38a984c3b415a13142d2f65aa30edcdc60d70497
Author:        Lon Hohberger <lhh at redhat.com>
AuthorDate:    Mon Apr 26 15:33:57 2010 -0400
Committer:     Lon Hohberger <lhh at redhat.com>
CommitterDate: Tue Apr 27 10:13:55 2010 -0400

gfs2: Fix handling of mount points with spaces

Mount points may contain spaces, tabs, newlines, and the
backslash character according to getmntent(3).  Unfortunately,
while scanning /proc/mounts, mount.gfs2 was not unescaping
the escape sequences, causing mount.gfs2 to not update mtab
if a mount point contained any of these characters.

Utilities relying on mtab (e.g. fuser) would consequently
be unable to list processes holding references on the mount
point.

Resolves: rhbz#586100

Signed-off-by: Lon Hohberger <lhh at redhat.com>
Signed-off-by: David Teigland <teigland at redhat.com>
Signed-off-by: Steven Whitehouse <swhiteho at redhat.com>
---
 gfs2/mount/util.c |   55 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 53 insertions(+), 2 deletions(-)

diff --git a/gfs2/mount/util.c b/gfs2/mount/util.c
index 16fc382..bc26daf 100644
--- a/gfs2/mount/util.c
+++ b/gfs2/mount/util.c
@@ -201,6 +201,48 @@ void parse_opts(struct mount_options *mo)
 	log_debug("parse_opts: locktable = \"%s\"", mo->locktable);
 }
 
+/* Remove escape sequences from mount path.  Per getmntent(3), there are
+   only four escape sequences we need to handle.  Consequently, this does
+   not need to be a general-purpose unescape function */
+
+static int mnt_unescape(char *dest, size_t len, const char *src)
+{
+	unsigned i = 0, j = 0;
+	size_t srclen;
+	int ret = -1;
+
+	srclen = strlen(src);
+	while (i < srclen) {
+		if (src[i] != '\\') {
+			dest[j] = src[i];
+			++i; ++j;
+			continue;
+		}
+
+		++i;
+		if ((srclen - 3) < i)
+			return -1;
+
+		if (!strncmp(&src[i], "040", 3)) {
+			dest[j] = ' ';
+		} else if (!strncmp(&src[i], "011", 3)) {
+			dest[j] = '\t';
+		} else if (!strncmp(&src[i], "012", 3)) {
+			dest[j] = '\n';
+		} else if (!strncmp(&src[i], "134", 3)) {
+			dest[j] = '\\';
+		} else {
+			return -1;
+		}
+
+		i+=3;
+		j++;
+	}
+
+	return 0;
+}
+
+
 /* - when unmounting, we don't know the dev and need this function to set it;
    we also want to select the _last_ line with a matching dir since it will
    be the top-most fs that the umount(2) will unmount
@@ -212,6 +254,7 @@ void read_proc_mounts(struct mount_options *mo)
 	FILE *file;
 	char line[PATH_MAX];
 	char path[PATH_MAX];
+	char unescaped_path[PATH_MAX];
 	char type[PATH_MAX];
 	char opts[PATH_MAX];
 	char device[PATH_MAX];
@@ -234,8 +277,16 @@ void read_proc_mounts(struct mount_options *mo)
 	while (fgets(line, PATH_MAX, file)) {
 		if (sscanf(line, "%s %s %s %s", device, path, type, opts) != 4)
 			continue;
-		if (strcmp(path, mo->dir))
-			continue;
+		if (strcmp(path, mo->dir)) {
+			if (!strchr(path, '\\'))
+				continue;
+			/* /proc/mounts entry may have escaped spaces */
+			if (mnt_unescape(unescaped_path, sizeof(unescaped_path),
+					 path) < 0)
+				continue;
+			if (strcmp(unescaped_path, mo->dir))
+				continue;
+		}
 		if (mo->dev[0]) {
 			if (stat(device, &st_mounts_dev))
 				continue;


More information about the cluster-commits mailing list