[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v2 1/2] utils: Add warning messages
From: |
Lluís Vilanova |
Subject: |
[Qemu-devel] [PATCH v2 1/2] utils: Add warning messages |
Date: |
Mon, 23 Nov 2015 19:41:18 +0100 |
User-agent: |
StGit/0.17.1-dirty |
Adds a special error object that transforms error messages into
immediately reported warnings.
Signed-off-by: Lluís Vilanova <address@hidden>
---
include/qapi/error.h | 20 ++++++++++++++++++++
util/error.c | 37 +++++++++++++++++++++++++++----------
2 files changed, 47 insertions(+), 10 deletions(-)
diff --git a/include/qapi/error.h b/include/qapi/error.h
index 4d42cdc..9b7600c 100644
--- a/include/qapi/error.h
+++ b/include/qapi/error.h
@@ -57,6 +57,9 @@
* Call a function treating errors as fatal:
* foo(arg, &error_fatal);
*
+ * Call a function immediately showing all errors as warnings:
+ * foo(arg, &error_warn);
+ *
* Receive an error and pass it on to the caller:
* Error *err = NULL;
* foo(arg, &err);
@@ -108,6 +111,7 @@ ErrorClass error_get_class(const Error *err);
* then.
* If @errp is &error_abort, print a suitable message and abort().
* If @errp is &error_fatal, print a suitable message and exit(1).
+ * If @errp is &error_warn, print a suitable message.
* If @errp is anything else, address@hidden must be NULL.
* The new error's class is ERROR_CLASS_GENERIC_ERROR, and its
* human-readable error message is made from printf-style @fmt, ...
@@ -158,6 +162,7 @@ void error_setg_win32_internal(Error **errp,
* abort().
* Else, if @dst_errp is &error_fatal, print a suitable message and
* exit(1).
+ * Else, if @dst_errp is &error_warn, print a suitable message.
* Else, if @dst_errp already contains an error, ignore this one: free
* the error object.
* Else, move the error object from @local_err to address@hidden
@@ -218,12 +223,27 @@ void error_set_internal(Error **errp,
/*
* Pass to error_setg() & friends to abort() on error.
+ *
+ * WARNING: Do _not_ use for errors that are (or can be) triggered by guest
code
+ * (e.g., some unimplimented corner case in guest code translation or
+ * device code). Otherwise that can be abused by guest code to
+ * terminate QEMU.
*/
extern Error *error_abort;
/*
* Pass to error_setg() & friends to exit(1) on error.
+ *
+ * WARNING: Do _not_ use for errors that are (or can be) triggered by guest
code
+ * (e.g., some unimplimented corner case in guest code translation or
+ * device code). Otherwise that can be abused by guest code to
+ * terminate QEMU.
*/
extern Error *error_fatal;
+/*
+ * Pass to error_setg() & friends to immediately show an error as a warning.
+ */
+extern Error *error_warn;
+
#endif
diff --git a/util/error.c b/util/error.c
index 80c89a2..85170e54 100644
--- a/util/error.c
+++ b/util/error.c
@@ -15,6 +15,7 @@
#include "qemu-common.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
+#include "qemu/timer.h"
struct Error
{
@@ -27,8 +28,9 @@ struct Error
Error *error_abort;
Error *error_fatal;
+Error *error_warn;
-static void error_handle_fatal(Error **errp, Error *err)
+static bool error_handle_fatal(Error **errp, Error *err)
{
if (errp == &error_abort) {
fprintf(stderr, "Unexpected error in %s() at %s:%d:\n",
@@ -40,6 +42,20 @@ static void error_handle_fatal(Error **errp, Error *err)
error_report_err(err);
exit(1);
}
+
+ if (errp == &error_warn) {
+ /* cannot use error_report_err() because it adds newlines */
+ error_report("warning: [%s() at %s:%d] %s",
+ err->func, err->src, err->line, err->msg);
+ if (err->hint) {
+ error_printf_unless_qmp("warning: [%s() at %s:%d] %s",
+ err->func, err->src, err->line,
+ err->hint->str);
+ }
+ return true;
+ } else {
+ return false;
+ }
}
static void error_setv(Error **errp,
@@ -61,10 +77,10 @@ static void error_setv(Error **errp,
err->line = line;
err->func = func;
- error_handle_fatal(errp, err);
- *errp = err;
-
- errno = saved_errno;
+ if (!error_handle_fatal(errp, err)) {
+ *errp = err;
+ errno = saved_errno;
+ }
}
void error_set_internal(Error **errp,
@@ -232,10 +248,11 @@ void error_propagate(Error **dst_errp, Error *local_err)
if (!local_err) {
return;
}
- error_handle_fatal(dst_errp, local_err);
- if (dst_errp && !*dst_errp) {
- *dst_errp = local_err;
- } else {
- error_free(local_err);
+ if (!error_handle_fatal(dst_errp, local_err)) {
+ if (dst_errp && !*dst_errp) {
+ *dst_errp = local_err;
+ } else {
+ error_free(local_err);
+ }
}
}