From dd75e2e4645137c8ede69ddc14ce528e696d4246 Mon Sep 17 00:00:00 2001 From: Michal Privoznik Date: Tue, 7 Dec 2021 14:43:33 +0100 Subject: [PATCH] virStreamInData: Allow callback to not rewind the stream So far, virStreamInData() is effectively a wrapper over virFDStreamInData() which means it deals with files which can be rewound (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 Reviewed-by: Martin Kletzander --- 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; }