From mboxrd@z Thu Jan 1 00:00:00 1970 From: Steven Whitehouse Date: Tue, 27 Apr 2010 09:53:35 +0100 Subject: [Cluster-devel] [PATCH] gfs2: Fix handling of mount points with spaces In-Reply-To: <1272312565-17085-1-git-send-email-lhh@redhat.com> References: <1272312565-17085-1-git-send-email-lhh@redhat.com> Message-ID: <1272358415.2673.24.camel@localhost> List-Id: To: cluster-devel.redhat.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Hi, Looks good to me. Thanks, Steve. On Mon, 2010-04-26 at 16:09 -0400, Lon Hohberger wrote: > 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. > > 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 > --- > 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;