]> xenbits.xensource.com Git - libvirt.git/commitdiff
Try harder to send RPC error message back to client
authorDaniel P. Berrange <berrange@redhat.com>
Tue, 17 Aug 2010 14:31:51 +0000 (10:31 -0400)
committerDaniel P. Berrange <berrange@redhat.com>
Tue, 24 Aug 2010 13:19:05 +0000 (14:19 +0100)
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

index da810e2241ceb4f10b0e6526a31735e8f938392f..97316144a6d0bab461503dbc47a44f5855054ecb 100644 (file)
@@ -548,7 +548,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;
     }
 
 
@@ -558,22 +559,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);
@@ -588,25 +597,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;
 }