From: "Daniel P. Berrange" <berrange@xxxxxxxxxx> 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list