[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[libvirt] [PATCH v2 17/32] virnetclientstream: Introduce virNetClientStreamHandleSkip



This is a function that handles an incoming STREAM_SKIP packet.
Even though it is not wired up yet, it will be soon. At the
beginning do couple of checks whether server plays nicely and
sent us a STREAM_SKIP packed only after we've enabled sparse
streams. Then decodes the message payload to see how big the hole
is and stores it in passed @length argument.

Signed-off-by: Michal Privoznik <mprivozn redhat com>
---
 src/rpc/virnetclientstream.c | 63 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 63 insertions(+)

diff --git a/src/rpc/virnetclientstream.c b/src/rpc/virnetclientstream.c
index d7d2b0e..0e982ba 100644
--- a/src/rpc/virnetclientstream.c
+++ b/src/rpc/virnetclientstream.c
@@ -28,6 +28,7 @@
 #include "virerror.h"
 #include "virlog.h"
 #include "virthread.h"
+#include "libvirt_internal.h"
 
 #define VIR_FROM_THIS VIR_FROM_RPC
 
@@ -55,6 +56,7 @@ struct _virNetClientStream {
     bool incomingEOF;
 
     bool skippable; /* User requested skippable stream */
+    unsigned long long skipLength;  /* Size of incoming hole in stream. */
 
     virNetClientStreamEventCallback cb;
     void *cbOpaque;
@@ -358,6 +360,67 @@ int virNetClientStreamSendPacket(virNetClientStreamPtr st,
     return -1;
 }
 
+
+static int ATTRIBUTE_UNUSED
+virNetClientStreamHandleSkip(virNetClientPtr client,
+                             virNetClientStreamPtr st)
+{
+    virNetMessagePtr msg;
+    virNetStreamSkip data;
+    int ret = -1;
+
+    VIR_DEBUG("client=%p st=%p", client, st);
+
+    msg = st->rx;
+    memset(&data, 0, sizeof(data));
+
+    /* We should not be called unless there's VIR_NET_STREAM_SKIP
+     * message at the head of the list. But doesn't hurt to check */
+    if (!msg) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("No message in the queue"));
+        goto cleanup;
+    }
+
+    if (msg->header.type != VIR_NET_STREAM_SKIP) {
+        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;
+    }
+
+    /* Server should not send us VIR_NET_STREAM_SKIP unless we
+     * have requested so. But does not hurt to check ... */
+    if (!st->skippable) {
+        virReportError(VIR_ERR_RPC, "%s",
+                       _("Unexpected stream skip"));
+        goto cleanup;
+    }
+
+    if (virNetMessageDecodePayload(msg,
+                                   (xdrproc_t) xdr_virNetStreamSkip,
+                                   &data) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Malformed stream skip packet"));
+        goto cleanup;
+    }
+
+    virNetMessageQueueServe(&st->rx);
+    virNetMessageFree(msg);
+    st->skipLength += data.length;
+
+    ret = 0;
+ cleanup:
+    if (ret < 0) {
+        /* Abort stream? */
+    }
+    return ret;
+}
+
+
 int virNetClientStreamRecvPacket(virNetClientStreamPtr st,
                                  virNetClientPtr client,
                                  char *data,
-- 
2.8.3


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]