On 05/16/2017 10:04 AM, Michal Privoznik wrote: > Whenever server sends a client stream packet (either regular with > actual data or stream skip one) it is queued on @st->rx. So the > list is a mixture of both types of stream packets. So now that we > have all the helpers needed we can wire their processing up. But > since virNetClientStreamRecvPacket doesn't support > VIR_STREAM_RECV_STOP_AT_HOLE flag yet, let's turn all received > skips into zeroes repeating requested times. > > Signed-off-by: Michal Privoznik <mprivozn@xxxxxxxxxx> > --- > src/rpc/virnetclientstream.c | 45 ++++++++++++++++++++++++++++++++++++++++++-- > 1 file changed, 43 insertions(+), 2 deletions(-) > > diff --git a/src/rpc/virnetclientstream.c b/src/rpc/virnetclientstream.c > index bf3922cb5..75ec3f57f 100644 > --- a/src/rpc/virnetclientstream.c > +++ b/src/rpc/virnetclientstream.c > @@ -295,6 +295,8 @@ int virNetClientStreamQueuePacket(virNetClientStreamPtr st, > > virObjectLock(st); > > + /* Don't distinguish VIR_NET_STREAM and VIR_NET_STREAM_SKIP > + * here just yet. We want in order processing! */ > virNetMessageQueuePush(&st->rx, tmp_msg); > > virNetClientStreamEventTimerUpdate(st); > @@ -390,7 +392,7 @@ virNetClientStreamSetHole(virNetClientStreamPtr st, > * Returns: 0 on success, > * -1 otherwise. > */ > -static int ATTRIBUTE_UNUSED > +static int > virNetClientStreamHandleHole(virNetClientPtr client, > virNetClientStreamPtr st) > { > @@ -468,6 +470,8 @@ int virNetClientStreamRecvPacket(virNetClientStreamPtr st, > virCheckFlags(0, -1); > > virObjectLock(st); > + > + reread: > if (!st->rx && !st->incomingEOF) { > virNetMessagePtr msg; > int ret; > @@ -499,8 +503,45 @@ int virNetClientStreamRecvPacket(virNetClientStreamPtr st, > } > > VIR_DEBUG("After IO rx=%p", st->rx); > + > + if (st->rx && > + st->rx->header.type == VIR_NET_STREAM_HOLE && > + st->holeLength == 0) { Of course this is what I was referring to in patch 19... The only way to call virNetClientStreamHandleHole is if holeLength = 0, but since all the other validity checks (e.g. st->rx/msg and msg->header.type == HOLE) are present - what's one more later on... Your call you could also modify patch 19 to not have any extraneous checks that wouldn't be possible given the above lines... Your call, IDC. > + /* Handle skip sent to us by server. */ > + > + if (virNetClientStreamHandleHole(client, st) < 0) > + goto cleanup; > + } > + > + if (!st->rx && !st->incomingEOF && !st->holeLength) { holeLength == 0 Reviewed-by: John Ferlan <jferlan@xxxxxxxxxx> John > + if (nonblock) { > + VIR_DEBUG("Non-blocking mode and no data available"); > + rv = -2; > + goto cleanup; > + } > + > + /* We have consumed all packets from incoming queue but those > + * were only skip packets, no data. Read the stream again. */ > + goto reread; > + } > + > want = nbytes; > - while (want && st->rx) { > + > + if (st->holeLength) { > + /* Pretend holeLength zeroes was read from stream. */ > + size_t len = want; > + > + if (len > st->holeLength) > + len = st->holeLength; > + > + memset(data, 0, len); > + st->holeLength -= len; > + want -= len; > + } > + > + while (want && > + st->rx && > + st->rx->header.type == VIR_NET_STREAM) { > virNetMessagePtr msg = st->rx; > size_t len = want; > > -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list