Patchwork [3/7] monitor: QError support

login
register
mail settings
Submitter Luiz Capitulino
Date Oct. 29, 2009, 6:42 p.m.
Message ID <1256841750-15228-4-git-send-email-lcapitulino@redhat.com>
Download mbox | patch
Permalink /patch/37219/
State New
Headers show

Comments

Luiz Capitulino - Oct. 29, 2009, 6:42 p.m.
This commit paves the way for QError support in the Monitor,
it adds a QError member to the Monitor struct and functions
to check and print it.

Additionally, it introduces qemu_error_structed() which should
be used by monitor handlers which report errors.

This new function has to be used in place of qemu_error(), which
will become private when all the conversion is done.

Basically, the Monitor's error flow is something like this:

1. An error happens in the handler, it calls qemu_error_structed()
2. qemu_error_structed() builds a new QError object and stores it in
   the Monitor struct
3. The handler returns
4. Top level Monitor code checks the Monitor struct and calls
   qerror_print() to print the error

When in protocol mode, step 4 will use the specified QError to
build a protocol error response, intead of calling qerror_print().

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
 monitor.c |   43 ++++++++++++++++++++++++++++++++++++++++++-
 sysemu.h  |    7 +++++++
 2 files changed, 49 insertions(+), 1 deletions(-)

Patch

diff --git a/monitor.c b/monitor.c
index 109ff5c..4d56b8e 100644
--- a/monitor.c
+++ b/monitor.c
@@ -49,6 +49,7 @@ 
 #include "qlist.h"
 #include "qdict.h"
 #include "qstring.h"
+#include "qerror.h"
 
 //#define DEBUG
 //#define DEBUG_COMPLETION
@@ -103,6 +104,7 @@  struct Monitor {
     CPUState *mon_cpu;
     BlockDriverCompletionFunc *password_completion_cb;
     void *password_opaque;
+    QError *error;
     QLIST_HEAD(,mon_fd_t) fds;
     QLIST_ENTRY(Monitor) entry;
 };
@@ -3146,6 +3148,18 @@  fail:
     return NULL;
 }
 
+static inline int monitor_has_error(const Monitor *mon)
+{
+    return mon->error != NULL;
+}
+
+static void monitor_print_error(Monitor *mon)
+{
+    qerror_print(mon->error);
+    QDECREF(mon->error);
+    mon->error = NULL;
+}
+
 static void monitor_handle_command(Monitor *mon, const char *cmdline)
 {
     QDict *qdict;
@@ -3171,7 +3185,10 @@  static void monitor_handle_command(Monitor *mon, const char *cmdline)
         cmd->mhandler.cmd(mon, qdict);
     }
 
-   qemu_errors_to_previous();
+    if (monitor_has_error(mon))
+        monitor_print_error(mon);
+
+    qemu_errors_to_previous();
 
 out:
     QDECREF(qdict);
@@ -3622,3 +3639,27 @@  void qemu_error(const char *fmt, ...)
         break;
     }
 }
+
+void qemu_error_qerror(QErrorCode code, const char *file, int linenr,
+                       const char *fmt, ...)
+{
+    va_list va;
+    QError *qerror;
+
+    assert(qemu_error_sink != NULL);
+
+    va_start(va, fmt);
+    qerror = qerror_from_info(code, file, linenr, fmt, &va);
+    va_end(va);
+
+    switch (qemu_error_sink->dest) {
+    case ERR_SINK_FILE:
+        qerror_print(qerror);
+        QDECREF(qerror);
+        break;
+    case ERR_SINK_MONITOR:
+        assert(qemu_error_sink->mon->error == NULL);
+        qemu_error_sink->mon->error = qerror;
+        break;
+    }
+}
diff --git a/sysemu.h b/sysemu.h
index 17af024..440a47c 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -7,6 +7,7 @@ 
 #include "qemu-queue.h"
 #include "qemu-timer.h"
 #include "qdict.h"
+#include "qerror.h"
 
 #ifdef _WIN32
 #include <windows.h>
@@ -71,6 +72,12 @@  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)));
+void qemu_error_qerror(QErrorCode code, const char *file, int linenr,
+                       const char *fmt, ...)
+                      __attribute__ ((format(printf, 4, 5)));
+
+#define qemu_error_structed(code, fmt, ...) \
+    qemu_error_qerror(code, __FILE__, __LINE__, fmt, ## __VA_ARGS__)
 
 #ifdef _WIN32
 /* Polling handling */