|
|
9ae3a8 |
From 2112c4a8297592045ac8ed8b0677e81208296364 Mon Sep 17 00:00:00 2001
|
|
|
9ae3a8 |
From: Kevin Wolf <kwolf@redhat.com>
|
|
|
9ae3a8 |
Date: Thu, 23 Oct 2014 10:10:05 +0200
|
|
|
9ae3a8 |
Subject: [PATCH 02/19] error: Add error_abort
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Message-id: <1414059011-15516-3-git-send-email-kwolf@redhat.com>
|
|
|
9ae3a8 |
Patchwork-id: 61836
|
|
|
9ae3a8 |
O-Subject: [RHEL-7.1 qemu-kvm PATCH v2 2/8] error: Add error_abort
|
|
|
9ae3a8 |
Bugzilla: 1088176
|
|
|
9ae3a8 |
RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
|
|
|
9ae3a8 |
RH-Acked-by: Markus Armbruster <armbru@redhat.com>
|
|
|
9ae3a8 |
RH-Acked-by: Max Reitz <mreitz@redhat.com>
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
From: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Add a special Error * that can be passed to error handling APIs to
|
|
|
9ae3a8 |
signal that any errors are fatal and should abort QEMU. There are two
|
|
|
9ae3a8 |
advantages to this:
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
- allows for brevity when wishing to assert success of Error **
|
|
|
9ae3a8 |
accepting APIs. No need for this pattern:
|
|
|
9ae3a8 |
Error * local_err = NULL;
|
|
|
9ae3a8 |
api_call(foo, bar, &local_err);
|
|
|
9ae3a8 |
assert_no_error(local_err);
|
|
|
9ae3a8 |
This also removes the need for _nofail variants of APIs with
|
|
|
9ae3a8 |
asserting call sites now reduced to 1LOC.
|
|
|
9ae3a8 |
- SIGABRT happens from within the offending API. When a fatal error
|
|
|
9ae3a8 |
occurs in an API call (when the caller is asserting sucess) failure
|
|
|
9ae3a8 |
often means the API itself is broken. With the abort happening in the
|
|
|
9ae3a8 |
API call now, the stack frames into the call are available at debug
|
|
|
9ae3a8 |
time. In the assert_no_error scheme the abort happens after the fact.
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
The exact semantic is that when an error is raised, if the argument
|
|
|
9ae3a8 |
Error ** matches &error_abort, then the abort occurs immediately. The
|
|
|
9ae3a8 |
error messaged is reported.
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
For error_propagate, if the destination error is &error_abort, then
|
|
|
9ae3a8 |
the abort happens at propagation time.
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
|
|
|
9ae3a8 |
Reviewed-by: Markus Armbruster <armbru@redhat.com>
|
|
|
9ae3a8 |
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
|
|
|
9ae3a8 |
(cherry picked from commit 5d24ee70bcbcf578614193526bcd5ed30a8eb16c)
|
|
|
9ae3a8 |
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Conflicts:
|
|
|
9ae3a8 |
util/error.c
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Conflicts because RHEL 7 doesn't have error_set_win32().
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
|
|
9ae3a8 |
---
|
|
|
9ae3a8 |
include/qapi/error.h | 6 ++++++
|
|
|
9ae3a8 |
util/error.c | 17 ++++++++++++++++-
|
|
|
9ae3a8 |
2 files changed, 22 insertions(+), 1 deletion(-)
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
diff --git a/include/qapi/error.h b/include/qapi/error.h
|
|
|
9ae3a8 |
index ffd1cea..fc7f44a 100644
|
|
|
9ae3a8 |
--- a/include/qapi/error.h
|
|
|
9ae3a8 |
+++ b/include/qapi/error.h
|
|
|
9ae3a8 |
@@ -82,4 +82,10 @@ void error_propagate(Error **dst_err, Error *local_err);
|
|
|
9ae3a8 |
*/
|
|
|
9ae3a8 |
void error_free(Error *err);
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
+/**
|
|
|
9ae3a8 |
+ * If passed to error_set and friends, abort().
|
|
|
9ae3a8 |
+ */
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+extern Error *error_abort;
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
#endif
|
|
|
9ae3a8 |
diff --git a/util/error.c b/util/error.c
|
|
|
9ae3a8 |
index 53b0435..82658bb 100644
|
|
|
9ae3a8 |
--- a/util/error.c
|
|
|
9ae3a8 |
+++ b/util/error.c
|
|
|
9ae3a8 |
@@ -23,6 +23,8 @@ struct Error
|
|
|
9ae3a8 |
ErrorClass err_class;
|
|
|
9ae3a8 |
};
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
+Error *error_abort;
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
void error_set(Error **errp, ErrorClass err_class, const char *fmt, ...)
|
|
|
9ae3a8 |
{
|
|
|
9ae3a8 |
Error *err;
|
|
|
9ae3a8 |
@@ -40,6 +42,11 @@ void error_set(Error **errp, ErrorClass err_class, const char *fmt, ...)
|
|
|
9ae3a8 |
va_end(ap);
|
|
|
9ae3a8 |
err->err_class = err_class;
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
+ if (errp == &error_abort) {
|
|
|
9ae3a8 |
+ error_report("%s", error_get_pretty(err));
|
|
|
9ae3a8 |
+ abort();
|
|
|
9ae3a8 |
+ }
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
*errp = err;
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
@@ -68,6 +75,11 @@ void error_set_errno(Error **errp, int os_errno, ErrorClass err_class,
|
|
|
9ae3a8 |
va_end(ap);
|
|
|
9ae3a8 |
err->err_class = err_class;
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
+ if (errp == &error_abort) {
|
|
|
9ae3a8 |
+ error_report("%s", error_get_pretty(err));
|
|
|
9ae3a8 |
+ abort();
|
|
|
9ae3a8 |
+ }
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
*errp = err;
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
@@ -112,7 +124,10 @@ void error_free(Error *err)
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
void error_propagate(Error **dst_err, Error *local_err)
|
|
|
9ae3a8 |
{
|
|
|
9ae3a8 |
- if (dst_err && !*dst_err) {
|
|
|
9ae3a8 |
+ if (local_err && dst_err == &error_abort) {
|
|
|
9ae3a8 |
+ error_report("%s", error_get_pretty(local_err));
|
|
|
9ae3a8 |
+ abort();
|
|
|
9ae3a8 |
+ } else if (dst_err && !*dst_err) {
|
|
|
9ae3a8 |
*dst_err = local_err;
|
|
|
9ae3a8 |
} else if (local_err) {
|
|
|
9ae3a8 |
error_free(local_err);
|
|
|
9ae3a8 |
--
|
|
|
9ae3a8 |
1.8.3.1
|
|
|
9ae3a8 |
|