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