[libvirt] [PATCH RFC 07/48] Introduce virStreamSkip

Daniel P. Berrange berrange at redhat.com
Mon Jun 27 17:13:02 UTC 2016


On Wed, Jun 22, 2016 at 04:43:24PM +0200, Michal Privoznik wrote:
> This API can be used to tell the other side of the stream to skip
> some bytes in the stream. This can be used to create a sparse
> file on the receiving side of a stream.
> 
> It takes just one argument @length, which says how big the hole
> is. Since our streams are not rewindable like regular files, we
> don't need @whence argument like seek(2) has.
> 
> Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
> ---
>  include/libvirt/libvirt-stream.h |  3 +++
>  src/driver-stream.h              |  5 ++++
>  src/libvirt-stream.c             | 57 ++++++++++++++++++++++++++++++++++++++++
>  src/libvirt_public.syms          |  1 +
>  4 files changed, 66 insertions(+)
> 
> diff --git a/include/libvirt/libvirt-stream.h b/include/libvirt/libvirt-stream.h
> index bee2516..4e0a599 100644
> --- a/include/libvirt/libvirt-stream.h
> +++ b/include/libvirt/libvirt-stream.h
> @@ -50,6 +50,9 @@ int virStreamRecvFlags(virStreamPtr st,
>                         size_t nbytes,
>                         unsigned int flags);
>  
> +int virStreamSkip(virStreamPtr st,
> +                  unsigned long long length);
> +
>  
>  /**
>   * virStreamSourceFunc:
> diff --git a/src/driver-stream.h b/src/driver-stream.h
> index d4b0480..20ea13f 100644
> --- a/src/driver-stream.h
> +++ b/src/driver-stream.h
> @@ -42,6 +42,10 @@ typedef int
>                           unsigned int flags);
>  
>  typedef int
> +(*virDrvStreamSkip)(virStreamPtr st,
> +                    unsigned long long length);
> +
> +typedef int
>  (*virDrvStreamEventAddCallback)(virStreamPtr stream,
>                                  int events,
>                                  virStreamEventCallback cb,
> @@ -68,6 +72,7 @@ struct _virStreamDriver {
>      virDrvStreamSend streamSend;
>      virDrvStreamRecv streamRecv;
>      virDrvStreamRecvFlags streamRecvFlags;
> +    virDrvStreamSkip streamSkip;
>      virDrvStreamEventAddCallback streamEventAddCallback;
>      virDrvStreamEventUpdateCallback streamEventUpdateCallback;
>      virDrvStreamEventRemoveCallback streamEventRemoveCallback;
> diff --git a/src/libvirt-stream.c b/src/libvirt-stream.c
> index 80b2d47..55f3ef5 100644
> --- a/src/libvirt-stream.c
> +++ b/src/libvirt-stream.c
> @@ -346,6 +346,63 @@ virStreamRecvFlags(virStreamPtr stream,
>  
>  
>  /**
> + * virStreamSkip:
> + * @stream: pointer to the stream object
> + * @length: number of bytes to skip
> + *
> + * Skip @length bytes in the stream. This is useful when there's
> + * no actual data in the stream, just a hole. If that's the case,
> + * this API can be used to skip the hole properly instead of
> + * transmitting zeroes to the other side.
> + *
> + * An example using this with a hypothetical file upload API
> + * looks like:
> + *
> + *   virStream st;
> + *
> + *   while (1) {
> + *     char buf[4096];
> + *     size_t len;
> + *     if (..in hole...) {
> + *       ..get hole size...
> + *       virStreamSkip(st, len);
> + *     } else {
> + *       ...read len bytes...
> + *       virStreamSend(st, buf, len);
> + *     }
> + *   }
> + *
> + * Returns 0 on success,
> + *        -1 error
> + */
> +int
> +virStreamSkip(virStreamPtr stream,
> +              unsigned long long length)
> +{
> +    VIR_DEBUG("stream=%p, length=%llu", stream, length);
> +
> +    virResetLastError();
> +
> +    virCheckStreamReturn(stream, -1);
> +
> +    if (stream->driver &&
> +        stream->driver->streamSkip) {
> +        int ret;
> +        ret = (stream->driver->streamSkip)(stream, length);
> +        if (ret < 0)
> +            goto error;
> +        return ret;
> +    }
> +
> +    virReportUnsupportedError();
> +
> + error:
> +    virDispatchError(stream->conn);
> +    return -1;
> +}
> +
> +
> +/**
>   * virStreamSendAll:
>   * @stream: pointer to the stream object
>   * @handler: source callback for reading data from application
> diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
> index d013d9f..5b536eb 100644
> --- a/src/libvirt_public.syms
> +++ b/src/libvirt_public.syms
> @@ -739,6 +739,7 @@ LIBVIRT_2.0.0 {
>          virDomainSetGuestVcpus;
>          virConnectStoragePoolEventRegisterAny;
>          virStreamRecvFlags;
> +        virStreamSkip;
>  } LIBVIRT_1.3.3;

We can put this in a 2.1.0 block now


ACK

Regards,
Daniel
-- 
|: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org              -o-             http://virt-manager.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org       -o-       http://live.gnome.org/gtk-vnc :|




More information about the libvir-list mailing list