[libvirt] [PATCH 2/3] Create virFileIsOnNetworkShare utility function

Laine Stump laine at laine.org
Fri Jun 25 11:42:14 UTC 2010


This code was previously used inline during qemudDomainSaveFlag. This
patch moves it into a utility function in preparation for it to be
used elsewhere.
---
 src/libvirt_private.syms |    1 +
 src/qemu/qemu_driver.c   |   83 +++++++++++++---------------------------------
 src/util/util.c          |   67 +++++++++++++++++++++++++++++++++++++
 src/util/util.h          |    2 +
 4 files changed, 93 insertions(+), 60 deletions(-)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 4e61e55..06fa319 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -672,6 +672,7 @@ virParseMacAddr;
 virFileDeletePid;
 virFindFileInPath;
 virFileExists;
+virFileIsOnNetworkShare;
 virFileHasSuffix;
 virFileLinkPointsTo;
 virFileMakePath;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 9140b50..6bbc94b 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -46,13 +46,6 @@
 #include <sys/ioctl.h>
 #include <sys/un.h>
 
-#ifdef __linux__
-# include <sys/vfs.h>
-# ifndef NFS_SUPER_MAGIC
-#  define NFS_SUPER_MAGIC 0x6969
-# endif /* NFS_SUPER_MAGIC */
-#endif /* __linux__ */
-
 #include "virterror_internal.h"
 #include "logging.h"
 #include "datatypes.h"
@@ -5069,62 +5062,32 @@ static int qemudDomainSaveFlag(virDomainPtr dom, const char *path,
                 goto endjob;
             }
 
-#ifdef __linux__
             /* On Linux we can also verify the FS-type of the directory. */
-            char *dirpath, *p;
-            struct statfs st;
-            int statfs_ret;
-
-            if ((dirpath = strdup(path)) == NULL) {
-                virReportOOMError();
-                goto endjob;
-            }
-
-            do {
-                // Try less and less of the path until we get to a
-                // directory we can stat. Even if we don't have 'x'
-                // permission on any directory in the path on the NFS
-                // server (assuming it's NFS), we will be able to stat the
-                // mount point, and that will properly tell us if the
-                // fstype is NFS.
-
-                if ((p = strrchr(dirpath, '/')) == NULL) {
-                    qemuReportError(VIR_ERR_INVALID_ARG,
-                                    _("Invalid relative path '%s' for domain save file"),
-                                    path);
-                    VIR_FREE(dirpath);
-                    goto endjob;
-                }
-
-                if (p == dirpath)
-                    *(p+1) = '\0';
-                else
-                    *p = '\0';
-
-                statfs_ret = statfs(dirpath, &st);
-
-            } while ((statfs_ret == -1) && (p != dirpath));
-
-            if (statfs_ret == -1) {
-                virReportSystemError(errno,
-                                     _("Failed to create domain save file "
-                                       "'%s': statfs of all elements of path "
-                                       "failed"),
-                                     path);
-                VIR_FREE(dirpath);
-                goto endjob;
-            }
+            switch (virFileIsOnNetworkShare(path)) {
+                case 1:
+                   /* it was on a network share, so we'll continue
+                    * as outlined above
+                    */
+                   break;
+
+                case -1:
+                   virReportSystemError(errno,
+                                        _("Failed to create domain save file "
+                                          "'%s': couldn't determine fs type"),
+                                        path);
+                   goto endjob;
+                   break;
+
+                case 0:
+                default:
+                   /* local file - log the error returned by virFileOperation */
+                   virReportSystemError(rc,
+                                        _("Failed to create domain save file '%s'"),
+                                        path);
+                   goto endjob;
+                   break;
 
-            if (st.f_type != NFS_SUPER_MAGIC) {
-                virReportSystemError(rc,
-                                     _("Failed to create domain save file '%s'"
-                                       " (fstype of '%s' is 0x%X"),
-                                     path, dirpath, (unsigned int) st.f_type);
-                VIR_FREE(dirpath);
-                goto endjob;
             }
-            VIR_FREE(dirpath);
-#endif
 
             /* Retry creating the file as driver->user */
 
diff --git a/src/util/util.c b/src/util/util.c
index 445fd4e..bf6ea30 100644
--- a/src/util/util.c
+++ b/src/util/util.c
@@ -48,6 +48,13 @@
 #endif
 #include "c-ctype.h"
 
+#ifdef __linux__
+# include <sys/vfs.h>
+# ifndef NFS_SUPER_MAGIC
+#  define NFS_SUPER_MAGIC 0x6969
+# endif /* NFS_SUPER_MAGIC */
+#endif /* __linux__ */
+
 #ifdef HAVE_PATHS_H
 # include <paths.h>
 #endif
@@ -1258,6 +1265,66 @@ int virFileExists(const char *path)
     return(0);
 }
 
+int virFileIsOnNetworkShare(const char *path)
+{
+#ifdef __linux__
+    char *dirpath, *p;
+    struct statfs st;
+    int ret = -1, statfs_ret;
+
+    if ((dirpath = strdup(path)) == NULL) {
+        virReportOOMError();
+        goto error;
+    }
+
+    do {
+        /* Try less and less of the path until we get to a
+         * directory we can stat. Even if we don't have 'x'
+         * permission on any directory in the path on the NFS
+         * server (assuming it's NFS), we will be able to stat the
+         * mount point, and that will properly tell us if the
+         * fstype is NFS.
+         */
+
+        if ((p = strrchr(dirpath, '/')) == NULL) {
+            virUtilError(VIR_ERR_INVALID_ARG,
+                         _("Invalid relative path '%s'"), path);
+            goto error;
+        }
+
+        if (p == dirpath)
+            *(p+1) = '\0';
+        else
+            *p = '\0';
+
+        statfs_ret = statfs(dirpath, &st);
+
+    } while ((statfs_ret == -1) && (p != dirpath));
+
+    if (statfs_ret == -1) {
+        virReportSystemError(errno,
+                             _("statfs of all elements of path %s failed"),
+                             path);
+        goto error;
+    }
+
+    if (st.f_type == NFS_SUPER_MAGIC) {
+        ret = 1;
+    } else {
+        VIR_WARN("fstype of '%s' unrecognized (0x%X)",
+                 dirpath, (unsigned int) st.f_type);
+        ret = 0;
+    }
+
+error:
+    VIR_FREE(dirpath);
+    return ret;
+
+#else
+    return 1;
+#endif
+}
+
 # ifndef WIN32
 static int virFileOperationNoFork(const char *path, int openflags, mode_t mode,
                                   uid_t uid, gid_t gid,
diff --git a/src/util/util.h b/src/util/util.h
index 476eac4..494c88a 100644
--- a/src/util/util.h
+++ b/src/util/util.h
@@ -118,6 +118,8 @@ char *virFindFileInPath(const char *file);
 
 int virFileExists(const char *path);
 
+int virFileIsOnNetworkShare(const char *path);
+
 char *virFileSanitizePath(const char *path);
 
 enum {
-- 
1.7.1




More information about the libvir-list mailing list