rpc: Introduce virNetClientStreamInData()

The aim of this function is to look at a virNetClientStream and
tell whether the incoming packet (if there's one) contains data
(type VIR_NET_STREAM) or a hole (type VIR_NET_STREAM_HOLE) and
how big the section is. This function will be called from the
remote driver in one of future commits.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
This commit is contained in:
Michal Privoznik 2021-12-07 14:04:35 +01:00
parent dd75e2e464
commit 2981d1c95e
3 changed files with 69 additions and 0 deletions

View File

@ -66,6 +66,7 @@ virNetClientStreamEOF;
virNetClientStreamEventAddCallback;
virNetClientStreamEventRemoveCallback;
virNetClientStreamEventUpdateCallback;
virNetClientStreamInData;
virNetClientStreamMatches;
virNetClientStreamNew;
virNetClientStreamQueuePacket;

View File

@ -801,3 +801,67 @@ bool virNetClientStreamEOF(virNetClientStream *st)
{
return st->incomingEOF;
}
int virNetClientStreamInData(virNetClientStream *st,
int *inData,
long long *length)
{
int ret = -1;
bool msgPopped = false;
virNetMessage *msg = NULL;
virObjectLock(st);
if (!st->allowSkip) {
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
_("Holes are not supported with this stream"));
goto cleanup;
}
if (virNetClientStreamCheckState(st) < 0)
goto cleanup;
msg = st->rx;
if (!msg) {
/* No incoming message. This means that the stream is at its end. In
* this case, virStreamInData() should set both inData and length to
* zero and return success. If there is a trailing hole though (there
* shouldn't be), signal that to the caller. */
*inData = 0;
*length = st->holeLength;
st->holeLength = 0;
} else if (msg->header.type == VIR_NET_STREAM) {
*inData = 1;
*length = msg->bufferLength - msg->bufferOffset;
} else if (msg->header.type == VIR_NET_STREAM_HOLE) {
*inData = 0;
if (st->holeLength == 0) {
if (virNetClientStreamHandleHole(NULL, st) < 0)
goto cleanup;
/* virNetClientStreamHandleHole() called above did pop the message from
* the queue (and freed it). Instead of trying to push it back let's
* just signal to the caller what we did. */
msgPopped = true;
}
*length = st->holeLength;
st->holeLength = 0;
} else {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Invalid message prog=%d type=%d serial=%u proc=%d"),
msg->header.prog,
msg->header.type,
msg->header.serial,
msg->header.proc);
goto cleanup;
}
ret = msgPopped ? 1 : 0;
cleanup:
virObjectUnlock(st);
return ret;
}

View File

@ -90,3 +90,7 @@ int virNetClientStreamEventRemoveCallback(virNetClientStream *st);
bool virNetClientStreamEOF(virNetClientStream *st)
ATTRIBUTE_NONNULL(1);
int virNetClientStreamInData(virNetClientStream *st,
int *inData,
long long *length);