From: "Daniel P. Berrange" <berra...@redhat.com> Add a function for efficiently checking if a path is a filesystem mount point.
NB will not work for bind mounts, only true filesystem mounts. Signed-off-by: Daniel P. Berrange <berra...@redhat.com> --- src/libvirt_private.syms | 1 + src/util/virfile.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++ src/util/virfile.h | 2 ++ 3 files changed, 61 insertions(+) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index fe40834..31fa604 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1182,6 +1182,7 @@ virFileIsAbsPath; virFileIsDir; virFileIsExecutable; virFileIsLink; +virFileIsMountPoint; virFileLinkPointsTo; virFileLock; virFileLoopDeviceAssociate; diff --git a/src/util/virfile.c b/src/util/virfile.c index e10de5a..fa21aeb 100644 --- a/src/util/virfile.c +++ b/src/util/virfile.c @@ -1513,6 +1513,64 @@ virFileIsExecutable(const char *file) return false; } + +/* + * Check that a file refers to a mount point. Trick is that for + * a mount point, the st_dev field will differ from the parent + * directory. + * + * Note that this will not detect bind mounts of dirs/files, + * only true filesystem mounts. + */ +int virFileIsMountPoint(const char *file) +{ + char *parent = NULL; + char *tmp; + int ret = -1; + struct stat sb1, sb2; + + if (VIR_STRDUP_QUIET(parent, file) < 0) + goto cleanup; + + if (!(tmp = strrchr(parent, '/'))) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Could not find '/' in '%s'"), + file); + goto cleanup; + } + + *tmp = '\0'; + + VIR_DEBUG("Comparing '%s' to '%s'", file, parent); + + if (stat(file, &sb1) < 0) { + if (errno == ENOENT) + ret = 0; + else + virReportSystemError(errno, + _("Cannot stat '%s'"), + file); + goto cleanup; + } + + if (stat(parent, &sb2) < 0) { + virReportSystemError(errno, + _("Cannot stat '%s'"), + parent); + goto cleanup; + } + + if (!S_ISDIR(sb1.st_mode)) + return false; + + ret = sb1.st_dev != sb2.st_dev; + VIR_DEBUG("Is mount %d", ret); + + cleanup: + VIR_FREE(parent); + return ret; +} + #ifndef WIN32 /* Check that a file is accessible under certain * user & gid. diff --git a/src/util/virfile.h b/src/util/virfile.h index 72d35ce..ff84719 100644 --- a/src/util/virfile.h +++ b/src/util/virfile.h @@ -156,6 +156,8 @@ bool virFileIsDir (const char *file) ATTRIBUTE_NONNULL(1); bool virFileExists(const char *file) ATTRIBUTE_NONNULL(1); bool virFileIsExecutable(const char *file) ATTRIBUTE_NONNULL(1); +int virFileIsMountPoint(const char *file) ATTRIBUTE_NONNULL(1); + char *virFileSanitizePath(const char *path); enum { -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list