|
 |
564d46 |
[PATCH] xfsprogs: handle symlinks etc in fs_table_initialise_mounts()
|
|
 |
564d46 |
|
|
 |
564d46 |
Commit:
|
|
 |
564d46 |
|
|
 |
564d46 |
6a23747d xfs_quota: support relative path as `path' arguments
|
|
 |
564d46 |
|
|
 |
564d46 |
used realpath() on the supplied pathname to handle things like
|
|
 |
564d46 |
relative pathnames and pathnames ending in "/" which otherwise
|
|
 |
564d46 |
caused the getmntent scanning to fail.
|
|
 |
564d46 |
|
|
 |
564d46 |
However, this regressed cases where a path in mtab was a symlink;
|
|
 |
564d46 |
realpath() resolves this to the target, and so no match is found.
|
|
 |
564d46 |
|
|
 |
564d46 |
This causes i.e.:
|
|
 |
564d46 |
|
|
 |
564d46 |
# xfs_quota -x -c report /dev/mapper/testvg-testlv
|
|
 |
564d46 |
|
|
 |
564d46 |
to fail with:
|
|
 |
564d46 |
|
|
 |
564d46 |
xfs_quota: cannot setup path for mount /dev/mapper/testvg-testlv: No such device or address
|
|
 |
564d46 |
|
|
 |
564d46 |
because the scanning looks for /dev/dm-3, but the long symlink
|
|
 |
564d46 |
name is what exists in mtab, and no match is found.
|
|
 |
564d46 |
|
|
 |
564d46 |
Fix this, but keep the intended enhancements, by testing *both* the
|
|
 |
564d46 |
user-specified path (which might be relative, or contain a trailing
|
|
 |
564d46 |
slash on a mountpoint) and the realpath-resolved path (which turns
|
|
 |
564d46 |
a relative mountpoint into a full path, and removes trailing slashes),
|
|
 |
564d46 |
to determine whether the user-specified path is an xfs mountpoint or
|
|
 |
564d46 |
device.
|
|
 |
564d46 |
|
|
 |
564d46 |
While we're at it, add a few comments, and go back to the testing
|
|
 |
564d46 |
of "path" not "rpath"; whether or not path is passed to the function
|
|
 |
564d46 |
is what determines control flow. If path is specified, and realpath
|
|
 |
564d46 |
succeeds, we're guaranteed to have rpath as well, so there is no need
|
|
 |
564d46 |
to retest that. rpath is initialized to NULL, so an unconditional
|
|
 |
564d46 |
free(rpath) is safe as well.
|
|
 |
564d46 |
|
|
 |
564d46 |
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
|
|
 |
564d46 |
---
|
|
 |
564d46 |
|
|
 |
564d46 |
|
|
 |
564d46 |
diff --git a/libxcmd/paths.c b/libxcmd/paths.c
|
|
 |
564d46 |
index bd84cde..7b0e434 100644
|
|
 |
564d46 |
--- a/libxcmd/paths.c
|
|
 |
564d46 |
+++ b/libxcmd/paths.c
|
|
 |
564d46 |
@@ -266,6 +266,10 @@ out_nomem:
|
|
 |
564d46 |
return ENOMEM;
|
|
 |
564d46 |
}
|
|
 |
564d46 |
|
|
 |
564d46 |
+/*
|
|
 |
564d46 |
+ * If *path is NULL, initialize the fs table with all xfs mount points in mtab
|
|
 |
564d46 |
+ * If *path is specified, search for that path in mtab
|
|
 |
564d46 |
+ */
|
|
 |
564d46 |
static int
|
|
 |
564d46 |
fs_table_initialise_mounts(
|
|
 |
564d46 |
char *path)
|
|
 |
564d46 |
@@ -288,6 +292,7 @@ fs_table_initialise_mounts(
|
|
 |
564d46 |
if ((mtp = setmntent(mtab_file, "r")) == NULL)
|
|
 |
564d46 |
return ENOENT;
|
|
 |
564d46 |
|
|
 |
564d46 |
+ /* Use realpath to resolve symlinks, relative paths, etc */
|
|
 |
564d46 |
if (path)
|
|
 |
564d46 |
if ((rpath = realpath(path, NULL)) == NULL)
|
|
 |
564d46 |
return ENOENT;
|
|
 |
564d46 |
@@ -295,31 +300,37 @@ fs_table_initialise_mounts(
|
|
 |
564d46 |
while ((mnt = getmntent(mtp)) != NULL) {
|
|
 |
564d46 |
if (strcmp(mnt->mnt_type, "xfs") != 0)
|
|
 |
564d46 |
continue;
|
|
 |
564d46 |
- if (rpath &&
|
|
 |
564d46 |
- ((strcmp(rpath, mnt->mnt_dir) != 0) &&
|
|
 |
564d46 |
+ if (path &&
|
|
 |
564d46 |
+ ((strcmp(path, mnt->mnt_dir) != 0) &&
|
|
 |
564d46 |
+ (strcmp(path, mnt->mnt_fsname) != 0) &&
|
|
 |
564d46 |
+ (strcmp(rpath, mnt->mnt_dir) != 0) &&
|
|
 |
564d46 |
(strcmp(rpath, mnt->mnt_fsname) != 0)))
|
|
 |
564d46 |
continue;
|
|
 |
564d46 |
if (fs_extract_mount_options(mnt, &fslog, &fsrt))
|
|
 |
564d46 |
continue;
|
|
 |
564d46 |
(void) fs_table_insert(mnt->mnt_dir, 0, FS_MOUNT_POINT,
|
|
 |
564d46 |
mnt->mnt_fsname, fslog, fsrt);
|
|
 |
564d46 |
- if (rpath) {
|
|
 |
564d46 |
+ if (path) {
|
|
 |
564d46 |
found = 1;
|
|
 |
564d46 |
break;
|
|
 |
564d46 |
}
|
|
 |
564d46 |
}
|
|
 |
564d46 |
endmntent(mtp);
|
|
 |
564d46 |
- if (rpath) {
|
|
 |
564d46 |
- free(rpath);
|
|
 |
564d46 |
- if (!found)
|
|
 |
564d46 |
- error = ENXIO;
|
|
 |
564d46 |
- }
|
|
 |
564d46 |
+ free(rpath);
|
|
 |
564d46 |
+
|
|
 |
564d46 |
+ if (path && !found)
|
|
 |
564d46 |
+ error = ENXIO;
|
|
 |
564d46 |
+
|
|
 |
564d46 |
return error;
|
|
 |
564d46 |
}
|
|
 |
564d46 |
|
|
 |
564d46 |
#elif defined(HAVE_GETMNTINFO)
|
|
 |
564d46 |
#include <sys/mount.h>
|
|
 |
564d46 |
|
|
 |
564d46 |
+/*
|
|
 |
564d46 |
+ * If *path is NULL, initialize the fs table with all xfs mount points in mtab
|
|
 |
564d46 |
+ * If *path is specified, search for that path in mtab
|
|
 |
564d46 |
+ */
|
|
 |
564d46 |
static int
|
|
 |
564d46 |
fs_table_initialise_mounts(
|
|
 |
564d46 |
char *path)
|
|
 |
564d46 |
@@ -335,6 +346,7 @@ fs_table_initialise_mounts(
|
|
 |
564d46 |
return 0;
|
|
 |
564d46 |
}
|
|
 |
564d46 |
|
|
 |
564d46 |
+ /* Use realpath to resolve symlinks, relative paths, etc */
|
|
 |
564d46 |
if (path)
|
|
 |
564d46 |
if ((rpath = realpath(path, NULL)) == NULL)
|
|
 |
564d46 |
return ENOENT;
|
|
 |
564d46 |
@@ -342,24 +354,24 @@ fs_table_initialise_mounts(
|
|
 |
564d46 |
for (i = 0; i < count; i++) {
|
|
 |
564d46 |
if (strcmp(stats[i].f_fstypename, "xfs") != 0)
|
|
 |
564d46 |
continue;
|
|
 |
564d46 |
- if (rpath &&
|
|
 |
564d46 |
- ((strcmp(rpath, stats[i].f_mntonname) != 0) &&
|
|
 |
564d46 |
+ if (path &&
|
|
 |
564d46 |
+ ((strcmp(path, stats[i].f_mntonname) != 0) &&
|
|
 |
564d46 |
+ (strcmp(path, stats[i].f_mntfromname) != 0) &&
|
|
 |
564d46 |
+ (strcmp(rpath, stats[i].f_mntonname) != 0) &&
|
|
 |
564d46 |
(strcmp(rpath, stats[i].f_mntfromname) != 0)))
|
|
 |
564d46 |
continue;
|
|
 |
564d46 |
/* TODO: external log and realtime device? */
|
|
 |
564d46 |
(void) fs_table_insert(stats[i].f_mntonname, 0,
|
|
 |
564d46 |
FS_MOUNT_POINT, stats[i].f_mntfromname,
|
|
 |
564d46 |
NULL, NULL);
|
|
 |
564d46 |
- if (rpath) {
|
|
 |
564d46 |
+ if (path) {
|
|
 |
564d46 |
found = 1;
|
|
 |
564d46 |
break;
|
|
 |
564d46 |
}
|
|
 |
564d46 |
}
|
|
 |
564d46 |
- if (rpath) {
|
|
 |
564d46 |
- free(rpath);
|
|
 |
564d46 |
- if (!found)
|
|
 |
564d46 |
- error = ENXIO;
|
|
 |
564d46 |
- }
|
|
 |
564d46 |
+ free(rpath);
|
|
 |
564d46 |
+ if (path && !found)
|
|
 |
564d46 |
+ error = ENXIO;
|
|
 |
564d46 |
|
|
 |
564d46 |
return error;
|
|
 |
564d46 |
}
|
|
 |
564d46 |
|
|
 |
564d46 |
|
|
 |
564d46 |
|
|
 |
564d46 |
_______________________________________________
|
|
 |
564d46 |
xfs mailing list
|
|
 |
564d46 |
xfs@oss.sgi.com
|
|
 |
564d46 |
http://oss.sgi.com/mailman/listinfo/xfs
|
|
 |
564d46 |
|
|
 |
564d46 |
|