From f84c1660131e8111fd2aaac2e298f57b31285250 Mon Sep 17 00:00:00 2001 From: John Levon Date: Mon, 9 Feb 2009 14:24:06 +0000 Subject: [PATCH] Improve error reporting in virsh --- ChangeLog | 5 +++++ src/virsh.c | 59 ++++++++++++++++++++++++++++++++++++++--------------- 2 files changed, 48 insertions(+), 16 deletions(-) diff --git a/ChangeLog b/ChangeLog index 917b1fd6f5..413d21629a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Mon Feb 9 14:19:02 GMT 2009 John Levon + + * src/virsh.c: rather than verbosely printing every error, save + the last error and report that only if the entire command fails. + Mon Feb 9 14:07:51 GMT 2009 John Levon * include/libvirt/virterror.h: diff --git a/src/virsh.c b/src/virsh.c index ad2dae06e6..57bd3969eb 100644 --- a/src/virsh.c +++ b/src/virsh.c @@ -92,22 +92,6 @@ typedef enum { VSH_ERR_ERROR } vshErrorLevel; -/* - * The error handler for virsh - */ -static void -virshErrorHandler(void *unused, virErrorPtr error) -{ - if ((unused != NULL) || (error == NULL)) - return; - - /* Suppress the VIR_ERR_NO_XEN error which fails as non-root */ - if ((error->code == VIR_ERR_NO_XEN) || (error->code == VIR_ERR_OK)) - return; - - virDefaultErrorFunc(error); -} - /* * virsh command line grammar: * @@ -321,6 +305,46 @@ static int namesorter(const void *a, const void *b) { return strcasecmp(*sa, *sb); } +static virErrorPtr last_error; + +/* + * Quieten libvirt until we're done with the command. + */ +static void +virshErrorHandler(void *unused ATTRIBUTE_UNUSED, virErrorPtr error) +{ + virFreeError(last_error); + last_error = virSaveLastError(); + if (getenv("VIRSH_DEBUG") != NULL) + virDefaultErrorFunc(error); +} + +/* + * Report an error when a command finishes. This is better than before + * (when correct operation would report errors), but it has some + * problems: we lose the smarter formatting of virDefaultErrorFunc(), + * and it can become harder to debug problems, if errors get reported + * twice during one command. This case shouldn't really happen anyway, + * and it's IMHO a bug that libvirt does that sometimes. + */ +static void +virshReportError(vshControl *ctl) +{ + if (last_error == NULL) + return; + + if (last_error->code == VIR_ERR_OK) { + vshError(ctl, FALSE, "%s", _("unknown error")); + goto out; + } + + vshError(ctl, FALSE, "%s", last_error->message); + +out: + virFreeError(last_error); + last_error = NULL; +} + /* --------------- * Commands @@ -6103,6 +6127,9 @@ vshCommandRun(vshControl *ctl, const vshCmd *cmd) if (ctl->timing) GETTIMEOFDAY(&after); + if (ret == FALSE) + virshReportError(ctl); + if (STREQ(cmd->def->name, "quit")) /* hack ... */ return ret;