[libvirt] [PATCH] Add APIs for obtaining the unique ID of LVM & SCSI volumes

Daniel P. Berrange berrange at redhat.com
Thu Aug 2 13:09:31 UTC 2012


From: "Daniel P. Berrange" <berrange at redhat.com>

Both LVM volumes and SCSI LUNs have a globally unique
identifier associated with them. It is useful to be able
to query this identifier to then perform disk locking,
rather than try to figure out a stable pathname.
---
 src/util/storage_file.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++++
 src/util/storage_file.h |  3 ++
 2 files changed, 96 insertions(+)

diff --git a/src/util/storage_file.c b/src/util/storage_file.c
index f38aa8e..56fd322 100644
--- a/src/util/storage_file.c
+++ b/src/util/storage_file.c
@@ -24,6 +24,7 @@
 #include <config.h>
 #include "storage_file.h"
 
+#include <command.h>
 #include <sys/stat.h>
 #include <unistd.h>
 #include <fcntl.h>
@@ -38,6 +39,7 @@
 #include "virterror_internal.h"
 #include "logging.h"
 #include "virfile.h"
+#include "c-ctype.h"
 
 #define VIR_FROM_THIS VIR_FROM_STORAGE
 
@@ -1073,3 +1075,94 @@ int virStorageFileIsClusterFS(const char *path)
                                         VIR_STORAGE_FILE_SHFS_GFS2 |
                                         VIR_STORAGE_FILE_SHFS_OCFS);
 }
+
+#ifdef LVS
+const char *virStorageFileGetLVMKey(const char *path)
+{
+    /*
+     *  # lvs --noheadings --unbuffered --nosuffix --options "uuid" LVNAME
+     *    06UgP5-2rhb-w3Bo-3mdR-WeoL-pytO-SAa2ky
+     */
+    char *key = NULL;
+    virCommandPtr cmd = virCommandNewArgList(
+        LVS,
+        "--noheadings", "--unbuffered", "--nosuffix",
+        "--options", "uuid", path,
+        NULL
+        );
+
+    /* Run the program and capture its output */
+    virCommandSetOutputBuffer(cmd, &key);
+    if (virCommandRun(cmd, NULL) < 0)
+        goto cleanup;
+
+    if (key) {
+        char *nl;
+        char *tmp = key;
+
+        /* Find first non-space character */
+        while (*tmp && c_isspace(*tmp)) {
+            tmp++;
+        }
+        /* Kill leading spaces */
+        if (tmp != key)
+            memmove(key, tmp, strlen(tmp)+1);
+
+        /* Kill trailing newline */
+        if ((nl = strchr(key, '\n')))
+            *nl = '\0';
+    }
+
+    if (key && STREQ(key, ""))
+        VIR_FREE(key);
+
+cleanup:
+    virCommandFree(cmd);
+
+    return key;
+}
+#else
+const char *virStorageFileGetLVMKey(const char *path)
+{
+    virReportSystemError(ENOSYS, _("Unable to get LVM key for %s"), path);
+    return NULL;
+}
+#endif
+
+#ifdef HAVE_UDEV
+const char *virStorageFileGetSCSIKey(const char *path)
+{
+    char *key = NULL;
+    virCommandPtr cmd = virCommandNewArgList(
+        "/lib/udev/scsi_id",
+        "--replace-whitespace",
+        "--whitelisted",
+        "--device", path,
+        NULL
+        );
+
+    /* Run the program and capture its output */
+    virCommandSetOutputBuffer(cmd, &key);
+    if (virCommandRun(cmd, NULL) < 0)
+        goto cleanup;
+
+    if (key && STRNEQ(key, "")) {
+        char *nl = strchr(key, '\n');
+        if (nl)
+            *nl = '\0';
+    } else {
+        VIR_FREE(key);
+    }
+
+cleanup:
+    virCommandFree(cmd);
+
+    return key;
+}
+#else
+const char *virStorageFileGetSCSIKey(const char *path)
+{
+    virReportSystemError(ENOSYS, _("Unable to get SCSI key for %s"), path);
+    return NULL;
+}
+#endif
diff --git a/src/util/storage_file.h b/src/util/storage_file.h
index 1fbe08e..99a5e36 100644
--- a/src/util/storage_file.h
+++ b/src/util/storage_file.h
@@ -86,4 +86,7 @@ int virStorageFileIsClusterFS(const char *path);
 int virStorageFileIsSharedFSType(const char *path,
                                  int fstypes);
 
+const char *virStorageFileGetLVMKey(const char *path);
+const char *virStorageFileGetSCSIKey(const char *path);
+
 #endif /* __VIR_STORAGE_FILE_H__ */
-- 
1.7.11.2




More information about the libvir-list mailing list