@@ -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;
+ }
+}
@@ -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 */
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(-)