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