From patchwork Wed Aug 26 13:19:17 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gerd Hoffmann X-Patchwork-Id: 32148 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 bilbo.ozlabs.org (Postfix) with ESMTPS id 558C9B70C4 for ; Wed, 26 Aug 2009 23:25:05 +1000 (EST) Received: from localhost ([127.0.0.1]:57594 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MgIUn-00049D-Is for incoming@patchwork.ozlabs.org; Wed, 26 Aug 2009 09:25:01 -0400 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1MgIPX-0001us-6l for qemu-devel@nongnu.org; Wed, 26 Aug 2009 09:19:35 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1MgIPR-0001qT-Lx for qemu-devel@nongnu.org; Wed, 26 Aug 2009 09:19:33 -0400 Received: from [199.232.76.173] (port=58188 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MgIPR-0001qH-8u for qemu-devel@nongnu.org; Wed, 26 Aug 2009 09:19:29 -0400 Received: from mx1.redhat.com ([209.132.183.28]:4913) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1MgIPQ-0004Z2-PO for qemu-devel@nongnu.org; Wed, 26 Aug 2009 09:19:29 -0400 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id n7QDJSej020063 for ; Wed, 26 Aug 2009 09:19:28 -0400 Received: from zweiblum.home.kraxel.org (vpn1-4-183.ams2.redhat.com [10.36.4.183]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with SMTP id n7QDJN76012314; Wed, 26 Aug 2009 09:19:24 -0400 Received: by zweiblum.home.kraxel.org (Postfix, from userid 500) id 7040A700D9; Wed, 26 Aug 2009 15:19:20 +0200 (CEST) From: Gerd Hoffmann To: qemu-devel@nongnu.org Date: Wed, 26 Aug 2009 15:19:17 +0200 Message-Id: <1251292759-32247-3-git-send-email-kraxel@redhat.com> In-Reply-To: <1251292759-32247-1-git-send-email-kraxel@redhat.com> References: <1251292759-32247-1-git-send-email-kraxel@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.12 X-detected-operating-system: by monty-python.gnu.org: Genre and OS details not recognized. Cc: Gerd Hoffmann Subject: [Qemu-devel] [PATCH 2/4] add qemu_error() + friends 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 This patch adds some functions for error reporting to address the problem that error messages should be routed to different destinations depending on the context of the caller, i.e. monitor command errors should go to the monitor, command line errors to stderr. qemu_error() is a printf-like function to report errors. qemu_errors_to_file() and qemu_errors_to_mon() switch the destination for the error message to the specified file or monitor. When setting a new destination the old one will be kept. One can switch back using qemu_errors_to_previous(). i.e. it works like a stack. main() calls qemu_errors_to_file(stderr), so errors go to stderr by default. monitor callbacks are wrapped into qemu_errors_to_mon() + qemu_errors_to_previous(), so any errors triggered by monitor commands will go to the monitor. Each thread has its own error message destination. qemu-kvm probably should add a qemu_errors_to_file(stderr) call to the i/o-thread initialization code. Signed-off-by: Gerd Hoffmann --- monitor.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- sysemu.h | 5 ++++ vl.c | 1 + 3 files changed, 76 insertions(+), 1 deletions(-) diff --git a/monitor.c b/monitor.c index 967171b..6f7c940 100644 --- a/monitor.c +++ b/monitor.c @@ -2782,6 +2782,7 @@ static void monitor_handle_command(Monitor *mon, const char *cmdline) goto fail; } + qemu_errors_to_mon(mon); switch(nb_args) { case 0: handler_0 = cmd->handler; @@ -2833,8 +2834,10 @@ static void monitor_handle_command(Monitor *mon, const char *cmdline) break; default: monitor_printf(mon, "unsupported number of arguments: %d\n", nb_args); - goto fail; + break; } + qemu_errors_to_previous(); + fail: for(i = 0; i < MAX_ARGS; i++) qemu_free(str_allocated[i]); @@ -3202,3 +3205,69 @@ void monitor_read_bdrv_key_start(Monitor *mon, BlockDriverState *bs, if (err && completion_cb) completion_cb(opaque, err); } + +typedef struct QemuErrorSink QemuErrorSink; +struct QemuErrorSink { + enum { + ERR_SINK_FILE, + ERR_SINK_MONITOR, + } dest; + union { + FILE *fp; + Monitor *mon; + }; + QemuErrorSink *previous; +}; + +static __thread QemuErrorSink *qemu_error_sink; + +void qemu_errors_to_file(FILE *fp) +{ + QemuErrorSink *sink; + + sink = qemu_mallocz(sizeof(*sink)); + sink->dest = ERR_SINK_FILE; + sink->fp = fp; + sink->previous = qemu_error_sink; + qemu_error_sink = sink; +} + +void qemu_errors_to_mon(Monitor *mon) +{ + QemuErrorSink *sink; + + sink = qemu_mallocz(sizeof(*sink)); + sink->dest = ERR_SINK_MONITOR; + sink->mon = mon; + sink->previous = qemu_error_sink; + qemu_error_sink = sink; +} + +void qemu_errors_to_previous(void) +{ + QemuErrorSink *sink; + + assert(qemu_error_sink != NULL); + sink = qemu_error_sink; + qemu_error_sink = sink->previous; + qemu_free(sink); +} + +void qemu_error(const char *fmt, ...) +{ + va_list args; + + assert(qemu_error_sink != NULL); + switch (qemu_error_sink->dest) { + case ERR_SINK_FILE: + va_start(args, fmt); + vfprintf(qemu_error_sink->fp, fmt, args); + va_end(args); + break; + case ERR_SINK_MONITOR: + va_start(args, fmt); + monitor_vprintf(qemu_error_sink->mon, fmt, args); + va_end(args); + break; + } +} diff --git a/sysemu.h b/sysemu.h index 1df0872..eaf7f58 100644 --- a/sysemu.h +++ b/sysemu.h @@ -65,6 +65,11 @@ int qemu_savevm_state_complete(QEMUFile *f); int qemu_savevm_state(QEMUFile *f); int qemu_loadvm_state(QEMUFile *f); +void qemu_errors_to_file(FILE *fp); +void qemu_errors_to_mon(Monitor *mon); +void qemu_errors_to_previous(void); +void qemu_error(const char *fmt, ...) __attribute__ ((format(printf, 1, 2))); + #ifdef _WIN32 /* Polling handling */ diff --git a/vl.c b/vl.c index c164f45..7bbd273 100644 --- a/vl.c +++ b/vl.c @@ -4801,6 +4801,7 @@ int main(int argc, char **argv, char **envp) CPUState *env; int show_vnc_port = 0; + qemu_errors_to_file(stderr); qemu_cache_utils_init(envp); LIST_INIT (&vm_change_state_head);