[libvirt] [PATCH 2/5] utils: Introduce virFileGetMPathTargets

Michal Privoznik mprivozn at redhat.com
Mon Mar 26 05:16:43 UTC 2018


This helper fetches targets for multipath devices.

Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
---
 src/libvirt_private.syms |  1 +
 src/util/virfile.c       | 90 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/util/virfile.h       |  4 +++
 3 files changed, 95 insertions(+)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 03fe3b315f..1bbff72263 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1773,6 +1773,7 @@ virFileGetACLs;
 virFileGetHugepageSize;
 virFileGetMountReverseSubtree;
 virFileGetMountSubtree;
+virFileGetMPathTargets;
 virFileHasSuffix;
 virFileInData;
 virFileIsAbsPath;
diff --git a/src/util/virfile.c b/src/util/virfile.c
index 5e9bd2007a..f89e4bd823 100644
--- a/src/util/virfile.c
+++ b/src/util/virfile.c
@@ -64,6 +64,10 @@
 # include <sys/ioctl.h>
 #endif
 
+#ifdef WITH_DEVMAPPER
+# include <libdevmapper.h>
+#endif
+
 #include "configmake.h"
 #include "intprops.h"
 #include "viralloc.h"
@@ -4227,3 +4231,89 @@ virFileWaitForExists(const char *path,
 
     return 0;
 }
+
+
+#ifdef WITH_DEVMAPPER
+/**
+ * virFileGetMPathTargets:
+ * @path: multipath device
+ * @devs: returned array of st_rdevs of @path targets
+ * @ndevs: size of @devs and @devNames
+ *
+ * For given @path figure out its targets, and store them in
+ * @devs. Items from @devs are meant to be used in
+ * minor() and major() to receive device MAJ:MIN pairs.
+ *
+ * If @path is not a multipath device, @ndevs is set to 0 and
+ * success is returned.
+ *
+ * If we don't have permissions to talk to kernel, -1 is returned
+ * and errno is set to EBADF.
+ *
+ * Returns 0 on success, -1 otherwise.
+ */
+int
+virFileGetMPathTargets(const char *path,
+                       unsigned long long **devs,
+                       size_t *ndevs)
+{
+    struct dm_deps *deps;
+    struct dm_task *dmt;
+    struct dm_info info;
+    size_t i;
+    int ret = -1;
+
+    *ndevs = 0;
+
+    if (!(dmt = dm_task_create(DM_DEVICE_DEPS)))
+        goto cleanup;
+
+    if (!dm_task_set_name(dmt, path)) {
+        if (errno == ENOENT) {
+            /* It's okay, @path is not managed by devmapper =>
+             * not a multipath device. */
+            ret = 0;
+        }
+        goto cleanup;
+    }
+
+    dm_task_no_open_count(dmt);
+
+    if (!dm_task_run(dmt))
+        goto cleanup;
+
+    if (!dm_task_get_info(dmt, &info))
+        goto cleanup;
+
+    if (!info.exists) {
+        ret = 0;
+        goto cleanup;
+    }
+
+    if (!(deps = dm_task_get_deps(dmt)))
+        goto cleanup;
+
+    if (VIR_ALLOC_N(*devs, deps->count) < 0)
+        goto cleanup;
+    *ndevs = deps->count;
+
+    for (i = 0; i < deps->count; i++)
+        (*devs)[i] = deps->device[i];
+
+    ret = 0;
+ cleanup:
+    dm_task_destroy(dmt);
+    return ret;
+}
+
+#else /* ! WITH_DEVMAPPER */
+
+int
+virFileGetMPathTargets(const char *path ATTRIBUTE_UNUSED,
+                       unsigned long long **devs ATTRIBUTE_UNUSED,
+                       size_t *ndevs ATTRIBUTE_UNUSED)
+{
+    errno = ENOSYS;
+    return -1;
+}
+#endif /* ! WITH_DEVMAPPER */
diff --git a/src/util/virfile.h b/src/util/virfile.h
index cd2a3867c2..0db8bf0b99 100644
--- a/src/util/virfile.h
+++ b/src/util/virfile.h
@@ -358,4 +358,8 @@ int virFileInData(int fd,
                   int *inData,
                   long long *length);
 
+int virFileGetMPathTargets(const char *path,
+                           unsigned long long **devs,
+                           size_t *ndevs);
+
 #endif /* __VIR_FILE_H */
-- 
2.16.1




More information about the libvir-list mailing list