There are couple of callbacks we pass to virStreamSendAll(), virStreamRecvAll() or its sparse variants. However, none of these callbacks reports error if one occurs and neither do the virStream* functions leaving user with very unhelpful error message: error: cannot receive data from volume fedora.img error: An error occurred, but the cause is unknown Signed-off-by: Michal Privoznik <mprivozn@xxxxxxxxxx> --- tools/virsh-util.c | 38 +++++++++++++++++++++++++++++--------- tools/virsh-util.h | 2 +- tools/virsh-volume.c | 8 ++++++-- 3 files changed, 36 insertions(+), 12 deletions(-) diff --git a/tools/virsh-util.c b/tools/virsh-util.c index 44be3ad64..183f4c8bb 100644 --- a/tools/virsh-util.c +++ b/tools/virsh-util.c @@ -147,9 +147,15 @@ virshStreamSink(virStreamPtr st ATTRIBUTE_UNUSED, size_t nbytes, void *opaque) { - int *fd = opaque; + virshStreamCallbackDataPtr cbData = opaque; + int fd = cbData->fd; + const char *filename = cbData->filename; + int ret; - return safewrite(*fd, bytes, nbytes); + if ((ret = safewrite(fd, bytes, nbytes)) < 0) + virReportSystemError(errno, _("unable to write to %s"), filename); + + return ret; } @@ -161,8 +167,13 @@ virshStreamSource(virStreamPtr st ATTRIBUTE_UNUSED, { virshStreamCallbackDataPtr cbData = opaque; int fd = cbData->fd; + const char *filename = cbData->filename; + int ret; - return saferead(fd, bytes, nbytes); + if ((ret = saferead(fd, bytes, nbytes)) < 0) + virReportSystemError(errno, _("unable to read from %s"), filename); + + return ret; } @@ -173,10 +184,13 @@ virshStreamSourceSkip(virStreamPtr st ATTRIBUTE_UNUSED, { virshStreamCallbackDataPtr cbData = opaque; int fd = cbData->fd; + const char *filename = cbData->filename; off_t cur; - if ((cur = lseek(fd, offset, SEEK_CUR)) == (off_t) -1) + if ((cur = lseek(fd, offset, SEEK_CUR)) == (off_t) -1) { + virReportSystemError(errno, _("unable to seek in %s"), filename); return -1; + } return 0; } @@ -187,14 +201,20 @@ virshStreamSkip(virStreamPtr st ATTRIBUTE_UNUSED, long long offset, void *opaque) { - int *fd = opaque; + virshStreamCallbackDataPtr cbData = opaque; + int fd = cbData->fd; + const char *filename = cbData->filename; off_t cur; - if ((cur = lseek(*fd, offset, SEEK_CUR)) == (off_t) -1) + if ((cur = lseek(fd, offset, SEEK_CUR)) == (off_t) -1) { + virReportSystemError(errno, _("unable to seek in %s"), filename); return -1; + } - if (ftruncate(*fd, cur) < 0) + if (ftruncate(fd, cur) < 0) { + virReportSystemError(errno, _("unable to truncate %s"), filename); return -1; + } return 0; } @@ -207,12 +227,12 @@ virshStreamInData(virStreamPtr st ATTRIBUTE_UNUSED, void *opaque) { virshStreamCallbackDataPtr cbData = opaque; - vshControl *ctl = cbData->ctl; int fd = cbData->fd; + const char *filename = cbData->filename; int ret; if ((ret = virFileInData(fd, inData, offset)) < 0) - vshError(ctl, "%s", _("Unable to get current position in stream")); + virReportSystemError(errno, _("unable to seek in %s"), filename); return ret; } diff --git a/tools/virsh-util.h b/tools/virsh-util.h index 9a0af3513..0babb311b 100644 --- a/tools/virsh-util.h +++ b/tools/virsh-util.h @@ -60,8 +60,8 @@ virshStreamSink(virStreamPtr st, typedef struct _virshStreamCallbackData virshStreamCallbackData; typedef virshStreamCallbackData *virshStreamCallbackDataPtr; struct _virshStreamCallbackData { - vshControl *ctl; int fd; + const char *filename; }; int diff --git a/tools/virsh-volume.c b/tools/virsh-volume.c index 0736bdcdb..ea4660fee 100644 --- a/tools/virsh-volume.c +++ b/tools/virsh-volume.c @@ -698,8 +698,8 @@ cmdVolUpload(vshControl *ctl, const vshCmd *cmd) goto cleanup; } - cbData.ctl = ctl; cbData.fd = fd; + cbData.filename = file; if (vshCommandOptBool(cmd, "sparse")) flags |= VIR_STORAGE_VOL_UPLOAD_SPARSE_STREAM; @@ -795,6 +795,7 @@ cmdVolDownload(vshControl *ctl, const vshCmd *cmd) bool created = false; virshControlPtr priv = ctl->privData; unsigned int flags = 0; + virshStreamCallbackData cbData; if (vshCommandOptULongLong(ctl, cmd, "offset", &offset) < 0) return false; @@ -821,6 +822,9 @@ cmdVolDownload(vshControl *ctl, const vshCmd *cmd) created = true; } + cbData.fd = fd; + cbData.filename = file; + if (!(st = virStreamNew(priv->conn, 0))) { vshError(ctl, _("cannot create a new stream")); goto cleanup; @@ -831,7 +835,7 @@ cmdVolDownload(vshControl *ctl, const vshCmd *cmd) goto cleanup; } - if (virStreamSparseRecvAll(st, virshStreamSink, virshStreamSkip, &fd) < 0) { + if (virStreamSparseRecvAll(st, virshStreamSink, virshStreamSkip, &cbData) < 0) { vshError(ctl, _("cannot receive data from volume %s"), name); goto cleanup; } -- 2.13.0 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list