On 05/16/2017 11: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(a)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.
Not sure what you mean. long long is the same size as off_t for any
application that enables large file support (libvirt does that) or is
compiled on 64bits. Any 32bit virt mgmt application should really enable
large file support, otherwise is pretty useless.
> + * 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'.
Maybe. One day. For now I'm happy with this example as-is. The example
should show how to set up virStreamSparseRecvAll.
Michal