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@xxxxxxxxxx> > --- > 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 :| -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list