[libvirt] [PATCH 2/4] Try harder to send RPC error message back to client

Daniel P. Berrange berrange at redhat.com
Tue Aug 17 16:00:24 UTC 2010


When failing to serialize the normal RPC reply, try harder to
send a error message back to the client, instead of immediately
closing the connection.

* daemon/dispatch.c: Improve error messages when RPC reply
  can not be sent
---
 daemon/dispatch.c |   45 ++++++++++++++++++++++++++++-----------------
 1 files changed, 28 insertions(+), 17 deletions(-)

diff --git a/daemon/dispatch.c b/daemon/dispatch.c
index 9d1abc0..a24c811 100644
--- a/daemon/dispatch.c
+++ b/daemon/dispatch.c
@@ -527,7 +527,8 @@ remoteDispatchClientCall (struct qemud_server *server,
 
     if (remoteEncodeClientMessageHeader(msg) < 0) {
         xdr_free (data->ret_filter, (char*)&ret);
-        goto fatal_error;
+        remoteDispatchFormatError(&rerr, "%s", _("failed to serialize reply header"));
+        goto xdr_hdr_error;
     }
 
 
@@ -537,22 +538,30 @@ remoteDispatchClientCall (struct qemud_server *server,
                    msg->bufferLength,
                    XDR_ENCODE);
 
-    if (xdr_setpos(&xdr, msg->bufferOffset) == 0)
+    if (xdr_setpos(&xdr, msg->bufferOffset) == 0) {
+        remoteDispatchFormatError(&rerr, "%s", _("failed to change XDR reply offset"));
         goto xdr_error;
+    }
 
     /* If OK, serialise return structure, if error serialise error. */
     /* Serialise reply data */
-    if (!((data->ret_filter) (&xdr, &ret)))
+    if (!((data->ret_filter) (&xdr, &ret))) {
+        remoteDispatchFormatError(&rerr, "%s", _("failed to serialize reply payload (probable message size limit)"));
         goto xdr_error;
+    }
 
     /* Update the length word. */
     msg->bufferOffset += xdr_getpos (&xdr);
     len = msg->bufferOffset;
-    if (xdr_setpos (&xdr, 0) == 0)
+    if (xdr_setpos (&xdr, 0) == 0) {
+        remoteDispatchFormatError(&rerr, "%s", _("failed to change XDR reply offset"));
         goto xdr_error;
+    }
 
-    if (!xdr_u_int (&xdr, &len))
+    if (!xdr_u_int (&xdr, &len)) {
+        remoteDispatchFormatError(&rerr, "%s", _("failed to update reply length header"));
         goto xdr_error;
+    }
 
     xdr_destroy (&xdr);
     xdr_free (data->ret_filter, (char*)&ret);
@@ -567,25 +576,27 @@ remoteDispatchClientCall (struct qemud_server *server,
 
     return 0;
 
+xdr_error:
+    /* Bad stuff serializing reply. Try to send a little info
+     * back to client to assist in bug reporting/diagnosis */
+    xdr_free (data->ret_filter, (char*)&ret);
+    xdr_destroy (&xdr);
+    /* fallthrough */
+
+xdr_hdr_error:
+    VIR_WARN("Failed to serialize reply for program '%d' proc '%d' as XDR",
+             msg->hdr.prog, msg->hdr.proc);
+    /* fallthrough */
+
 rpc_error:
-    /* Semi-bad stuff happened, we can still try to send back
-     * an RPC error message to client */
+    /* Bad stuff (de-)serializing message, but we have an
+     * RPC error message we can send back to the client */
     rv = remoteSerializeReplyError(client, &rerr, &msg->hdr);
 
     if (rv >= 0)
         VIR_FREE(msg);
 
     return rv;
-
-xdr_error:
-    /* Seriously bad stuff happened, so we'll kill off this client
-       and not send back any RPC error */
-    xdr_free (data->ret_filter, (char*)&ret);
-    xdr_destroy (&xdr);
-fatal_error:
-    VIR_WARN("Failed to serialize reply for program '%d' proc '%d' as XDR",
-             msg->hdr.prog, msg->hdr.proc);
-    return -1;
 }
 
 
-- 
1.7.2.1




More information about the libvir-list mailing list