]> xenbits.xensource.com Git - libvirt.git/commitdiff
Add APIs for obtaining the unique ID of LVM & SCSI volumes
authorDaniel P. Berrange <berrange@redhat.com>
Wed, 20 Jul 2011 09:40:53 +0000 (10:40 +0100)
committerDaniel P. Berrange <berrange@redhat.com>
Thu, 9 Aug 2012 15:12:01 +0000 (16:12 +0100)
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.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
src/util/storage_file.c
src/util/storage_file.h

index 101518a7df31c5b636e9923b159003a58f83f7fb..2399e50033a1ff58c263f7a4a960097f00f8a984 100644 (file)
@@ -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
index 1fbe08e916fea6f93be9706982c091c746606aa7..99a5e36d9ad84199f03a5a872221afbd92622f53 100644 (file)
@@ -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__ */