]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
virfile: Rework virFileIsSharedFixFUSE
authorMichal Privoznik <mprivozn@redhat.com>
Tue, 9 Oct 2018 11:08:07 +0000 (13:08 +0200)
committerMichal Privoznik <mprivozn@redhat.com>
Wed, 10 Oct 2018 15:14:45 +0000 (17:14 +0200)
There are couple of things wrong with the current implementation.
The first one is that in the first loop the code tries to build a
list of fuse.glusterfs mount points. Well, since the strings are
allocated in a temporary buffer and are not duplicated this
results in wrong decision made later in the code.

The second problem is that the code does not take into account
subtree mounts. For instance, if there's a fuse.gluster mounted
at /some/path and another FS mounted at /some/path/subdir the
code would not recognize this subdir mount.

Reported-by: Han Han <hhan@redhat.com>
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
src/util/virfile.c
tests/virfiledata/mounts3.txt
tests/virfiletest.c

index a49bc30eb2f491476553cc88ea332d3009af22ab..e09992e41a24f09a44561b797c889b3c30ce4cf3 100644 (file)
@@ -3468,18 +3468,14 @@ static int
 virFileIsSharedFixFUSE(const char *path,
                        long long *f_type)
 {
-    char *dirpath = NULL;
-    const char **mounts = NULL;
-    size_t nmounts = 0;
-    char *p;
     FILE *f = NULL;
     struct mntent mb;
     char mntbuf[1024];
+    char *mntDir = NULL;
+    char *mntType = NULL;
+    size_t maxMatching = 0;
     int ret = -1;
 
-    if (VIR_STRDUP(dirpath, path) < 0)
-        return -1;
-
     if (!(f = setmntent(PROC_MOUNTS, "r"))) {
         virReportSystemError(errno,
                              _("Unable to open %s"),
@@ -3488,43 +3484,36 @@ virFileIsSharedFixFUSE(const char *path,
     }
 
     while (getmntent_r(f, &mb, mntbuf, sizeof(mntbuf))) {
-        if (STRNEQ("fuse.glusterfs", mb.mnt_type))
-            continue;
+        const char *p;
+        size_t len = strlen(mb.mnt_dir);
 
-        if (VIR_APPEND_ELEMENT_COPY(mounts, nmounts, mb.mnt_dir) < 0)
-            goto cleanup;
-    }
+        if (!(p = STRSKIP(path, mb.mnt_dir)))
+            continue;
 
-    /* Add NULL sentinel so that this is a virStringList */
-    if (VIR_REALLOC_N(mounts, nmounts + 1) < 0)
-        goto cleanup;
-    mounts[nmounts] = NULL;
+        if (*(p - 1) != '/' && *p != '/' && *p != '\0')
+            continue;
 
-    do {
-        if ((p = strrchr(dirpath, '/')) == NULL) {
-            virReportSystemError(EINVAL,
-                                 _("Invalid relative path '%s'"), path);
-            goto cleanup;
+        if (len > maxMatching) {
+            maxMatching = len;
+            VIR_FREE(mntType);
+            VIR_FREE(mntDir);
+            if (VIR_STRDUP(mntDir, mb.mnt_dir) < 0 ||
+                VIR_STRDUP(mntType, mb.mnt_type) < 0)
+                goto cleanup;
         }
+    }
 
-        if (p == dirpath)
-            *(p+1) = '\0';
-        else
-            *p = '\0';
-
-        if (virStringListHasString(mounts, dirpath)) {
-            VIR_DEBUG("Found gluster FUSE mountpoint=%s for path=%s. "
-                      "Fixing shared FS type", dirpath, path);
-            *f_type = GFS2_MAGIC;
-            break;
-        }
-    } while (p != dirpath);
+    if (STREQ_NULLABLE(mntType, "fuse.glusterfs")) {
+        VIR_DEBUG("Found gluster FUSE mountpoint=%s for path=%s. "
+                  "Fixing shared FS type", mntDir, path);
+        *f_type = GFS2_MAGIC;
+    }
 
     ret = 0;
  cleanup:
+    VIR_FREE(mntType);
+    VIR_FREE(mntDir);
     endmntent(f);
-    VIR_FREE(mounts);
-    VIR_FREE(dirpath);
     return ret;
 }
 
index 226f67dc00a854d6e5f474e877b3e71e8142f1c9..134c6e8f8199972efec2bded8dbd4161f9612379 100644 (file)
@@ -31,3 +31,5 @@ hugetlbfs /hugepages2M hugetlbfs rw,relatime,mode=1777,pagesize=2M 0 0
 none /run/user/1000 tmpfs rw,relatime,mode=700,uid=1000 0 0
 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
 dev /nfs/blah devtmpfs rw,nosuid,relatime,size=10240k,nr_inodes=4093060,mode=755 0 0
+host:/gv0 /gluster fuse.glusterfs rw 0 0
+root@host:/tmp/mkdir /gluster/sshfs fuse.sshfs rw 0 0
index 42d918aecc862059115c5661ac4629e514f7a600..d5102b1cc47dbe8b2f35a9fc77abdf331101b527 100644 (file)
@@ -454,6 +454,8 @@ mymain(void)
     DO_TEST_FILE_IS_SHARED_FS_TYPE("mounts2.txt", "/run/user/501/gvfs/some/file", false);
     DO_TEST_FILE_IS_SHARED_FS_TYPE("mounts3.txt", "/nfs/file", true);
     DO_TEST_FILE_IS_SHARED_FS_TYPE("mounts3.txt", "/nfs/blah", false);
+    DO_TEST_FILE_IS_SHARED_FS_TYPE("mounts3.txt", "/gluster/file", true);
+    DO_TEST_FILE_IS_SHARED_FS_TYPE("mounts3.txt", "/gluster/sshfs/file", false);
 
     return ret != 0 ? EXIT_FAILURE : EXIT_SUCCESS;
 }