[libvirt] PATCH: Pass 'remote_error' object to RPC handlers
Daniel Veillard
veillard at redhat.com
Mon Oct 20 14:38:52 UTC 2008
On Fri, Oct 17, 2008 at 12:27:52PM +0100, Daniel P. Berrange wrote:
> In the libvirtd daemon, remote.c file the current RPC handlers have
> a return value contract saying
>
> 0 - success
> -1 - failure in libvirt call, no error returned
> -2 - failure in dispatch process, error already serialized & sent
>
> While this isn't a problem for the code as it stands today, for the thread
> support I want to be able to avoid the dispatch handlers having to touch
> the 'struct qemud_client' object in normal usage. Allowing the RPC
> handlers to directly serialize & send the error makes this impossible
> because it requires access to the client object.
>
> So this patch changes the way the RPC handlers deal with errors. The
> RPC handler API changes from
>
> typedef int (*dispatch_fn) (struct qemud_server *server,
> struct qemud_client *client,
> dispatch_args *args,
> dispatch_ret *ret);
>
> To
>
> typedef int (*dispatch_fn) (struct qemud_server *server,
> struct qemud_client *client,
> remote_error *err,
> dispatch_args *args,
> dispatch_ret *ret);
>
> Note, the addition of a 'remote_error *err' argument. Whenever an error
> occurs during the dispatch process, the RPC handler must populate this
> 'remote_error *err' object with the error details. This rule applies
> whether its a libvirt error, or a dispatch process error, so there is
> no longer any need to have separate -1 or -2 return values, a simple
> -1 or 0 return value suffices.
Sounds fine,
> @@ -1381,7 +1380,14 @@ static void qemudDispatchClientRead(stru
> if (client->bufferOffset < client->bufferLength)
> return; /* Not read enough */
>
> - remoteDispatchClientRequest (server, client);
> + if ((len = remoteDispatchClientRequest (server, client)) == 0)
> + qemudDispatchClientFailure(server, client);
Shouldn't you return here instead of continuing ?
> +
> + /* Set up the output buffer. */
> + client->mode = QEMUD_MODE_TX_PACKET;
> + client->bufferLength = len;
> + client->bufferOffset = 0;
> +
> if (qemudRegisterClientEvent(server, client, 1) < 0)
> qemudDispatchClientFailure(server, client);
>
[...]
> +static void
> +remoteDispatchFormatError (remote_error *rerr,
> + const char *fmt, ...)
> +{
> + va_list args;
> + char msgbuf[1024];
> + char *msg = msgbuf;
> +
> + va_start (args, fmt);
> + vsnprintf (msgbuf, sizeof msgbuf, fmt, args);
> + va_end (args);
> +
> + remoteDispatchStringError (rerr, VIR_ERR_RPC, msg);
> +}
Really no way we would get more than 1024 bytes ? The problem is that
if this happens it's usually a stack being printed and the useful info
can be at the end.
[...]
> - remoteDispatchError (client, &req,
> - _("program mismatch (actual %x, expected %x)"),
> - req.prog, REMOTE_PROGRAM);
> - xdr_destroy (&xdr);
> - return;
> + remoteDispatchFormatError (&rerr,
> + _("program mismatch (actual %x, expected %x)"),
> + req.prog, REMOTE_PROGRAM);
stylistic issue, indenting to the opening ( is nice but can exceed the
80 columns rule, I usually prefer dropping the ( alignment to fit in.
> @@ -1395,6 +1368,7 @@ remoteDispatchDomainMigratePrepare (stru
> args->flags, dname, args->resource);
> if (r == -1) {
maybe if (r < 0) { as a mor generic error catching instruction
> VIR_FREE(uri_out);
> + remoteDispatchConnError(rerr, client->conn);
> return -1;
> }
>
> @@ -1439,7 +1413,10 @@ remoteDispatchDomainMigratePerform (stru
> args->uri,
> args->flags, dname, args->resource);
> virDomainFree (dom);
> - if (r == -1) return -1;
> + if (r == -1) {
Same thing, we didn't defined virDrvDomainMigratePerform error code
so maybe it's better to be generic
[...]
> @@ -482,8 +482,12 @@ void virDomainRemoveInactive(virDomainOb
> memmove(doms->objs + i, doms->objs + i + 1,
> sizeof(*(doms->objs)) * (doms->count - (i + 1)));
>
> - if (VIR_REALLOC_N(doms->objs, doms->count - 1) < 0) {
> - ; /* Failure to reduce memory allocation isn't fatal */
> + if (doms->count > 1) {
> + if (VIR_REALLOC_N(doms->objs, doms->count - 1) < 0) {
> + ; /* Failure to reduce memory allocation isn't fatal */
> + }
> + } else {
> + VIR_FREE(doms->objs);
> }
> doms->count--;
Like this there is a couple case where new error handling blocks have
been added, but after having reviewed the full patch I really could not
find anything suspicious. Since arguments of functions have been changed
I don't think one could miss one function lacking the change.
The only suggestion I would have is that there is a number of cases
where we test the error by checking against a -1 return value after
calling the API, maybe it's safer to just check for < 0 . But really as
if this looks okay (but that was long !)
thanks, there is clearly many cases where propagating the real error
will really improve debugging problems !
Daniel
--
Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/
daniel at veillard.com | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library http://libvirt.org/
More information about the libvir-list
mailing list