[libvirt] [PATCH v3 08/31] Introduce virStreamSparseRecvAll

John Ferlan jferlan at redhat.com
Wed May 17 02:21:27 UTC 2017


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 at redhat.com>
>> ---
>>  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 at redhat.com>
> 
> 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().
>> + */
> 
> 
> [...]
> 




More information about the libvir-list mailing list