]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/libvirt.git/commitdiff
Fix error reporting when fetching SCSI/LVM keys
authorDaniel P. Berrange <berrange@redhat.com>
Tue, 11 Dec 2012 19:10:51 +0000 (19:10 +0000)
committerDaniel P. Berrange <berrange@redhat.com>
Thu, 13 Dec 2012 15:26:57 +0000 (15:26 +0000)
The current  virStorageFileGet{LVM,SCSI}Key methods return
the key as the return value. Unfortunately it is desirable
for "NULL" to be a valid return value, as well as an error
indicator. Thus the returned key must instead be provided
as an out-parameter.

When we invoke lvs or scsi_id to extract ID for block devices,
we don't want virCommandWait logging errors messages. Thus we
must explicitly check 'status != 0', rather than letting
virCommandWait do it.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
src/util/storage_file.c
src/util/storage_file.h

index 83a05b3929fbd7c6d627dabac44f952a931bdad4..3f85e0e2d6723f939f8a7a6e0eb5cdd92c3441d8 100644 (file)
@@ -1218,62 +1218,75 @@ int virStorageFileIsClusterFS(const char *path)
 }
 
 #ifdef LVS
-char *virStorageFileGetLVMKey(const char *path)
+int virStorageFileGetLVMKey(const char *path,
+                            char **key)
 {
     /*
      *  # lvs --noheadings --unbuffered --nosuffix --options "uuid" LVNAME
      *    06UgP5-2rhb-w3Bo-3mdR-WeoL-pytO-SAa2ky
      */
-    char *key = NULL;
+    int status;
     virCommandPtr cmd = virCommandNewArgList(
         LVS,
         "--noheadings", "--unbuffered", "--nosuffix",
         "--options", "uuid", path,
         NULL
         );
+    int ret = -1;
+
+    *key = NULL;
 
     /* Run the program and capture its output */
-    virCommandSetOutputBuffer(cmd, &key);
-    if (virCommandRun(cmd, NULL) < 0)
+    virCommandSetOutputBuffer(cmd, key);
+    if (virCommandRun(cmd, &status) < 0)
         goto cleanup;
 
-    if (key) {
+    /* Explicitly check status == 0, rather than passing NULL
+     * to virCommandRun because we don't want to raise an actual
+     * error in this scenario, just return a NULL key.
+     */
+
+    if (status == 0 && *key) {
         char *nl;
-        char *tmp = key;
+        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);
+        if (tmp != *key)
+            memmove(*key, tmp, strlen(tmp)+1);
 
         /* Kill trailing newline */
-        if ((nl = strchr(key, '\n')))
+        if ((nl = strchr(*key, '\n')))
             *nl = '\0';
     }
 
-    if (key && STREQ(key, ""))
-        VIR_FREE(key);
+    ret = 0;
 
 cleanup:
+    if (*key && STREQ(*key, ""))
+        VIR_FREE(*key);
+
     virCommandFree(cmd);
 
-    return key;
+    return ret;
 }
 #else
-char *virStorageFileGetLVMKey(const char *path)
+int virStorageFileGetLVMKey(const char *path,
+                            char **key ATTRIBUTE_UNUSED)
 {
     virReportSystemError(ENOSYS, _("Unable to get LVM key for %s"), path);
-    return NULL;
+    return -1;
 }
 #endif
 
 #ifdef HAVE_UDEV
-char *virStorageFileGetSCSIKey(const char *path)
+int virStorageFileGetSCSIKey(const char *path,
+                             char **key)
 {
-    char *key = NULL;
+    int status;
     virCommandPtr cmd = virCommandNewArgList(
         "/lib/udev/scsi_id",
         "--replace-whitespace",
@@ -1281,30 +1294,41 @@ char *virStorageFileGetSCSIKey(const char *path)
         "--device", path,
         NULL
         );
+    int ret = -1;
+
+    *key = NULL;
 
     /* Run the program and capture its output */
-    virCommandSetOutputBuffer(cmd, &key);
-    if (virCommandRun(cmd, NULL) < 0)
+    virCommandSetOutputBuffer(cmd, key);
+    if (virCommandRun(cmd, &status) < 0)
         goto cleanup;
 
-    if (key && STRNEQ(key, "")) {
-        char *nl = strchr(key, '\n');
+    /* Explicitly check status == 0, rather than passing NULL
+     * to virCommandRun because we don't want to raise an actual
+     * error in this scenario, just return a NULL key.
+     */
+    if (status == 0 && *key) {
+        char *nl = strchr(*key, '\n');
         if (nl)
             *nl = '\0';
-    } else {
-        VIR_FREE(key);
     }
 
+    ret = 0;
+
 cleanup:
+    if (*key && STREQ(*key, ""))
+        VIR_FREE(*key);
+
     virCommandFree(cmd);
 
-    return key;
+    return ret;
 }
 #else
-char *virStorageFileGetSCSIKey(const char *path)
+int virStorageFileGetSCSIKey(const char *path,
+                             char **key ATTRIBUTE_UNUSED)
 {
     virReportSystemError(ENOSYS, _("Unable to get SCSI key for %s"), path);
-    return NULL;
+    return -1;
 }
 #endif
 
index 9e4516e0dca09dfdee74f8daf63f8862e5767376..6fbd2758c2c9e27f050e803983f5b3385d49a779 100644 (file)
@@ -101,7 +101,9 @@ int virStorageFileIsClusterFS(const char *path);
 int virStorageFileIsSharedFSType(const char *path,
                                  int fstypes);
 
-char *virStorageFileGetLVMKey(const char *path);
-char *virStorageFileGetSCSIKey(const char *path);
+int virStorageFileGetLVMKey(const char *path,
+                            char **key);
+int virStorageFileGetSCSIKey(const char *path,
+                             char **key);
 
 #endif /* __VIR_STORAGE_FILE_H__ */