From patchwork Thu Mar 4 15:56:49 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 46958 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id F0852B6ED0 for ; Fri, 5 Mar 2010 04:30:03 +1100 (EST) Received: from localhost ([127.0.0.1]:44556 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NnEs3-0005TF-Bg for incoming@patchwork.ozlabs.org; Thu, 04 Mar 2010 12:29:59 -0500 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1NnDXe-0005kk-St for qemu-devel@nongnu.org; Thu, 04 Mar 2010 11:04:51 -0500 Received: from [199.232.76.173] (port=58592 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NnDXd-0005kF-PW for qemu-devel@nongnu.org; Thu, 04 Mar 2010 11:04:49 -0500 Received: from Debian-exim by monty-python.gnu.org with spam-scanned (Exim 4.60) (envelope-from ) id 1NnDXO-0001Pt-MM for qemu-devel@nongnu.org; Thu, 04 Mar 2010 11:04:48 -0500 Received: from oxygen.pond.sub.org ([213.239.205.148]:47483) by monty-python.gnu.org with esmtps (TLS-1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1NnDXM-0001Ol-PG for qemu-devel@nongnu.org; Thu, 04 Mar 2010 11:04:33 -0500 Received: from blackfin.pond.sub.org (pD9E38041.dip.t-dialin.net [217.227.128.65]) by oxygen.pond.sub.org (Postfix) with ESMTPA id EC696276DA7 for ; Thu, 4 Mar 2010 17:04:29 +0100 (CET) Received: by blackfin.pond.sub.org (Postfix, from userid 500) id B962116E; Thu, 4 Mar 2010 16:57:13 +0100 (CET) From: Markus Armbruster To: qemu-devel@nongnu.org Date: Thu, 4 Mar 2010 16:56:49 +0100 Message-Id: <1267718231-13303-29-git-send-email-armbru@redhat.com> X-Mailer: git-send-email 1.6.6.1 In-Reply-To: <1267718231-13303-1-git-send-email-armbru@redhat.com> References: <1267718231-13303-1-git-send-email-armbru@redhat.com> X-detected-operating-system: by monty-python.gnu.org: GNU/Linux 2.6 (newer, 3) Cc: Luiz Capitulino Subject: [Qemu-devel] [PATCH 28/50] error: Let converted handlers print in human monitor X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org While fully converted handlers are not supposed to print anything when running in a QMP monitor, they are free to print in a human monitor. For instance, device_add (not yet converted) prints help, and will continue to do so after conversion. Moreover, utility functions converted to QError should remain usable from unconverted handlers. Two problems: * handler_audit() complains when a converted handler prints. Limit that to QMP monitors. * With QMP, handlers need to pass the error object by way of monitor_set_error(). However, we do that both for QMP and for the human monitor. The human monitor prints the error object after the handler returns. If the handler prints anything else, that output "overtakes" the error message. Limit use of monitor_set_error() to QMP monitors. Update handler_audit() accordingly. Signed-off-by: Markus Armbruster --- monitor.c | 80 ++++++++++++++++++++++++++------------------------------- qemu-error.c | 2 +- 2 files changed, 38 insertions(+), 44 deletions(-) diff --git a/monitor.c b/monitor.c index 3580d37..dfeb9db 100644 --- a/monitor.c +++ b/monitor.c @@ -3873,13 +3873,6 @@ void monitor_set_error(Monitor *mon, QError *qerror) } } -static void monitor_print_error(Monitor *mon) -{ - qerror_print(mon->error); - QDECREF(mon->error); - mon->error = NULL; -} - static int is_async_return(const QObject *data) { if (data && qobject_type(data) == QTYPE_QDICT) { @@ -3891,45 +3884,49 @@ static int is_async_return(const QObject *data) static void handler_audit(Monitor *mon, const mon_cmd_t *cmd, int ret) { - if (ret && !monitor_has_error(mon)) { - /* - * If it returns failure, it must have passed on error. - * - * Action: Report an internal error to the client if in QMP. - */ - if (monitor_ctrl_mode(mon)) { + if (monitor_ctrl_mode(mon)) { + if (ret && !monitor_has_error(mon)) { + /* + * If it returns failure, it must have passed on error. + * + * Action: Report an internal error to the client if in QMP. + */ qerror_report(QERR_UNDEFINED_ERROR); + MON_DEBUG("command '%s' returned failure but did not pass an error\n", + cmd->name); } - MON_DEBUG("command '%s' returned failure but did not pass an error\n", - cmd->name); - } #ifdef CONFIG_DEBUG_MONITOR - if (!ret && monitor_has_error(mon)) { - /* - * If it returns success, it must not have passed an error. - * - * Action: Report the passed error to the client. - */ - MON_DEBUG("command '%s' returned success but passed an error\n", - cmd->name); - } + if (!ret && monitor_has_error(mon)) { + /* + * If it returns success, it must not have passed an error. + * + * Action: Report the passed error to the client. + */ + MON_DEBUG("command '%s' returned success but passed an error\n", + cmd->name); + } - if (mon_print_count_get(mon) > 0 && strcmp(cmd->name, "info") != 0) { - /* - * Handlers should not call Monitor print functions. - * - * Action: Ignore them in QMP. - * - * (XXX: we don't check any 'info' or 'query' command here - * because the user print function _is_ called by do_info(), hence - * we will trigger this check. This problem will go away when we - * make 'query' commands real and kill do_info()) - */ - MON_DEBUG("command '%s' called print functions %d time(s)\n", - cmd->name, mon_print_count_get(mon)); - } + if (mon_print_count_get(mon) > 0 && strcmp(cmd->name, "info") != 0) { + /* + * Handlers should not call Monitor print functions. + * + * Action: Ignore them in QMP. + * + * (XXX: we don't check any 'info' or 'query' command here + * because the user print function _is_ called by do_info(), hence + * we will trigger this check. This problem will go away when we + * make 'query' commands real and kill do_info()) + */ + MON_DEBUG("command '%s' called print functions %d time(s)\n", + cmd->name, mon_print_count_get(mon)); + } #endif + } else { + assert(!monitor_has_error(mon)); + QDECREF(mon->error); + mon->error = NULL; + } } static void monitor_call_handler(Monitor *mon, const mon_cmd_t *cmd, @@ -3982,9 +3979,6 @@ static void handle_user_command(Monitor *mon, const char *cmdline) cmd->mhandler.cmd(mon, qdict); } - if (monitor_has_error(mon)) - monitor_print_error(mon); - out: QDECREF(qdict); } diff --git a/qemu-error.c b/qemu-error.c index 5be6bea..a8c178b 100644 --- a/qemu-error.c +++ b/qemu-error.c @@ -207,7 +207,7 @@ void qerror_report_internal(const char *file, int linenr, const char *func, qerror = qerror_from_info(file, linenr, func, fmt, &va); va_end(va); - if (cur_mon) { + if (monitor_cur_is_qmp()) { monitor_set_error(cur_mon, qerror); } else { qerror_print(qerror);