I was wondering why this never made it to the list - seems I just sent it to Michal... So here's what I sent... John On 05/16/2017 05:34 PM, John Ferlan wrote: > > > On 05/16/2017 10:03 AM, Michal Privoznik wrote: >> This is just a wrapper over new functions that have been just >> introduced: virStreamRecvFlags(), virStreamRecvHole(). It's very >> similar to virStreamRecvAll() except it handles sparse streams >> well. >> >> Signed-off-by: Michal Privoznik <mprivozn@xxxxxxxxxx> >> --- >> include/libvirt/libvirt-stream.h | 33 ++++++++++- >> src/libvirt-stream.c | 123 +++++++++++++++++++++++++++++++++++++++ >> src/libvirt_public.syms | 1 + >> 3 files changed, 154 insertions(+), 3 deletions(-) >> > > [...] > >> diff --git a/src/libvirt-stream.c b/src/libvirt-stream.c >> index bedb6159a..6bf4c4f29 100644 >> --- a/src/libvirt-stream.c >> +++ b/src/libvirt-stream.c >> @@ -668,6 +668,129 @@ virStreamRecvAll(virStreamPtr stream, >> } >> >> >> +/** >> + * virStreamSparseRecvAll: >> + * @stream: pointer to the stream object >> + * @handler: sink callback for writing data to application >> + * @holeHandler: stream hole callback for skipping holes >> + * @opaque: application defined data >> + * >> + * Receive the entire data stream, sending the data to the >> + * requested data sink @handler and calling the skip @holeHandler >> + * to generate holes for sparse stream targets. This is simply a >> + * convenient alternative to virStreamRecvFlags, for apps that do >> + * blocking-I/O. >> + * >> + * An example using this with a hypothetical file download >> + * API looks like: >> + * >> + * int mysink(virStreamPtr st, const char *buf, int nbytes, void *opaque) { >> + * int *fd = opaque; >> + * >> + * return write(*fd, buf, nbytes); >> + * } >> + * >> + * int myskip(virStreamPtr st, long long offset, void *opaque) { >> + * int *fd = opaque; >> + * > > I think this is where perhaps the example of lseek in "off_t" chunks of > "long long offset" would be applicable... Perhaps why I ended up in the > off_t rathole before. > >> + * return lseek(*fd, offset, SEEK_CUR) == (off_t) -1 ? -1 : 0; >> + * } >> + * >> + * virStreamPtr st = virStreamNew(conn, 0); >> + * int fd = open("demo.iso", O_WRONLY); >> + * >> + * virConnectDownloadSparseFile(conn, st); > > ^^ This API doesn't exist... Of course neither did > virConnectDownloadFile from whence you copied the example. Maybe both > should be 'adjusted'. > > > Reviewed-by: John Ferlan <jferlan@xxxxxxxxxx> > > John > >> + * if (virStreamSparseRecvAll(st, mysink, myskip, &fd) < 0) { >> + * ...report an error ... >> + * goto done; >> + * } >> + * if (virStreamFinish(st) < 0) >> + * ...report an error... >> + * virStreamFree(st); >> + * close(fd); >> + * >> + * Note that @opaque data is shared between both @handler and >> + * @holeHandler callbacks. >> + * >> + * Returns 0 if all the data was successfully received. The caller >> + * should invoke virStreamFinish(st) to flush the stream upon >> + * success and then virStreamFree(st). >> + * >> + * Returns -1 upon any error, with virStreamAbort() already >> + * having been called, so the caller need only call virStreamFree(). >> + */ > > > [...] > -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list