[libvirt] [PATCH 1/6 v2] Add virFileIsMountPoint function

Daniel P. Berrange berrange at redhat.com
Wed Oct 16 11:13:48 UTC 2013


From: "Daniel P. Berrange" <berrange at 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 <berrange at redhat.com>
---
 src/libvirt_private.syms |  1 +
 src/util/virfile.c       | 50 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/util/virfile.h       |  2 ++
 3 files changed, 53 insertions(+)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 84c1c28..fff91ca 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1187,6 +1187,7 @@ virFileIsAbsPath;
 virFileIsDir;
 virFileIsExecutable;
 virFileIsLink;
+virFileIsMountPoint;
 virFileLinkPointsTo;
 virFileLock;
 virFileLoopDeviceAssociate;
diff --git a/src/util/virfile.c b/src/util/virfile.c
index e10de5a..b93fa87 100644
--- a/src/util/virfile.c
+++ b/src/util/virfile.c
@@ -1513,6 +1513,56 @@ 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))
+        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




More information about the libvir-list mailing list