From ccacd4fe3b7c9de7a4b6bb10220193fc4ba41221 Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Mon, 7 Oct 2013 12:51:58 +0100 Subject: [PATCH] Add virFileIsMountPoint function 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 --- src/libvirt_private.syms | 1 + src/util/virfile.c | 52 ++++++++++++++++++++++++++++++++++++++++ src/util/virfile.h | 2 ++ 3 files changed, 55 insertions(+) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index e7b9a59c0e..ad8a79d7dc 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1196,6 +1196,7 @@ virFileIsAbsPath; virFileIsDir; virFileIsExecutable; virFileIsLink; +virFileIsMountPoint; virFileLinkPointsTo; virFileLock; virFileLoopDeviceAssociate; diff --git a/src/util/virfile.c b/src/util/virfile.c index 3a9980cf4e..4882006d98 100644 --- a/src/util/virfile.c +++ b/src/util/virfile.c @@ -1518,6 +1518,58 @@ 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; + int ret = -1; + struct stat sb1, sb2; + + if (!(parent = mdir_name(file))) { + virReportOOMError(); + goto cleanup; + } + + 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)) { + ret = 0; + goto cleanup; + } + + 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 72d35ce4eb..ff84719ccf 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 { -- GitLab