[GEDI] [RFC v5 024/126] error: auto propagated local_err

Vladimir Sementsov-Ogievskiy vsementsov at virtuozzo.com
Fri Oct 11 16:04:10 UTC 2019

Here is introduced ERRP_AUTO_PROPAGATE macro, to be used at start of
functions with errp OUT parameter.

It has three goals:

1. Fix issue with error_fatal & error_prepend/error_append_hint: user
can't see this additional information, because exit() happens in
error_setg earlier than information is added. [Reported by Greg Kurz]

2. Fix issue with error_abort & error_propagate: when we wrap
error_abort by local_err+error_propagate, resulting coredump will
refer to error_propagate and not to the place where error happened.
(the macro itself doesn't fix the issue, but it allows to [3.] drop all
local_err+error_propagate pattern, which will definitely fix the issue)
[Reported by Kevin Wolf]

3. Drop local_err+error_propagate pattern, which is used to workaround
void functions with errp parameter, when caller wants to know resulting
status. (Note: actually these functions could be merely updated to
return int error code).

To achieve these goals, we need to add invocation of the macro at start
of functions, which needs error_prepend/error_append_hint (1.); add
invocation of the macro at start of functions which do
local_err+error_propagate scenario the check errors, drop local errors
from them and just use *errp instead (2., 3.).

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov at virtuozzo.com>
Reviewed-by: Eric Blake <eblake at redhat.com>

CC: Gerd Hoffmann <kraxel at redhat.com>
CC: "Gonglei (Arei)" <arei.gonglei at huawei.com>
CC: Eduardo Habkost <ehabkost at redhat.com>
CC: Igor Mammedov <imammedo at redhat.com>
CC: Laurent Vivier <lvivier at redhat.com>
CC: Amit Shah <amit at kernel.org>
CC: Kevin Wolf <kwolf at redhat.com>
CC: Max Reitz <mreitz at redhat.com>
CC: John Snow <jsnow at redhat.com>
CC: Ari Sundholm <ari at tuxera.com>
CC: Pavel Dovgalyuk <pavel.dovgaluk at ispras.ru>
CC: Paolo Bonzini <pbonzini at redhat.com>
CC: Stefan Hajnoczi <stefanha at redhat.com>
CC: Fam Zheng <fam at euphon.net>
CC: Stefan Weil <sw at weilnetz.de>
CC: Ronnie Sahlberg <ronniesahlberg at gmail.com>
CC: Peter Lieven <pl at kamp.de>
CC: Eric Blake <eblake at redhat.com>
CC: "Denis V. Lunev" <den at openvz.org>
CC: Markus Armbruster <armbru at redhat.com>
CC: Alberto Garcia <berto at igalia.com>
CC: Jason Dillaman <dillaman at redhat.com>
CC: Wen Congyang <wencongyang2 at huawei.com>
CC: Xie Changlong <xiechanglong.d at gmail.com>
CC: Liu Yuan <namei.unix at gmail.com>
CC: "Richard W.M. Jones" <rjones at redhat.com>
CC: Jeff Cody <codyprime at gmail.com>
CC: "Marc-André Lureau" <marcandre.lureau at redhat.com>
CC: "Daniel P. Berrangé" <berrange at redhat.com>
CC: Richard Henderson <rth at twiddle.net>
CC: Greg Kurz <groug at kaod.org>
CC: "Michael S. Tsirkin" <mst at redhat.com>
CC: Marcel Apfelbaum <marcel.apfelbaum at gmail.com>
CC: Beniamino Galvani <b.galvani at gmail.com>
CC: Peter Maydell <peter.maydell at linaro.org>
CC: "Cédric Le Goater" <clg at kaod.org>
CC: Andrew Jeffery <andrew at aj.id.au>
CC: Joel Stanley <joel at jms.id.au>
CC: Andrew Baumann <Andrew.Baumann at microsoft.com>
CC: "Philippe Mathieu-Daudé" <philmd at redhat.com>
CC: Antony Pavlov <antonynpavlov at gmail.com>
CC: Jean-Christophe Dubois <jcd at tribudubois.net>
CC: Peter Chubb <peter.chubb at nicta.com.au>
CC: Subbaraya Sundeep <sundeep.lkml at gmail.com>
CC: Eric Auger <eric.auger at redhat.com>
CC: Alistair Francis <alistair at alistair23.me>
CC: "Edgar E. Iglesias" <edgar.iglesias at gmail.com>
CC: Stefano Stabellini <sstabellini at kernel.org>
CC: Anthony Perard <anthony.perard at citrix.com>
CC: Paul Durrant <paul at xen.org>
CC: Paul Burton <pburton at wavecomp.com>
CC: Aleksandar Rikalo <arikalo at wavecomp.com>
CC: Chris Wulff <crwulff at gmail.com>
CC: Marek Vasut <marex at denx.de>
CC: David Gibson <david at gibson.dropbear.id.au>
CC: Cornelia Huck <cohuck at redhat.com>
CC: Halil Pasic <pasic at linux.ibm.com>
CC: Christian Borntraeger <borntraeger at de.ibm.com>
CC: "Hervé Poussineau" <hpoussin at reactos.org>
CC: Xiao Guangrong <xiaoguangrong.eric at gmail.com>
CC: Aurelien Jarno <aurelien at aurel32.net>
CC: Aleksandar Markovic <amarkovic at wavecomp.com>
CC: Mark Cave-Ayland <mark.cave-ayland at ilande.co.uk>
CC: Jason Wang <jasowang at redhat.com>
CC: Laszlo Ersek <lersek at redhat.com>
CC: Yuval Shaia <yuval.shaia at oracle.com>
CC: Palmer Dabbelt <palmer at sifive.com>
CC: Sagar Karandikar <sagark at eecs.berkeley.edu>
CC: Bastian Koppelmann <kbastian at mail.uni-paderborn.de>
CC: David Hildenbrand <david at redhat.com>
CC: Thomas Huth <thuth at redhat.com>
CC: Eric Farman <farman at linux.ibm.com>
CC: Matthew Rosato <mjrosato at linux.ibm.com>
CC: Hannes Reinecke <hare at suse.com>
CC: Michael Walle <michael at walle.cc>
CC: Artyom Tarasenko <atar4qemu at gmail.com>
CC: Stefan Berger <stefanb at linux.ibm.com>
CC: Samuel Thibault <samuel.thibault at ens-lyon.org>
CC: Alex Williamson <alex.williamson at redhat.com>
CC: Tony Krowiak <akrowiak at linux.ibm.com>
CC: Pierre Morel <pmorel at linux.ibm.com>
CC: Michael Roth <mdroth at linux.vnet.ibm.com>
CC: Hailiang Zhang <zhang.zhanghailiang at huawei.com>
CC: Juan Quintela <quintela at redhat.com>
CC: "Dr. David Alan Gilbert" <dgilbert at redhat.com>
CC: Luigi Rizzo <rizzo at iet.unipi.it>
CC: Giuseppe Lettieri <g.lettieri at iet.unipi.it>
CC: Vincenzo Maffione <v.maffione at gmail.com>
CC: Jan Kiszka <jan.kiszka at siemens.com>
CC: Anthony Green <green at moxielogic.com>
CC: Stafford Horne <shorne at gmail.com>
CC: Guan Xuetao <gxt at mprc.pku.edu.cn>
CC: Max Filippov <jcmvbkbc at gmail.com>
CC: qemu-block at nongnu.org
CC: integration at gluster.org
CC: sheepdog at lists.wpkg.org
CC: qemu-arm at nongnu.org
CC: xen-devel at lists.xenproject.org
CC: qemu-ppc at nongnu.org
CC: qemu-s390x at nongnu.org
CC: qemu-riscv at nongnu.org

 include/qapi/error.h | 38 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/include/qapi/error.h b/include/qapi/error.h
index d6898d833b..47238d9065 100644
--- a/include/qapi/error.h
+++ b/include/qapi/error.h
@@ -345,6 +345,44 @@ void error_set_internal(Error **errp,
                         ErrorClass err_class, const char *fmt, ...)
     GCC_FMT_ATTR(6, 7);
+typedef struct ErrorPropagator {
+    Error *local_err;
+    Error **errp;
+} ErrorPropagator;
+static inline void error_propagator_cleanup(ErrorPropagator *prop)
+    error_propagate(prop->errp, prop->local_err);
+G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(ErrorPropagator, error_propagator_cleanup);
+ *
+ * This macro is created to be the first line of a function with Error **errp
+ * OUT parameter. It's needed only in cases where we want to use error_prepend,
+ * error_append_hint or dereference *errp. It's still safe (but useless) in
+ * other cases.
+ *
+ * If errp is NULL or points to error_fatal, it is rewritten to point to a
+ * local Error object, which will be automatically propagated to the original
+ * errp on function exit (see error_propagator_cleanup).
+ *
+ * After invocation of this macro it is always safe to dereference errp
+ * (as it's not NULL anymore) and to add information (by error_prepend or
+ * error_append_hint)
+ * (as, if it was error_fatal, we swapped it with a local_error to be
+ * propagated on cleanup).
+ *
+ * Note: we don't wrap the error_abort case, as we want resulting coredump
+ * to point to the place where the error happened, not to error_propagate.
+ */
+#define ERRP_AUTO_PROPAGATE()                                  \
+    g_auto(ErrorPropagator) _auto_errp_prop = {.errp = errp};  \
+    errp = ((errp == NULL || *errp == error_fatal)             \
+            ? &_auto_errp_prop.local_err : errp)
  * Special error destination to abort on error.
  * See error_setg() and error_propagate() for details.

More information about the integration mailing list