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