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