]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/libvirt.git/commitdiff
Improve SCSI volume key generation
authorDaniel P. Berrange <berrange@redhat.com>
Fri, 12 Nov 2010 15:49:40 +0000 (15:49 +0000)
committerDaniel P. Berrange <berrange@redhat.com>
Tue, 5 Apr 2011 15:04:22 +0000 (16:04 +0100)
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

* src/storage/storage_backend_scsi.c: Improve volume key
  field value stability and uniqueness

src/storage/storage_backend_scsi.c

index d880d65ec372eca6cb9bcd041a9faba7d5d5d7b5..da3454701370438814706a13329514ddb2ad380c 100644 (file)
@@ -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,45 @@ cleanup:
     return ret;
 }
 
+
+static char *
+virStorageBackendSCSISerial(const char *dev)
+{
+    char *serial = NULL;
+#ifdef HAVE_UDEV
+    virCommandPtr cmd = virCommandNewArgList(
+        "/lib/udev/scsi_id",
+        "--replace-whitespace",
+        "--whitelisted",
+        "--device", dev,
+        NULL
+        );
+
+    /* Run the program and capture its output */
+    virCommandSetOutputBuffer(cmd, &serial);
+    if (virCommandRun(cmd, NULL) < 0)
+        goto cleanup;
+#endif
+
+    if (serial && STRNEQ(serial, "")) {
+        char *nl = strchr(serial, '\n');
+        if (nl)
+            *nl = '\0';
+    } else {
+        VIR_FREE(serial);
+        if (!(serial = strdup(dev)))
+            virReportOOMError();
+    }
+
+#ifdef HAVE_UDEV
+cleanup:
+    virCommandFree(cmd);
+#endif
+
+    return serial;
+}
+
+
 static int
 virStorageBackendSCSINewLun(virStoragePoolObjPtr pool,
                             uint32_t host ATTRIBUTE_UNUSED,
@@ -233,10 +273,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;
     }