[libvirt] [PATCH v3 26/31] daemonStreamHandleRead: Wire up seekable stream

John Ferlan jferlan at redhat.com
Wed May 17 13:58:02 UTC 2017



On 05/16/2017 10:04 AM, Michal Privoznik wrote:
> Whenever client is able to receive some data from stream
> daemonStreamHandleRead is called. But now the behaviour of this
> function needs to be changed a bit. Previously it just read data
> from underlying file (of chardev or whatever) and sent those
> through the stream to client. This model will not work any longer
> because it does not differentiate whether underlying file is in
> data or hole section. Therefore, at the beginning of this
> function add code that checks this situation and acts
> accordingly.

empty
 between paragraphs
> So after the this, when wanting to send some data we always check
> whether we are not in a hole and if so, skip it an inform client

s/it an inform/it and inform/

> about its size.
> 
> Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
> ---
>  daemon/stream.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 59 insertions(+)
> 
> diff --git a/daemon/stream.c b/daemon/stream.c
> index 57ddfe830..284499912 100644
> --- a/daemon/stream.c
> +++ b/daemon/stream.c
> @@ -29,6 +29,7 @@
>  #include "virlog.h"
>  #include "virnetserverclient.h"
>  #include "virerror.h"
> +#include "libvirt_internal.h"

Oh, right virStreamInData is not publicly available... (patch 10
comments)...

>  
>  #define VIR_FROM_THIS VIR_FROM_STREAMS
>  
> @@ -53,6 +54,7 @@ struct daemonClientStream {
>      bool tx;
>  
>      bool allowSkip;
> +    size_t dataLen; /* How much data is there remaining until we see a hole */
>  
>      daemonClientStreamPtr next;
>  };
> @@ -796,6 +798,8 @@ daemonStreamHandleRead(virNetServerClientPtr client,
>      size_t bufferLen = VIR_NET_MESSAGE_LEGACY_PAYLOAD_MAX;
>      int ret = -1;
>      int rv;
> +    int inData = 0;
> +    long long length = 0;
>  
>      VIR_DEBUG("client=%p, stream=%p tx=%d closed=%d",
>                client, stream, stream->tx, stream->closed);
> @@ -820,6 +824,58 @@ daemonStreamHandleRead(virNetServerClientPtr client,
>      if (!(msg = virNetMessageNew(false)))
>          goto cleanup;
>  
> +    if (stream->allowSkip && !stream->dataLen) {

dataLen == 0 ?

(I know, same thing - I guess it's just one of those visual things for
me...)


> +        /* Handle skip. We want to send some data to the client. But we might
> +         * be in a hole. Seek to next data. But if we are in data already, just
> +         * carry on. */
> +
> +        rv = virStreamInData(stream->st, &inData, &length);
> +        VIR_DEBUG("rv=%d inData=%d length=%lld", rv, inData, length);
> +
> +        if (rv < 0) {
> +            if (virNetServerProgramSendStreamError(remoteProgram,
> +                                                   client,
> +                                                   msg,
> +                                                   &rerr,
> +                                                   stream->procedure,
> +                                                   stream->serial) < 0)
> +                goto cleanup;
> +            msg = NULL;
> +
> +            /* We're done with this call */
> +            goto done;
> +        } else {
> +            if (!inData && length) {
> +                stream->tx = false;
> +                msg->cb = daemonStreamMessageFinished;
> +                msg->opaque = stream;
> +                stream->refs++;
> +                if (virNetServerProgramSendStreamHole(remoteProgram,
> +                                                      client,
> +                                                      msg,
> +                                                      stream->procedure,
> +                                                      stream->serial,
> +                                                      length,
> +                                                      0) < 0)
> +                    goto cleanup;
> +
> +                msg = NULL;
> +
> +                /* We have successfully sent stream skip to the  other side.

Extra space between "the  other"

> +                 * To keep streams in sync seek locally too. */
> +                virStreamSendHole(stream->st, length, 0);
> +                /* We're done with this call */
> +                goto done;
> +            }
> +        }
> +
> +        stream->dataLen = length;
> +    }
> +
> +    if (stream->allowSkip &&
> +        bufferLen > stream->dataLen)
> +        bufferLen = stream->dataLen;
> +
>      rv = virStreamRecv(stream->st, buffer, bufferLen);
>      if (rv == -2) {
>          /* Should never get this, since we're only called when we know
> @@ -834,6 +890,8 @@ daemonStreamHandleRead(virNetServerClientPtr client,
>              goto cleanup;
>          msg = NULL;
>      } else {
> +        stream->dataLen -= rv;
> +

Since dataLen is only "set" if stream->allowSkip - should this be fenced
similarly?

Not that I see ->dataLen being used for anything other than sparse
stream mgmt...

Reviewed-by: John Ferlan <jferlan at redhat.com>

John

>          stream->tx = false;
>          if (rv == 0)
>              stream->recvEOF = true;
> @@ -851,6 +909,7 @@ daemonStreamHandleRead(virNetServerClientPtr client,
>          msg = NULL;
>      }
>  
> + done:
>      ret = 0;
>   cleanup:
>      VIR_FREE(buffer);
> 




More information about the libvir-list mailing list