[libvirt] [PATCH 3/9] Separate code for encoding outgoing remote message headers

Daniel P. Berrange berrange at redhat.com
Tue Jul 14 10:18:23 UTC 2009


Introduces an API for encoding the header field for outgoing messages
allowing some duplicated code to be eliminated

* qemud/dispatch.c, qemud/dispatch.h: add remoteEncodeClientMessageHeader
  for encoding message header. Update remoteDispatchClientRequest to
  use this method.
* qemud/remote.c: Update remoteDispatchDomainEventSend to use the
  generic remoteEncodeClientMessageHeader() for encoding event
  message hedaders. Push some logic from remoteRelayDomainEvent
  down into remoteDispatchDomainEventSend.

Signed-off-by: Daniel P. Berrange <berrange at redhat.com>
---
 qemud/dispatch.c |   99 +++++++++++++++++++++++++++++++++++++++++++----------
 qemud/dispatch.h |    2 +
 qemud/remote.c   |   79 ++++++++++++++++++-------------------------
 3 files changed, 115 insertions(+), 65 deletions(-)

diff --git a/qemud/dispatch.c b/qemud/dispatch.c
index 127f93b..29970e4 100644
--- a/qemud/dispatch.c
+++ b/qemud/dispatch.c
@@ -127,7 +127,10 @@ void remoteDispatchConnError (remote_error *rerr,
  * @msg: the complete incoming message, whose header to decode
  *
  * Decodes the header part of the client message, but does not
- * validate the decoded fields in the header.
+ * validate the decoded fields in the header. It expects
+ * bufferLength to refer to length of the data packet. Upon
+ * return bufferOffset will refer to the amount of the packet
+ * consumed by decoding of the header.
  *
  * returns 0 if successfully decoded, -1 upon fatal error
  */
@@ -159,6 +162,61 @@ cleanup:
 
 
 /*
+ * @msg: the outgoing message, whose header to encode
+ *
+ * Encodes the header part of the client message, setting the
+ * message offset ready to encode the payload. Leaves space
+ * for the length field later. Upon return bufferLength will
+ * refer to the total available space for message, while
+ * bufferOffset will refer to current space used by header
+ *
+ * returns 0 if successfully encoded, -1 upon fatal error
+ */
+int
+remoteEncodeClientMessageHeader (struct qemud_client_message *msg)
+{
+    XDR xdr;
+    int ret = -1;
+    unsigned int len = 0;
+
+    msg->bufferLength = sizeof(msg->buffer);
+    msg->bufferOffset = 0;
+
+    /* Format the header. */
+    xdrmem_create (&xdr,
+                   msg->buffer,
+                   msg->bufferLength,
+                   XDR_ENCODE);
+
+    /* The real value is filled in shortly */
+    if (!xdr_u_int (&xdr, &len)) {
+        goto cleanup;
+    }
+
+    if (!xdr_remote_message_header (&xdr, &msg->hdr))
+        goto cleanup;
+
+    len = xdr_getpos(&xdr);
+    xdr_setpos(&xdr, 0);
+
+    /* Fill in current length - may be re-written later
+     * if a payload is added
+     */
+    if (!xdr_u_int (&xdr, &len)) {
+        goto cleanup;
+    }
+
+    msg->bufferOffset += len;
+
+    ret = 0;
+
+cleanup:
+    xdr_destroy(&xdr);
+    return ret;
+}
+
+
+/*
  * @server: the unlocked server object
  * @client: the locked client object
  * @msg: the complete incoming message packet, with header already decoded
@@ -177,7 +235,6 @@ remoteDispatchClientRequest (struct qemud_server *server,
                              struct qemud_client_message *msg)
 {
     XDR xdr;
-    remote_message_header rep;
     remote_error rerr;
     dispatch_args args;
     dispatch_ret ret;
@@ -277,27 +334,29 @@ remoteDispatchClientRequest (struct qemud_server *server,
 
 rpc_error:
 
-    /* Return header. */
-    rep.prog = msg->hdr.prog;
-    rep.vers = msg->hdr.vers;
-    rep.proc = msg->hdr.proc;
-    rep.direction = REMOTE_REPLY;
-    rep.serial = msg->hdr.serial;
-    rep.status = rv < 0 ? REMOTE_ERROR : REMOTE_OK;
+    /* Return header. We're re-using same message object, so
+     * only need to tweak direction/status fields */
+    /*msg->hdr.prog = msg->hdr.prog;*/
+    /*msg->hdr.vers = msg->hdr.vers;*/
+    /*msg->hdr.proc = msg->hdr.proc;*/
+    msg->hdr.direction = REMOTE_REPLY;
+    /*msg->hdr.serial = msg->hdr.serial;*/
+    msg->hdr.status = rv < 0 ? REMOTE_ERROR : REMOTE_OK;
 
-    /* Serialise the return header. */
-    xdrmem_create (&xdr, msg->buffer, sizeof msg->buffer, XDR_ENCODE);
-
-    len = 0; /* We'll come back and write this later. */
-    if (!xdr_u_int (&xdr, &len)) {
+    if (remoteEncodeClientMessageHeader(msg) < 0) {
         if (rv == 0) xdr_free (data->ret_filter, (char*)&ret);
         goto fatal_error;
     }
 
-    if (!xdr_remote_message_header (&xdr, &rep)) {
-        if (rv == 0) xdr_free (data->ret_filter, (char*)&ret);
+
+    /* Now for the payload */
+    xdrmem_create (&xdr,
+                   msg->buffer,
+                   msg->bufferLength,
+                   XDR_ENCODE);
+
+    if (xdr_setpos(&xdr, msg->bufferOffset) == 0)
         goto fatal_error;
-    }
 
     /* If OK, serialise return structure, if error serialise error. */
     if (rv >= 0) {
@@ -313,8 +372,9 @@ rpc_error:
         xdr_free((xdrproc_t)xdr_remote_error,  (char *)&rerr);
     }
 
-    /* Write the length word. */
-    len = xdr_getpos (&xdr);
+    /* Update the length word. */
+    msg->bufferOffset += xdr_getpos (&xdr);
+    len = msg->bufferOffset;
     if (xdr_setpos (&xdr, 0) == 0)
         goto fatal_error;
 
@@ -323,6 +383,7 @@ rpc_error:
 
     xdr_destroy (&xdr);
 
+    /* Reset ready for I/O */
     msg->bufferLength = len;
     msg->bufferOffset = 0;
 
diff --git a/qemud/dispatch.h b/qemud/dispatch.h
index db372f1..ab45b19 100644
--- a/qemud/dispatch.h
+++ b/qemud/dispatch.h
@@ -30,6 +30,8 @@
 
 int
 remoteDecodeClientMessageHeader (struct qemud_client_message *req);
+int
+remoteEncodeClientMessageHeader (struct qemud_client_message *req);
 
 int
 remoteDispatchClientRequest (struct qemud_server *server,
diff --git a/qemud/remote.c b/qemud/remote.c
index d0bc677..fb06dc3 100644
--- a/qemud/remote.c
+++ b/qemud/remote.c
@@ -91,7 +91,6 @@ const dispatch_data const *remoteGetDispatchData(int proc)
 /* Prototypes */
 static void
 remoteDispatchDomainEventSend (struct qemud_client *client,
-                               struct qemud_client_message *msg,
                                virDomainPtr dom,
                                int event,
                                int detail);
@@ -108,14 +107,9 @@ int remoteRelayDomainEvent (virConnectPtr conn ATTRIBUTE_UNUSED,
     REMOTE_DEBUG("Relaying domain event %d %d", event, detail);
 
     if (client) {
-        struct qemud_client_message *ev;
-
-        if (VIR_ALLOC(ev) < 0)
-            return -1;
-
         virMutexLock(&client->lock);
 
-        remoteDispatchDomainEventSend (client, ev, dom, event, detail);
+        remoteDispatchDomainEventSend (client, dom, event, detail);
 
         if (qemudRegisterClientEvent(client->server, client, 1) < 0)
             qemudDispatchClientFailure(client);
@@ -4433,72 +4427,65 @@ remoteDispatchDomainEventsDeregister (struct qemud_server *server ATTRIBUTE_UNUS
 
 static void
 remoteDispatchDomainEventSend (struct qemud_client *client,
-                               struct qemud_client_message *msg,
                                virDomainPtr dom,
                                int event,
                                int detail)
 {
-    remote_message_header rep;
+    struct qemud_client_message *msg = NULL;
     XDR xdr;
     unsigned int len;
     remote_domain_event_ret data;
 
-    if (!client)
+    if (VIR_ALLOC(msg) < 0)
         return;
 
-    rep.prog = REMOTE_PROGRAM;
-    rep.vers = REMOTE_PROTOCOL_VERSION;
-    rep.proc = REMOTE_PROC_DOMAIN_EVENT;
-    rep.direction = REMOTE_MESSAGE;
-    rep.serial = 1;
-    rep.status = REMOTE_OK;
+    msg->hdr.prog = REMOTE_PROGRAM;
+    msg->hdr.vers = REMOTE_PROTOCOL_VERSION;
+    msg->hdr.proc = REMOTE_PROC_DOMAIN_EVENT;
+    msg->hdr.direction = REMOTE_MESSAGE;
+    msg->hdr.serial = 1;
+    msg->hdr.status = REMOTE_OK;
 
-    /* Serialise the return header and event. */
-    xdrmem_create (&xdr, msg->buffer, sizeof msg->buffer, XDR_ENCODE);
-
-    len = 0; /* We'll come back and write this later. */
-    if (!xdr_u_int (&xdr, &len)) {
-        /*remoteDispatchError (client, NULL, "%s", _("xdr_u_int failed (1)"));*/
-        xdr_destroy (&xdr);
-        return;
-    }
+    if (remoteEncodeClientMessageHeader(msg) < 0)
+        goto error;
 
-    if (!xdr_remote_message_header (&xdr, &rep)) {
-        xdr_destroy (&xdr);
-        return;
-    }
+    /* Serialise the return header and event. */
+    xdrmem_create (&xdr,
+                   msg->buffer + msg->bufferOffset,
+                   msg->bufferLength - msg->bufferOffset,
+                   XDR_ENCODE);
 
     /* build return data */
     make_nonnull_domain (&data.dom, dom);
     data.event = event;
     data.detail = detail;
 
-    if (!xdr_remote_domain_event_ret(&xdr, &data)) {
-        /*remoteDispatchError (client, NULL, "%s", _("serialise return struct"));*/
-        xdr_destroy (&xdr);
-        return;
-    }
+    if (!xdr_remote_domain_event_ret(&xdr, &data))
+        goto xdr_error;
 
-    len = xdr_getpos (&xdr);
-    if (xdr_setpos (&xdr, 0) == 0) {
-        /*remoteDispatchError (client, NULL, "%s", _("xdr_setpos failed"));*/
-        xdr_destroy (&xdr);
-        return;
-    }
 
-    if (!xdr_u_int (&xdr, &len)) {
-        /*remoteDispatchError (client, NULL, "%s", _("xdr_u_int failed (2)"));*/
-        xdr_destroy (&xdr);
-        return;
-    }
+    /* Update length word */
+    msg->bufferOffset += xdr_getpos (&xdr);
+    len = msg->bufferOffset;
+    if (xdr_setpos (&xdr, 0) == 0)
+        goto xdr_error;
 
-    xdr_destroy (&xdr);
+    if (!xdr_u_int (&xdr, &len))
+        goto xdr_error;
 
     /* Send it. */
     msg->async = 1;
     msg->bufferLength = len;
     msg->bufferOffset = 0;
     qemudClientMessageQueuePush(&client->tx, msg);
+
+    xdr_destroy (&xdr);
+    return;
+
+xdr_error:
+    xdr_destroy(&xdr);
+error:
+    VIR_FREE(msg);
 }
 
 /*----- Helpers. -----*/
-- 
1.6.2.5


-- 
|: Red Hat, Engineering, London   -o-   http://people.redhat.com/berrange/ :|
|: http://libvirt.org  -o-  http://virt-manager.org  -o-  http://ovirt.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505  -o-  F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|




More information about the libvir-list mailing list