|
 |
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 |
|