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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list