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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list