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(a)redhat.com>
---
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