|
|
a5a3f0 |
From 872bff1f3e49219389ed57bc2fbff8614b5f9be9 Mon Sep 17 00:00:00 2001
|
|
|
a5a3f0 |
Message-Id: <872bff1f3e49219389ed57bc2fbff8614b5f9be9@dist-git>
|
|
|
a5a3f0 |
From: Michal Privoznik <mprivozn@redhat.com>
|
|
|
a5a3f0 |
Date: Wed, 10 Oct 2018 17:25:56 +0200
|
|
|
a5a3f0 |
Subject: [PATCH] virfile: Rework virFileIsSharedFixFUSE
|
|
|
a5a3f0 |
|
|
|
a5a3f0 |
RHEL-7.7: https://bugzilla.redhat.com/show_bug.cgi?id=1632711
|
|
|
a5a3f0 |
RHEL-8.0: https://bugzilla.redhat.com/show_bug.cgi?id=1634782
|
|
|
a5a3f0 |
RHEL-7.6.z: https://bugzilla.redhat.com/show_bug.cgi?id=1635705
|
|
|
a5a3f0 |
|
|
|
a5a3f0 |
There are couple of things wrong with the current implementation.
|
|
|
a5a3f0 |
The first one is that in the first loop the code tries to build a
|
|
|
a5a3f0 |
list of fuse.glusterfs mount points. Well, since the strings are
|
|
|
a5a3f0 |
allocated in a temporary buffer and are not duplicated this
|
|
|
a5a3f0 |
results in wrong decision made later in the code.
|
|
|
a5a3f0 |
|
|
|
a5a3f0 |
The second problem is that the code does not take into account
|
|
|
a5a3f0 |
subtree mounts. For instance, if there's a fuse.gluster mounted
|
|
|
a5a3f0 |
at /some/path and another FS mounted at /some/path/subdir the
|
|
|
a5a3f0 |
code would not recognize this subdir mount.
|
|
|
a5a3f0 |
|
|
|
a5a3f0 |
Reported-by: Han Han <hhan@redhat.com>
|
|
|
a5a3f0 |
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
|
|
|
a5a3f0 |
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
|
|
|
a5a3f0 |
(cherry picked from commit 1dbf6222dd5e1fedcbe335fc0852ef66e7a92901)
|
|
|
a5a3f0 |
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
|
|
|
a5a3f0 |
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
|
|
|
a5a3f0 |
---
|
|
|
a5a3f0 |
src/util/virfile.c | 61 ++++++++++++++---------------------
|
|
|
a5a3f0 |
tests/virfiledata/mounts3.txt | 2 ++
|
|
|
a5a3f0 |
tests/virfiletest.c | 2 ++
|
|
|
a5a3f0 |
3 files changed, 29 insertions(+), 36 deletions(-)
|
|
|
a5a3f0 |
|
|
|
a5a3f0 |
diff --git a/src/util/virfile.c b/src/util/virfile.c
|
|
|
a5a3f0 |
index 05ecf7bf21..e1dee7633a 100644
|
|
|
a5a3f0 |
--- a/src/util/virfile.c
|
|
|
a5a3f0 |
+++ b/src/util/virfile.c
|
|
|
a5a3f0 |
@@ -3544,18 +3544,14 @@ static int
|
|
|
a5a3f0 |
virFileIsSharedFixFUSE(const char *path,
|
|
|
a5a3f0 |
long long *f_type)
|
|
|
a5a3f0 |
{
|
|
|
a5a3f0 |
- char *dirpath = NULL;
|
|
|
a5a3f0 |
- const char **mounts = NULL;
|
|
|
a5a3f0 |
- size_t nmounts = 0;
|
|
|
a5a3f0 |
- char *p;
|
|
|
a5a3f0 |
FILE *f = NULL;
|
|
|
a5a3f0 |
struct mntent mb;
|
|
|
a5a3f0 |
char mntbuf[1024];
|
|
|
a5a3f0 |
+ char *mntDir = NULL;
|
|
|
a5a3f0 |
+ char *mntType = NULL;
|
|
|
a5a3f0 |
+ size_t maxMatching = 0;
|
|
|
a5a3f0 |
int ret = -1;
|
|
|
a5a3f0 |
|
|
|
a5a3f0 |
- if (VIR_STRDUP(dirpath, path) < 0)
|
|
|
a5a3f0 |
- return -1;
|
|
|
a5a3f0 |
-
|
|
|
a5a3f0 |
if (!(f = setmntent(PROC_MOUNTS, "r"))) {
|
|
|
a5a3f0 |
virReportSystemError(errno,
|
|
|
a5a3f0 |
_("Unable to open %s"),
|
|
|
a5a3f0 |
@@ -3564,43 +3560,36 @@ virFileIsSharedFixFUSE(const char *path,
|
|
|
a5a3f0 |
}
|
|
|
a5a3f0 |
|
|
|
a5a3f0 |
while (getmntent_r(f, &mb, mntbuf, sizeof(mntbuf))) {
|
|
|
a5a3f0 |
- if (STRNEQ("fuse.glusterfs", mb.mnt_type))
|
|
|
a5a3f0 |
+ const char *p;
|
|
|
a5a3f0 |
+ size_t len = strlen(mb.mnt_dir);
|
|
|
a5a3f0 |
+
|
|
|
a5a3f0 |
+ if (!(p = STRSKIP(path, mb.mnt_dir)))
|
|
|
a5a3f0 |
continue;
|
|
|
a5a3f0 |
|
|
|
a5a3f0 |
- if (VIR_APPEND_ELEMENT_COPY(mounts, nmounts, mb.mnt_dir) < 0)
|
|
|
a5a3f0 |
- goto cleanup;
|
|
|
a5a3f0 |
+ if (*(p - 1) != '/' && *p != '/' && *p != '\0')
|
|
|
a5a3f0 |
+ continue;
|
|
|
a5a3f0 |
+
|
|
|
a5a3f0 |
+ if (len > maxMatching) {
|
|
|
a5a3f0 |
+ maxMatching = len;
|
|
|
a5a3f0 |
+ VIR_FREE(mntType);
|
|
|
a5a3f0 |
+ VIR_FREE(mntDir);
|
|
|
a5a3f0 |
+ if (VIR_STRDUP(mntDir, mb.mnt_dir) < 0 ||
|
|
|
a5a3f0 |
+ VIR_STRDUP(mntType, mb.mnt_type) < 0)
|
|
|
a5a3f0 |
+ goto cleanup;
|
|
|
a5a3f0 |
+ }
|
|
|
a5a3f0 |
}
|
|
|
a5a3f0 |
|
|
|
a5a3f0 |
- /* Add NULL sentinel so that this is a virStringList */
|
|
|
a5a3f0 |
- if (VIR_REALLOC_N(mounts, nmounts + 1) < 0)
|
|
|
a5a3f0 |
- goto cleanup;
|
|
|
a5a3f0 |
- mounts[nmounts] = NULL;
|
|
|
a5a3f0 |
-
|
|
|
a5a3f0 |
- do {
|
|
|
a5a3f0 |
- if ((p = strrchr(dirpath, '/')) == NULL) {
|
|
|
a5a3f0 |
- virReportSystemError(EINVAL,
|
|
|
a5a3f0 |
- _("Invalid relative path '%s'"), path);
|
|
|
a5a3f0 |
- goto cleanup;
|
|
|
a5a3f0 |
- }
|
|
|
a5a3f0 |
-
|
|
|
a5a3f0 |
- if (p == dirpath)
|
|
|
a5a3f0 |
- *(p+1) = '\0';
|
|
|
a5a3f0 |
- else
|
|
|
a5a3f0 |
- *p = '\0';
|
|
|
a5a3f0 |
-
|
|
|
a5a3f0 |
- if (virStringListHasString(mounts, dirpath)) {
|
|
|
a5a3f0 |
- VIR_DEBUG("Found gluster FUSE mountpoint=%s for path=%s. "
|
|
|
a5a3f0 |
- "Fixing shared FS type", dirpath, path);
|
|
|
a5a3f0 |
- *f_type = GFS2_MAGIC;
|
|
|
a5a3f0 |
- break;
|
|
|
a5a3f0 |
- }
|
|
|
a5a3f0 |
- } while (p != dirpath);
|
|
|
a5a3f0 |
+ if (STREQ_NULLABLE(mntType, "fuse.glusterfs")) {
|
|
|
a5a3f0 |
+ VIR_DEBUG("Found gluster FUSE mountpoint=%s for path=%s. "
|
|
|
a5a3f0 |
+ "Fixing shared FS type", mntDir, path);
|
|
|
a5a3f0 |
+ *f_type = GFS2_MAGIC;
|
|
|
a5a3f0 |
+ }
|
|
|
a5a3f0 |
|
|
|
a5a3f0 |
ret = 0;
|
|
|
a5a3f0 |
cleanup:
|
|
|
a5a3f0 |
+ VIR_FREE(mntType);
|
|
|
a5a3f0 |
+ VIR_FREE(mntDir);
|
|
|
a5a3f0 |
endmntent(f);
|
|
|
a5a3f0 |
- VIR_FREE(mounts);
|
|
|
a5a3f0 |
- VIR_FREE(dirpath);
|
|
|
a5a3f0 |
return ret;
|
|
|
a5a3f0 |
}
|
|
|
a5a3f0 |
|
|
|
a5a3f0 |
diff --git a/tests/virfiledata/mounts3.txt b/tests/virfiledata/mounts3.txt
|
|
|
a5a3f0 |
index 226f67dc00..134c6e8f81 100644
|
|
|
a5a3f0 |
--- a/tests/virfiledata/mounts3.txt
|
|
|
a5a3f0 |
+++ b/tests/virfiledata/mounts3.txt
|
|
|
a5a3f0 |
@@ -31,3 +31,5 @@ hugetlbfs /hugepages2M hugetlbfs rw,relatime,mode=1777,pagesize=2M 0 0
|
|
|
a5a3f0 |
none /run/user/1000 tmpfs rw,relatime,mode=700,uid=1000 0 0
|
|
|
a5a3f0 |
host:/nfs /nfs nfs4 rw,relatime,vers=4.1,rsize=1048576,wsize=1048576,namlen=255,hard,proto=tcp6,timeo=600,retrans=2,sec=sys,clientaddr=::,local_lock=none,addr=:: 0 0
|
|
|
a5a3f0 |
dev /nfs/blah devtmpfs rw,nosuid,relatime,size=10240k,nr_inodes=4093060,mode=755 0 0
|
|
|
a5a3f0 |
+host:/gv0 /gluster fuse.glusterfs rw 0 0
|
|
|
a5a3f0 |
+root@host:/tmp/mkdir /gluster/sshfs fuse.sshfs rw 0 0
|
|
|
a5a3f0 |
diff --git a/tests/virfiletest.c b/tests/virfiletest.c
|
|
|
a5a3f0 |
index 80ea34bfa4..be4dbf8910 100644
|
|
|
a5a3f0 |
--- a/tests/virfiletest.c
|
|
|
a5a3f0 |
+++ b/tests/virfiletest.c
|
|
|
a5a3f0 |
@@ -455,6 +455,8 @@ mymain(void)
|
|
|
a5a3f0 |
DO_TEST_FILE_IS_SHARED_FS_TYPE("mounts2.txt", "/run/user/501/gvfs/some/file", false);
|
|
|
a5a3f0 |
DO_TEST_FILE_IS_SHARED_FS_TYPE("mounts3.txt", "/nfs/file", true);
|
|
|
a5a3f0 |
DO_TEST_FILE_IS_SHARED_FS_TYPE("mounts3.txt", "/nfs/blah", false);
|
|
|
a5a3f0 |
+ DO_TEST_FILE_IS_SHARED_FS_TYPE("mounts3.txt", "/gluster/file", true);
|
|
|
a5a3f0 |
+ DO_TEST_FILE_IS_SHARED_FS_TYPE("mounts3.txt", "/gluster/sshfs/file", false);
|
|
|
a5a3f0 |
|
|
|
a5a3f0 |
return ret != 0 ? EXIT_FAILURE : EXIT_SUCCESS;
|
|
|
a5a3f0 |
}
|
|
|
a5a3f0 |
--
|
|
|
a5a3f0 |
2.19.1
|
|
|
a5a3f0 |
|