[libvirt] [PATCH v2 6/6] streams: Report errors if sendAll/recvAll callbacks fail

Michal Privoznik mprivozn at redhat.com
Thu Jun 1 12:02:14 UTC 2017


We have couple of wrappers over our low level stream APIs:
virSreamRecvAll(), virStreamSendAll() and their sparse stream
variants. All of them take some callbacks and call them at
appropriate times. If a callback fails it aborts the whole
operation. However, if it so happens that the callback fails
without setting any error users are left with very unhelpful
error message:

  error: cannot receive data from volume fedora.img
  error: An error occurred, but the cause is unknown

One way to avoid it is to report error if callback hasn't.

Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
---
 src/libvirt-stream.c | 41 +++++++++++++++++++++++++++++++++--------
 1 file changed, 33 insertions(+), 8 deletions(-)

diff --git a/src/libvirt-stream.c b/src/libvirt-stream.c
index 1594ed212..efdbc9e44 100644
--- a/src/libvirt-stream.c
+++ b/src/libvirt-stream.c
@@ -596,8 +596,12 @@ virStreamSendAll(virStreamPtr stream,
     for (;;) {
         int got, offset = 0;
         got = (handler)(stream, bytes, want, opaque);
-        if (got < 0)
+        if (got < 0) {
+            if (!virGetLastError())
+                virReportError(VIR_ERR_OPERATION_FAILED, "%s",
+                               _("send handler failed"));
             goto cleanup;
+        }
         if (got == 0)
             break;
         while (offset < got) {
@@ -733,16 +737,21 @@ int virStreamSparseSendAll(virStreamPtr stream,
         const unsigned int skipFlags = 0;
 
         if (!dataLen) {
-            if (holeHandler(stream, &inData, &sectionLen, opaque) < 0)
+            if (holeHandler(stream, &inData, &sectionLen, opaque) < 0) {
+                if (!virGetLastError())
+                    virReportError(VIR_ERR_OPERATION_FAILED, "%s",
+                                   _("send holeHandler failed"));
                 goto cleanup;
+            }
 
             if (!inData && sectionLen) {
                 if (virStreamSendHole(stream, sectionLen, skipFlags) < 0)
                     goto cleanup;
 
                 if (skipHandler(stream, sectionLen, opaque) < 0) {
-                    virReportSystemError(errno, "%s",
-                                         _("unable to skip hole"));
+                    if (!virGetLastError())
+                        virReportError(VIR_ERR_OPERATION_FAILED, "%s",
+                                       _("send skipHandler failed"));
                     goto cleanup;
                 }
                 continue;
@@ -755,8 +764,12 @@ int virStreamSparseSendAll(virStreamPtr stream,
             want = dataLen;
 
         got = (handler)(stream, bytes, want, opaque);
-        if (got < 0)
+        if (got < 0) {
+            if (!virGetLastError())
+                virReportError(VIR_ERR_OPERATION_FAILED, "%s",
+                               _("send handler failed"));
             goto cleanup;
+        }
         if (got == 0)
             break;
         while (offset < got) {
@@ -862,8 +875,12 @@ virStreamRecvAll(virStreamPtr stream,
         while (offset < got) {
             int done;
             done = (handler)(stream, bytes + offset, got - offset, opaque);
-            if (done < 0)
+            if (done < 0) {
+                if (!virGetLastError())
+                    virReportError(VIR_ERR_OPERATION_FAILED, "%s",
+                                   _("receive handler failed"));
                 goto cleanup;
+            }
             offset += done;
         }
     }
@@ -976,8 +993,12 @@ virStreamSparseRecvAll(virStreamPtr stream,
             if (virStreamRecvHole(stream, &holeLen, holeFlags) < 0)
                 goto cleanup;
 
-            if (holeHandler(stream, holeLen, opaque) < 0)
+            if (holeHandler(stream, holeLen, opaque) < 0) {
+                if (!virGetLastError())
+                    virReportError(VIR_ERR_OPERATION_FAILED, "%s",
+                                   _("receive holeHandler failed"));
                 goto cleanup;
+            }
             continue;
         } else if (got < 0) {
             goto cleanup;
@@ -987,8 +1008,12 @@ virStreamSparseRecvAll(virStreamPtr stream,
         while (offset < got) {
             int done;
             done = (handler)(stream, bytes + offset, got - offset, opaque);
-            if (done < 0)
+            if (done < 0) {
+                if (!virGetLastError())
+                    virReportError(VIR_ERR_OPERATION_FAILED, "%s",
+                                   _("receive handler failed"));
                 goto cleanup;
+            }
             offset += done;
         }
     }
-- 
2.13.0




More information about the libvir-list mailing list