[libvirt] [PATCH 4/6] storage: fix virStorageFileGetBackingStoreStr error handling

Daniel P. Berrangé berrange at redhat.com
Wed Apr 25 15:52:41 UTC 2018


The virStorageFileGetBackingStoreStr method has overloaded the NULL
return value to indicate both no backing available and a fatal
error dealing with it.

The caller is thus not able to correctly propagate the error
messages.

Signed-off-by: Daniel P. Berrangé <berrange at redhat.com>
---
 src/qemu/qemu_driver.c    | 15 +++++++++------
 src/util/virstoragefile.c | 49 +++++++++++++++++++++++++++++++----------------
 src/util/virstoragefile.h |  5 +++--
 3 files changed, 44 insertions(+), 25 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 7484b00e23..672c5372eb 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -14608,12 +14608,15 @@ qemuDomainSnapshotDiskDataCollect(virQEMUDriverPtr driver,
 
         /* relative backing store paths need to be updated so that relative
          * block commit still works */
-        if (reuse &&
-            (backingStoreStr = virStorageFileGetBackingStoreStr(dd->src))) {
-            if (virStorageIsRelative(backingStoreStr))
-                VIR_STEAL_PTR(dd->relPath, backingStoreStr);
-            else
-                VIR_FREE(backingStoreStr);
+        if (reuse) {
+            if (virStorageFileGetBackingStoreStr(dd->src, &backingStoreStr) < 0)
+                goto error;
+            if (backingStoreStr != NULL) {
+                if (virStorageIsRelative(backingStoreStr))
+                    VIR_STEAL_PTR(dd->relPath, backingStoreStr);
+                else
+                    VIR_FREE(backingStoreStr);
+            }
         }
 
         /* Note that it's unsafe to assume that the disks in the persistent
diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
index 531540ac91..f09035cd4a 100644
--- a/src/util/virstoragefile.c
+++ b/src/util/virstoragefile.c
@@ -4357,14 +4357,8 @@ virStorageFileRead(virStorageSourcePtr src,
         return -1;
     }
 
-    if (!src->drv->backend->storageFileRead) {
-        virReportError(VIR_ERR_INTERNAL_ERROR,
-                       _("storage file reading is not supported for "
-                         "storage type %s (protocol: %s)"),
-                       virStorageTypeToString(src->type),
-                       virStorageNetProtocolTypeToString(src->protocol));
+    if (!src->drv->backend->storageFileRead)
         return -2;
-    }
 
     ret = src->drv->backend->storageFileRead(src, offset, len, buf);
 
@@ -4551,8 +4545,15 @@ virStorageFileGetMetadataRecurse(virStorageSourcePtr src,
         goto cleanup;
 
     if ((headerLen = virStorageFileRead(src, 0, VIR_STORAGE_MAX_HEADER,
-                                        &buf)) < 0)
+                                        &buf)) < 0) {
+        if (headerLen == -2)
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("storage file reading is not supported for "
+                             "storage type %s (protocol: %s)"),
+                           virStorageTypeToString(src->type),
+                           virStorageNetProtocolTypeToString(src->protocol));
         goto cleanup;
+    }
 
     if (virStorageFileGetMetadataInternal(src, buf, headerLen,
                                           &backingFormat) < 0)
@@ -4664,24 +4665,36 @@ virStorageFileGetMetadata(virStorageSourcePtr src,
  * In case when the string can't be retrieved or does not exist NULL is
  * returned.
  */
-char *
-virStorageFileGetBackingStoreStr(virStorageSourcePtr src)
+int
+virStorageFileGetBackingStoreStr(virStorageSourcePtr src,
+                                 char **backing)
 {
     virStorageSourcePtr tmp = NULL;
     char *buf = NULL;
     ssize_t headerLen;
-    char *ret = NULL;
+    int ret = -1;
+    int rv;
+
+    *backing = NULL;
 
     /* exit if we can't load information about the current image */
     if (!virStorageFileSupportsBackingChainTraversal(src))
-        return NULL;
+        return 0;
 
-    if (virStorageFileAccess(src, F_OK) < 0)
-        return NULL;
+    rv = virStorageFileAccess(src, F_OK);
+    if (rv == -2)
+        return 0;
+    if (rv < 0) {
+        virStorageFileReportBrokenChain(errno, src, src);
+        return -1;
+    }
 
     if ((headerLen = virStorageFileRead(src, 0, VIR_STORAGE_MAX_HEADER,
-                                        &buf)) < 0)
-        return NULL;
+                                        &buf)) < 0) {
+        if (headerLen == -2)
+            return 0;
+        return -1;
+    }
 
     if (!(tmp = virStorageSourceCopy(src, false)))
         goto cleanup;
@@ -4689,7 +4702,9 @@ virStorageFileGetBackingStoreStr(virStorageSourcePtr src)
     if (virStorageFileGetMetadataInternal(tmp, buf, headerLen, NULL) < 0)
         goto cleanup;
 
-    VIR_STEAL_PTR(ret, tmp->backingStoreRaw);
+    VIR_STEAL_PTR(*backing, tmp->backingStoreRaw);
+
+    ret = 0;
 
  cleanup:
     VIR_FREE(buf);
diff --git a/src/util/virstoragefile.h b/src/util/virstoragefile.h
index d129e81978..b92c1c47dd 100644
--- a/src/util/virstoragefile.h
+++ b/src/util/virstoragefile.h
@@ -474,8 +474,9 @@ int virStorageFileGetMetadata(virStorageSourcePtr src,
                               bool report_broken)
     ATTRIBUTE_NONNULL(1);
 
-char *virStorageFileGetBackingStoreStr(virStorageSourcePtr src)
-    ATTRIBUTE_NONNULL(1);
+int virStorageFileGetBackingStoreStr(virStorageSourcePtr src,
+                                     char **backing)
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
 
 void virStorageFileReportBrokenChain(int errcode,
                                      virStorageSourcePtr src,
-- 
2.14.3




More information about the libvir-list mailing list