An update of patch 10 from:
http://www.redhat.com/archives/libvir-list/2010-November/msg00555.html
The SCSI volumes get a better 'key' field based on the fully
qualified volume path. All SCSI volumes have a unique serial
available in hardware which can be obtained by sending a
suitable SCSI command. Call out to udev's 'scsi_id' command
to fetch this value
In v2:
- Only use scsi_id if HAVE_UDEV is defined. This ensures
use only on udev >= 145 and thus avoids problem of
different semantics on RHEL-5 vintage udev
- Use virCommandPtr instead of virExec
- Use VIR_FDOPEN instead of fdopen
* src/storage/storage_backend_scsi.c: Improve volume key
field value stability and uniqueness
---
src/storage/storage_backend_scsi.c | 65 +++++++++++++++++++++++++++++++++--
1 files changed, 61 insertions(+), 4 deletions(-)
diff --git a/src/storage/storage_backend_scsi.c b/src/storage/storage_backend_scsi.c
index d880d65..ed91703 100644
--- a/src/storage/storage_backend_scsi.c
+++ b/src/storage/storage_backend_scsi.c
@@ -33,6 +33,7 @@
#include "memory.h"
#include "logging.h"
#include "files.h"
+#include "command.h"
#define VIR_FROM_THIS VIR_FROM_STORAGE
@@ -160,6 +161,65 @@ cleanup:
return ret;
}
+
+static char *
+virStorageBackendSCSISerial(const char *dev)
+{
+ char *serial = NULL;
+#ifdef HAVE_UDEV
+ int fd = -1;
+ FILE *list = NULL;
+ char line[1024];
+ virCommandPtr cmd = virCommandNewArgList(
+ "/lib/udev/scsi_id",
+ "--replace-whitespace",
+ "--whitelisted",
+ "--device", dev,
+ NULL
+ );
+
+ /* Run the program and capture its output */
+ virCommandSetOutputFD(cmd, &fd);
+ if (virCommandRunAsync(cmd, NULL) < 0)
+ goto cleanup;
+
+ if ((list = VIR_FDOPEN(fd, "r")) == NULL) {
+ virStorageReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("cannot read fd"));
+ goto cleanup;
+ }
+
+ if (fgets(line, sizeof(line), list)) {
+ char *nl = strchr(line, '\n');
+ if (nl)
+ *nl = '\0';
+ VIR_ERROR("GOT ID %s\n", line);
+ serial = strdup(line);
+ } else {
+ VIR_ERROR("NO ID %s\n", dev);
+ serial = strdup(dev);
+ }
+
+ if (!serial) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+cleanup:
+ if (list)
+ fclose(list);
+ else
+ VIR_FORCE_CLOSE(fd);
+
+ virCommandFree(cmd);
+#else
+ if (!(serial = strdup(dev)))
+ virReportOOMError();
+#endif
+ return serial;
+}
+
+
static int
virStorageBackendSCSINewLun(virStoragePoolObjPtr pool,
uint32_t host ATTRIBUTE_UNUSED,
@@ -233,10 +293,7 @@ virStorageBackendSCSINewLun(virStoragePoolObjPtr pool,
goto free_vol;
}
- /* XXX should use logical unit's UUID instead */
- vol->key = strdup(vol->target.path);
- if (vol->key == NULL) {
- virReportOOMError();
+ if (!(vol->key = virStorageBackendSCSISerial(vol->target.path))) {
retval = -1;
goto free_vol;
}
--
1.7.4