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