So far, virStreamInData() is effectively a wrapper over virFDStreamInData() which means it deals with files which can be rewind (lseek()-ed) to whatever position we need. And in fact, that's what virFDStreamInData() does - it makes sure that the FD is left unchanged in terms of position in the file. Skipping the hole happens soon after - in daemonStreamHandleRead() when virStreamSendHole() is called. But this is about to change. Soon we will have another implementation where we won't be dealing with FDs but virNetMessage queue and it will be handy to pop message at the beginning of the queue. Implement and document this new behavior. Signed-off-by: Michal Privoznik <mprivozn@xxxxxxxxxx> --- src/libvirt-stream.c | 9 ++++++++- src/remote/remote_daemon_stream.c | 8 +++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/libvirt-stream.c b/src/libvirt-stream.c index 873d7b1d4e..bacbbfd325 100644 --- a/src/libvirt-stream.c +++ b/src/libvirt-stream.c @@ -505,7 +505,14 @@ virStreamRecvHole(virStreamPtr stream, * hole: @data = false, @length > 0 * EOF: @data = false, @length = 0 * - * Returns 0 on success, + * The position in the underlying stream should not be changed + * upon return from this function, e.g. position in the + * underlying file is kept the same. For streams where this + * condition is impossible to meet, the function can return 1 to + * signal this to a caller. + * + * Returns 0 on success (stream position unchanged), + * 1 on success (stream position changed), * -1 otherwise */ int diff --git a/src/remote/remote_daemon_stream.c b/src/remote/remote_daemon_stream.c index 007ad73e27..eb7ed5edf3 100644 --- a/src/remote/remote_daemon_stream.c +++ b/src/remote/remote_daemon_stream.c @@ -894,9 +894,11 @@ daemonStreamHandleRead(virNetServerClient *client, msg = NULL; - /* We have successfully sent stream skip to the other side. - * To keep streams in sync seek locally too. */ - virStreamSendHole(stream->st, length, 0); + /* We have successfully sent stream skip to the other side. To + * keep streams in sync seek locally too (rv == 0), unless it's + * already done (rv == 1). */ + if (rv == 0) + virStreamSendHole(stream->st, length, 0); /* We're done with this call */ goto done; } -- 2.32.0