99cbc7
From 945cc03b42ec947876cda10dff1bf76a446abbf1 Mon Sep 17 00:00:00 2001
99cbc7
Message-Id: <945cc03b42ec947876cda10dff1bf76a446abbf1@dist-git>
99cbc7
From: Michal Privoznik <mprivozn@redhat.com>
99cbc7
Date: Wed, 3 Oct 2018 17:04:13 +0200
99cbc7
Subject: [PATCH] virFileIsSharedFSType: Check for fuse.glusterfs too
99cbc7
99cbc7
RHEL-7.7: https://bugzilla.redhat.com/show_bug.cgi?id=1632711
99cbc7
RHEL-8.0: https://bugzilla.redhat.com/show_bug.cgi?id=1634782
99cbc7
RHEL-7.6.z: https://bugzilla.redhat.com/show_bug.cgi?id=1635705
99cbc7
99cbc7
GlusterFS is typically safe when it comes to migration. It's a
99cbc7
network FS after all. However, it can be mounted via FUSE driver
99cbc7
they provide. If that is the case we fail to identify it and
99cbc7
think migration is not safe and require VIR_MIGRATE_UNSAFE flag.
99cbc7
99cbc7
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
99cbc7
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
99cbc7
(cherry picked from commit 478da65fb46c866973886848ae17f1e16199a77d)
99cbc7
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
99cbc7
---
99cbc7
 src/util/virfile.c | 77 ++++++++++++++++++++++++++++++++++++++++++++--
99cbc7
 1 file changed, 75 insertions(+), 2 deletions(-)
99cbc7
99cbc7
diff --git a/src/util/virfile.c b/src/util/virfile.c
99cbc7
index 378d03ecf0..c87e26bf5b 100644
99cbc7
--- a/src/util/virfile.c
99cbc7
+++ b/src/util/virfile.c
99cbc7
@@ -3534,6 +3534,76 @@ int virFilePrintf(FILE *fp, const char *msg, ...)
99cbc7
 # ifndef HUGETLBFS_MAGIC
99cbc7
 #  define HUGETLBFS_MAGIC 0x958458f6
99cbc7
 # endif
99cbc7
+# ifndef FUSE_SUPER_MAGIC
99cbc7
+#  define FUSE_SUPER_MAGIC 0x65735546
99cbc7
+# endif
99cbc7
+
99cbc7
+# define PROC_MOUNTS "/proc/mounts"
99cbc7
+
99cbc7
+static int
99cbc7
+virFileIsSharedFixFUSE(const char *path,
99cbc7
+                       long *f_type)
99cbc7
+{
99cbc7
+    char *dirpath = NULL;
99cbc7
+    const char **mounts = NULL;
99cbc7
+    size_t nmounts = 0;
99cbc7
+    char *p;
99cbc7
+    FILE *f = NULL;
99cbc7
+    struct mntent mb;
99cbc7
+    char mntbuf[1024];
99cbc7
+    int ret = -1;
99cbc7
+
99cbc7
+    if (VIR_STRDUP(dirpath, path) < 0)
99cbc7
+        return -1;
99cbc7
+
99cbc7
+    if (!(f = setmntent(PROC_MOUNTS, "r"))) {
99cbc7
+        virReportSystemError(errno,
99cbc7
+                             _("Unable to open %s"),
99cbc7
+                             PROC_MOUNTS);
99cbc7
+        goto cleanup;
99cbc7
+    }
99cbc7
+
99cbc7
+    while (getmntent_r(f, &mb, mntbuf, sizeof(mntbuf))) {
99cbc7
+        if (STRNEQ("fuse.glusterfs", mb.mnt_type))
99cbc7
+            continue;
99cbc7
+
99cbc7
+        if (VIR_APPEND_ELEMENT_COPY(mounts, nmounts, mb.mnt_dir) < 0)
99cbc7
+            goto cleanup;
99cbc7
+    }
99cbc7
+
99cbc7
+    /* Add NULL sentinel so that this is a virStringList */
99cbc7
+    if (VIR_REALLOC_N(mounts, nmounts + 1) < 0)
99cbc7
+        goto cleanup;
99cbc7
+    mounts[nmounts] = NULL;
99cbc7
+
99cbc7
+    do {
99cbc7
+        if ((p = strrchr(dirpath, '/')) == NULL) {
99cbc7
+            virReportSystemError(EINVAL,
99cbc7
+                                 _("Invalid relative path '%s'"), path);
99cbc7
+            goto cleanup;
99cbc7
+        }
99cbc7
+
99cbc7
+        if (p == dirpath)
99cbc7
+            *(p+1) = '\0';
99cbc7
+        else
99cbc7
+            *p = '\0';
99cbc7
+
99cbc7
+        if (virStringListHasString(mounts, dirpath)) {
99cbc7
+            VIR_DEBUG("Found gluster FUSE mountpoint=%s for path=%s. "
99cbc7
+                      "Fixing shared FS type", dirpath, path);
99cbc7
+            *f_type = GFS2_MAGIC;
99cbc7
+            break;
99cbc7
+        }
99cbc7
+    } while (p != dirpath);
99cbc7
+
99cbc7
+    ret = 0;
99cbc7
+ cleanup:
99cbc7
+    endmntent(f);
99cbc7
+    VIR_FREE(mounts);
99cbc7
+    VIR_FREE(dirpath);
99cbc7
+    return ret;
99cbc7
+}
99cbc7
+
99cbc7
 
99cbc7
 int
99cbc7
 virFileIsSharedFSType(const char *path,
99cbc7
@@ -3581,6 +3651,11 @@ virFileIsSharedFSType(const char *path,
99cbc7
         return -1;
99cbc7
     }
99cbc7
 
99cbc7
+    if (sb.f_type == FUSE_SUPER_MAGIC) {
99cbc7
+        VIR_DEBUG("Found FUSE mount for path=%s. Trying to fix it", path);
99cbc7
+        virFileIsSharedFixFUSE(path, (long *) &sb.f_type);
99cbc7
+    }
99cbc7
+
99cbc7
     VIR_DEBUG("Check if path %s with FS magic %lld is shared",
99cbc7
               path, (long long int)sb.f_type);
99cbc7
 
99cbc7
@@ -3673,8 +3748,6 @@ virFileGetDefaultHugepageSize(unsigned long long *size)
99cbc7
     return ret;
99cbc7
 }
99cbc7
 
99cbc7
-# define PROC_MOUNTS "/proc/mounts"
99cbc7
-
99cbc7
 int
99cbc7
 virFileFindHugeTLBFS(virHugeTLBFSPtr *ret_fs,
99cbc7
                      size_t *ret_nfs)
99cbc7
-- 
99cbc7
2.21.0
99cbc7