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

Daniel P. Berrangé posted 6 patches 7 years ago
[libvirt] [PATCH 4/6] storage: fix virStorageFileGetBackingStoreStr error handling
Posted by Daniel P. Berrangé 7 years ago
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@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

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 4/6] storage: fix virStorageFileGetBackingStoreStr error handling
Posted by Peter Krempa 7 years ago
On Wed, Apr 25, 2018 at 16:52:41 +0100, Daniel Berrange wrote:
> 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@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/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)

This is called from qemuDomainBlockPeek, where this would cause no error
to be reported.

ACK with the above addressed.
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 4/6] storage: fix virStorageFileGetBackingStoreStr error handling
Posted by Daniel P. Berrangé 7 years ago
On Thu, Apr 26, 2018 at 09:56:16AM +0200, Peter Krempa wrote:
> On Wed, Apr 25, 2018 at 16:52:41 +0100, Daniel Berrange wrote:
> > 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@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/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)
> 
> This is called from qemuDomainBlockPeek, where this would cause no error
> to be reported.

Ok, will add the obvious error reporting fix.

> 
> ACK with the above addressed.



Regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list