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(a)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, §ionLen, opaque) < 0)
+ if (holeHandler(stream, &inData, §ionLen, 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