Blame SOURCES/xfsprogs-3.2.1-libxcmd-make-all-comparisons-using-realpathd-paths.patch

502773
commit ed350fc6c49155ec398866ebef1d59be02636bce
502773
Author: Eric Sandeen <sandeen@sandeen.net>
502773
Date:   Wed Jul 16 13:53:47 2014 +1000
502773
502773
    libxcmd: make all comparisons using realpath'd paths
502773
    
502773
    Both mountpoints and devices can be symlinks, so given a path
502773
    to look for, and mountpoints/devices from the system, use
502773
    realpath() on *everything* before making the comparison to see
502773
    if our path is a match.
502773
    
502773
    So, with symlinks for mount points as well as for devices:
502773
    
502773
    # ls -l /dev/mapper/testvg-lvol0
502773
    lrwxrwxrwx. 1 root root 7 Jul 11 19:24 /dev/mapper/testvg-lvol0 -> ../dm-3
502773
    # ls -l /mnt/scratch2
502773
    lrwxrwxrwx. 1 root root 12 Jul 11 19:57 /mnt/scratch2 -> /mnt/scratch
502773
    
502773
    this should all work, and does now:
502773
    
502773
    # xfs_quota -xc "report -h" /mnt/scratch2
502773
    User quota on /mnt/scratch (/dev/mapper/testvg-lvol0)
502773
                            Blocks
502773
    User ID      Used   Soft   Hard Warn/Grace
502773
    ---------- ---------------------------------
502773
    root            0      0      0  00 [------]
502773
    
502773
    # xfs_quota -xc "report -h" /mnt/scratch
502773
    User quota on /mnt/scratch (/dev/mapper/testvg-lvol0)
502773
                            Blocks
502773
    User ID      Used   Soft   Hard Warn/Grace
502773
    ---------- ---------------------------------
502773
    root            0      0      0  00 [------]
502773
    
502773
    # xfs_quota -xc "report -h" /dev/dm-3
502773
    User quota on /mnt/scratch (/dev/mapper/testvg-lvol0)
502773
                            Blocks
502773
    User ID      Used   Soft   Hard Warn/Grace
502773
    ---------- ---------------------------------
502773
    root            0      0      0  00 [------]
502773
    
502773
    # xfs_quota -xc "report -h" /dev/mapper/testvg-lvol0
502773
    User quota on /mnt/scratch (/dev/mapper/testvg-lvol0)
502773
                            Blocks
502773
    User ID      Used   Soft   Hard Warn/Grace
502773
    ---------- ---------------------------------
502773
    root            0      0      0  00 [------]
502773
    
502773
    The commit:
502773
    
502773
    050a7f1 xfsprogs: handle symlinks etc in fs_table_initialise_mounts()
502773
    
502773
    tried to fix this earlier, but only worked one way;
502773
    it compared the argument path in both given and realpath
502773
    form to the paths in getmntent, but did not compare to
502773
    the realpaths of the getmntent devices.
502773
    
502773
    If we reduce everything, everywhere, to a realpath(), we've
502773
    got our best shot at finding the match.
502773
    
502773
    Signed-off-by: Eric Sandeen <sandeen@redhat.com>
502773
    Reviewed-by: Christoph Hellwig <hch@lst.de>
502773
    Signed-off-by: Dave Chinner <david@fromorbit.com>
502773
502773
diff --git a/libxcmd/paths.c b/libxcmd/paths.c
502773
index 7b0e434..443adbb 100644
502773
--- a/libxcmd/paths.c
502773
+++ b/libxcmd/paths.c
502773
@@ -269,6 +269,9 @@ out_nomem:
502773
 /*
502773
  * If *path is NULL, initialize the fs table with all xfs mount points in mtab
502773
  * If *path is specified, search for that path in mtab
502773
+ *
502773
+ * Everything - path, devices, and mountpoints - are boiled down to realpath()
502773
+ * for comparison, but fs_table is populated with what comes from getmntent.
502773
  */
502773
 static int
502773
 fs_table_initialise_mounts(
502773
@@ -278,7 +281,7 @@ fs_table_initialise_mounts(
502773
 	FILE		*mtp;
502773
 	char		*fslog, *fsrt;
502773
 	int		error, found;
502773
-	char		*rpath = NULL;
502773
+	char		rpath[PATH_MAX], rmnt_fsname[PATH_MAX], rmnt_dir[PATH_MAX];
502773
 
502773
 	error = found = 0;
502773
 	fslog = fsrt = NULL;
502773
@@ -294,17 +297,20 @@ fs_table_initialise_mounts(
502773
 
502773
 	/* Use realpath to resolve symlinks, relative paths, etc */
502773
 	if (path)
502773
-		if ((rpath = realpath(path, NULL)) == NULL)
502773
-			return ENOENT;
502773
+		if (!realpath(path, rpath))
502773
+			return errno;
502773
 
502773
 	while ((mnt = getmntent(mtp)) != NULL) {
502773
 		if (strcmp(mnt->mnt_type, "xfs") != 0)
502773
 			continue;
502773
+		if (!realpath(mnt->mnt_dir, rmnt_dir))
502773
+			continue;
502773
+		if (!realpath(mnt->mnt_fsname, rmnt_fsname))
502773
+			continue;
502773
+
502773
 		if (path &&
502773
-		    ((strcmp(path, mnt->mnt_dir) != 0) &&
502773
-		     (strcmp(path, mnt->mnt_fsname) != 0) &&
502773
-		     (strcmp(rpath, mnt->mnt_dir) != 0) &&
502773
-		     (strcmp(rpath, mnt->mnt_fsname) != 0)))
502773
+		    ((strcmp(rpath, rmnt_dir) != 0) &&
502773
+		     (strcmp(rpath, rmnt_fsname) != 0)))
502773
 			continue;
502773
 		if (fs_extract_mount_options(mnt, &fslog, &fsrt))
502773
 			continue;
502773
@@ -316,7 +322,6 @@ fs_table_initialise_mounts(
502773
 		}
502773
 	}
502773
 	endmntent(mtp);
502773
-	free(rpath);
502773
 
502773
 	if (path && !found)
502773
 		error = ENXIO;
502773
@@ -330,6 +335,9 @@ fs_table_initialise_mounts(
502773
 /*
502773
  * If *path is NULL, initialize the fs table with all xfs mount points in mtab
502773
  * If *path is specified, search for that path in mtab
502773
+ *
502773
+ * Everything - path, devices, and mountpoints - are boiled down to realpath()
502773
+ * for comparison, but fs_table is populated with what comes from getmntinfo.
502773
  */
502773
 static int
502773
 fs_table_initialise_mounts(
502773
@@ -337,7 +345,7 @@ fs_table_initialise_mounts(
502773
 {
502773
 	struct statfs	*stats;
502773
 	int		i, count, error, found;
502773
-	char		*rpath = NULL;
502773
+	char		rpath[PATH_MAX], rmntfromname[PATH_MAX], rmntonname[PATH_MAX];
502773
 
502773
 	error = found = 0;
502773
 	if ((count = getmntinfo(&stats, 0)) < 0) {
502773
@@ -348,17 +356,20 @@ fs_table_initialise_mounts(
502773
 
502773
 	/* Use realpath to resolve symlinks, relative paths, etc */
502773
 	if (path)
502773
-		if ((rpath = realpath(path, NULL)) == NULL)
502773
-			return ENOENT;
502773
+		if (!realpath(path, rpath))
502773
+			return errno;
502773
 
502773
 	for (i = 0; i < count; i++) {
502773
 		if (strcmp(stats[i].f_fstypename, "xfs") != 0)
502773
 			continue;
502773
+		if (!realpath(stats[i].f_mntfromname, rmntfromname))
502773
+			continue;
502773
+		if (!realpath(stats[i].f_mntonname, rmnttomname)))
502773
+			continue;
502773
+
502773
 		if (path &&
502773
-		    ((strcmp(path, stats[i].f_mntonname) != 0) &&
502773
-		     (strcmp(path, stats[i].f_mntfromname) != 0) &&
502773
-		     (strcmp(rpath, stats[i].f_mntonname) != 0) &&
502773
-		     (strcmp(rpath, stats[i].f_mntfromname) != 0)))
502773
+		    ((strcmp(rpath, rmntonname) != 0) &&
502773
+		     (strcmp(rpath, rmntfromname) != 0)))
502773
 			continue;
502773
 		/* TODO: external log and realtime device? */
502773
 		(void) fs_table_insert(stats[i].f_mntonname, 0,
502773
@@ -369,7 +380,6 @@ fs_table_initialise_mounts(
502773
 			break;
502773
 		}
502773
 	}
502773
-	free(rpath);
502773
 	if (path && !found)
502773
 		error = ENXIO;
502773