mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-25 01:34:11 +03:00
Try harder to send RPC error message back to client
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
This commit is contained in:
parent
677c834ca7
commit
97d982a748
@ -548,7 +548,8 @@ remoteDispatchClientCall (struct qemud_server *server,
|
|||||||
|
|
||||||
if (remoteEncodeClientMessageHeader(msg) < 0) {
|
if (remoteEncodeClientMessageHeader(msg) < 0) {
|
||||||
xdr_free (data->ret_filter, (char*)&ret);
|
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,
|
msg->bufferLength,
|
||||||
XDR_ENCODE);
|
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;
|
goto xdr_error;
|
||||||
|
}
|
||||||
|
|
||||||
/* If OK, serialise return structure, if error serialise error. */
|
/* If OK, serialise return structure, if error serialise error. */
|
||||||
/* Serialise reply data */
|
/* 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;
|
goto xdr_error;
|
||||||
|
}
|
||||||
|
|
||||||
/* Update the length word. */
|
/* Update the length word. */
|
||||||
msg->bufferOffset += xdr_getpos (&xdr);
|
msg->bufferOffset += xdr_getpos (&xdr);
|
||||||
len = msg->bufferOffset;
|
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;
|
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;
|
goto xdr_error;
|
||||||
|
}
|
||||||
|
|
||||||
xdr_destroy (&xdr);
|
xdr_destroy (&xdr);
|
||||||
xdr_free (data->ret_filter, (char*)&ret);
|
xdr_free (data->ret_filter, (char*)&ret);
|
||||||
@ -588,25 +597,27 @@ remoteDispatchClientCall (struct qemud_server *server,
|
|||||||
|
|
||||||
return 0;
|
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:
|
rpc_error:
|
||||||
/* Semi-bad stuff happened, we can still try to send back
|
/* Bad stuff (de-)serializing message, but we have an
|
||||||
* an RPC error message to client */
|
* RPC error message we can send back to the client */
|
||||||
rv = remoteSerializeReplyError(client, &rerr, &msg->hdr);
|
rv = remoteSerializeReplyError(client, &rerr, &msg->hdr);
|
||||||
|
|
||||||
if (rv >= 0)
|
if (rv >= 0)
|
||||||
VIR_FREE(msg);
|
VIR_FREE(msg);
|
||||||
|
|
||||||
return rv;
|
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user