From: "Daniel P. Berrange" <berrange(a)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