From patchwork Fri Jan 31 13:01:08 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Vladimir Sementsov-Ogievskiy X-Patchwork-Id: 11359875 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id ABD8D159A for ; Fri, 31 Jan 2020 13:03:10 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 927B820CC7 for ; Fri, 31 Jan 2020 13:03:10 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 927B820CC7 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=virtuozzo.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1ixVvj-0001P1-3L; Fri, 31 Jan 2020 13:01:51 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1ixVvh-0001On-Qk for xen-devel@lists.xenproject.org; Fri, 31 Jan 2020 13:01:49 +0000 X-Inumbo-ID: d4888744-4429-11ea-8396-bc764e2007e4 Received: from relay.sw.ru (unknown [185.231.240.75]) by us1-rack-iad1.inumbo.com (Halon) with ESMTPS id d4888744-4429-11ea-8396-bc764e2007e4; Fri, 31 Jan 2020 13:01:44 +0000 (UTC) Received: from vovaso.qa.sw.ru ([10.94.3.0] helo=kvm.qa.sw.ru) by relay.sw.ru with esmtp (Exim 4.92.3) (envelope-from ) id 1ixVvH-0000zU-Oq; Fri, 31 Jan 2020 16:01:23 +0300 From: Vladimir Sementsov-Ogievskiy To: qemu-devel@nongnu.org Date: Fri, 31 Jan 2020 16:01:08 +0300 Message-Id: <20200131130118.1716-2-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20200131130118.1716-1-vsementsov@virtuozzo.com> References: <20200131130118.1716-1-vsementsov@virtuozzo.com> MIME-Version: 1.0 Subject: [Xen-devel] [PATCH v7 01/11] qapi/error: add (Error **errp) cleaning APIs X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , Laszlo Ersek , qemu-block@nongnu.org, Paul Durrant , =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= , armbru@redhat.com, Max Reitz , Greg Kurz , Stefano Stabellini , Gerd Hoffmann , Stefan Hajnoczi , Anthony Perard , xen-devel@lists.xenproject.org, Eric Blake , Michael Roth , Stefan Berger Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" Add functions to clean Error **errp: call corresponding Error *err cleaning function an set pointer to NULL. New functions: error_free_errp error_report_errp warn_report_errp Signed-off-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Greg Kurz Reviewed-by: Eric Blake --- CC: Eric Blake CC: Kevin Wolf CC: Max Reitz CC: Greg Kurz CC: Stefano Stabellini CC: Anthony Perard CC: Paul Durrant CC: Stefan Hajnoczi CC: "Philippe Mathieu-Daudé" CC: Laszlo Ersek CC: Gerd Hoffmann CC: Stefan Berger CC: Markus Armbruster CC: Michael Roth CC: qemu-block@nongnu.org CC: xen-devel@lists.xenproject.org include/qapi/error.h | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/include/qapi/error.h b/include/qapi/error.h index ad5b6e896d..d34987148d 100644 --- a/include/qapi/error.h +++ b/include/qapi/error.h @@ -309,6 +309,32 @@ void warn_reportf_err(Error *err, const char *fmt, ...) void error_reportf_err(Error *err, const char *fmt, ...) GCC_FMT_ATTR(2, 3); +/* + * Functions to clean Error **errp: call corresponding Error *err cleaning + * function, then set pointer to NULL. + */ +static inline void error_free_errp(Error **errp) +{ + assert(errp && *errp); + error_free(*errp); + *errp = NULL; +} + +static inline void error_report_errp(Error **errp) +{ + assert(errp && *errp); + error_report_err(*errp); + *errp = NULL; +} + +static inline void warn_report_errp(Error **errp) +{ + assert(errp && *errp); + warn_report_err(*errp); + *errp = NULL; +} + + /* * Just like error_setg(), except you get to specify the error class. * Note: use of error classes other than ERROR_CLASS_GENERIC_ERROR is From patchwork Fri Jan 31 13:01:09 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Vladimir Sementsov-Ogievskiy X-Patchwork-Id: 11359873 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1F62914B4 for ; Fri, 31 Jan 2020 13:03:10 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 059D920705 for ; Fri, 31 Jan 2020 13:03:10 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 059D920705 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=virtuozzo.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1ixVvj-0001P9-D7; Fri, 31 Jan 2020 13:01:51 +0000 Received: from all-amaz-eas1.inumbo.com ([34.197.232.57] helo=us1-amaz-eas2.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1ixVvh-0001Op-TV for xen-devel@lists.xenproject.org; Fri, 31 Jan 2020 13:01:49 +0000 X-Inumbo-ID: d48129a4-4429-11ea-8bc1-12813bfff9fa Received: from relay.sw.ru (unknown [185.231.240.75]) by us1-amaz-eas2.inumbo.com (Halon) with ESMTPS id d48129a4-4429-11ea-8bc1-12813bfff9fa; Fri, 31 Jan 2020 13:01:44 +0000 (UTC) Received: from vovaso.qa.sw.ru ([10.94.3.0] helo=kvm.qa.sw.ru) by relay.sw.ru with esmtp (Exim 4.92.3) (envelope-from ) id 1ixVvH-0000zU-VQ; Fri, 31 Jan 2020 16:01:24 +0300 From: Vladimir Sementsov-Ogievskiy To: qemu-devel@nongnu.org Date: Fri, 31 Jan 2020 16:01:09 +0300 Message-Id: <20200131130118.1716-3-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20200131130118.1716-1-vsementsov@virtuozzo.com> References: <20200131130118.1716-1-vsementsov@virtuozzo.com> MIME-Version: 1.0 Subject: [Xen-devel] [PATCH v7 02/11] error: auto propagated local_err X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , Laszlo Ersek , qemu-block@nongnu.org, Paul Durrant , =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= , armbru@redhat.com, Max Reitz , Greg Kurz , Stefano Stabellini , Gerd Hoffmann , Stefan Hajnoczi , Anthony Perard , xen-devel@lists.xenproject.org, Eric Blake , Michael Roth , Stefan Berger Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" Here is introduced ERRP_AUTO_PROPAGATE macro, to be used at start of functions with an errp OUT parameter. It has three goals: 1. Fix issue with error_fatal and 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 and error_propagate: when we wrap error_abort by local_err+error_propagate, the 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 us to [3.] drop the 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, later patches will add invocations of this macro at the start of functions with either use error_prepend/error_append_hint (solving 1) or which use local_err+error_propagate to check errors, switching those functions to use *errp instead (solving 2 and 3). Signed-off-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Greg Kurz Reviewed-by: Eric Blake --- CC: Eric Blake CC: Kevin Wolf CC: Max Reitz CC: Greg Kurz CC: Stefano Stabellini CC: Anthony Perard CC: Paul Durrant CC: Stefan Hajnoczi CC: "Philippe Mathieu-Daudé" CC: Laszlo Ersek CC: Gerd Hoffmann CC: Stefan Berger CC: Markus Armbruster CC: Michael Roth CC: qemu-block@nongnu.org CC: xen-devel@lists.xenproject.org include/qapi/error.h | 83 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 82 insertions(+), 1 deletion(-) diff --git a/include/qapi/error.h b/include/qapi/error.h index d34987148d..b9452d4806 100644 --- a/include/qapi/error.h +++ b/include/qapi/error.h @@ -78,7 +78,7 @@ * Call a function treating errors as fatal: * foo(arg, &error_fatal); * - * Receive an error and pass it on to the caller: + * Receive an error and pass it on to the caller (DEPRECATED*): * Error *err = NULL; * foo(arg, &err); * if (err) { @@ -98,6 +98,50 @@ * foo(arg, errp); * for readability. * + * DEPRECATED* This pattern is deprecated now, the use ERRP_AUTO_PROPAGATE macro + * instead (defined below). + * It's deprecated because of two things: + * + * 1. Issue with error_abort and error_propagate: when we wrap error_abort by + * local_err+error_propagate, the resulting coredump will refer to + * error_propagate and not to the place where error happened. + * + * 2. A lot of extra code of the same pattern + * + * How to update old code to use ERRP_AUTO_PROPAGATE? + * + * All you need is to add ERRP_AUTO_PROPAGATE() invocation at function start, + * than you may safely dereference errp to check errors and do not need any + * additional local Error variables or calls to error_propagate(). + * + * Example: + * + * old code + * + * void fn(..., Error **errp) { + * Error *err = NULL; + * foo(arg, &err); + * if (err) { + * handle the error... + * error_propagate(errp, err); + * return; + * } + * ... + * } + * + * updated code + * + * void fn(..., Error **errp) { + * ERRP_AUTO_PROPAGATE(); + * foo(arg, errp); + * if (*errp) { + * handle the error... + * return; + * } + * ... + * } + * + * * Receive and accumulate multiple errors (first one wins): * Error *err = NULL, *local_err = NULL; * foo(arg, &err); @@ -348,6 +392,43 @@ 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); + +/* + * ERRP_AUTO_PROPAGATE + * + * This macro is created to be the first line of a function which use + * Error **errp parameter to report error. 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. From patchwork Fri Jan 31 13:01:10 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Vladimir Sementsov-Ogievskiy X-Patchwork-Id: 11359879 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4656D14E3 for ; Fri, 31 Jan 2020 13:03:11 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 2D0C620CC7 for ; Fri, 31 Jan 2020 13:03:11 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 2D0C620CC7 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=virtuozzo.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1ixVvp-0001SR-OV; Fri, 31 Jan 2020 13:01:57 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1ixVvo-0001RL-Gj for xen-devel@lists.xenproject.org; Fri, 31 Jan 2020 13:01:56 +0000 X-Inumbo-ID: dac24352-4429-11ea-b211-bc764e2007e4 Received: from relay.sw.ru (unknown [185.231.240.75]) by us1-rack-iad1.inumbo.com (Halon) with ESMTPS id dac24352-4429-11ea-b211-bc764e2007e4; Fri, 31 Jan 2020 13:01:55 +0000 (UTC) Received: from vovaso.qa.sw.ru ([10.94.3.0] helo=kvm.qa.sw.ru) by relay.sw.ru with esmtp (Exim 4.92.3) (envelope-from ) id 1ixVvI-0000zU-3z; Fri, 31 Jan 2020 16:01:24 +0300 From: Vladimir Sementsov-Ogievskiy To: qemu-devel@nongnu.org Date: Fri, 31 Jan 2020 16:01:10 +0300 Message-Id: <20200131130118.1716-4-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20200131130118.1716-1-vsementsov@virtuozzo.com> References: <20200131130118.1716-1-vsementsov@virtuozzo.com> MIME-Version: 1.0 Subject: [Xen-devel] [PATCH v7 03/11] scripts: add coccinelle script to use auto propagated errp X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , Laszlo Ersek , qemu-block@nongnu.org, Paul Durrant , =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= , Greg Kurz , armbru@redhat.com, Stefano Stabellini , Gerd Hoffmann , Stefan Hajnoczi , Anthony Perard , xen-devel@lists.xenproject.org, Max Reitz , Eric Blake , Michael Roth , Stefan Berger Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" Script adds ERRP_AUTO_PROPAGATE macro invocation where appropriate and does corresponding changes in code (look for details in include/qapi/error.h) Usage example: spatch --sp-file scripts/coccinelle/auto-propagated-errp.cocci \ --macro-file scripts/cocci-macro-file.h --in-place --no-show-diff \ blockdev-nbd.c qemu-nbd.c {block/nbd*,nbd/*,include/block/nbd*}.[hc] Signed-off-by: Vladimir Sementsov-Ogievskiy --- CC: Eric Blake CC: Kevin Wolf CC: Max Reitz CC: Greg Kurz CC: Stefano Stabellini CC: Anthony Perard CC: Paul Durrant CC: Stefan Hajnoczi CC: "Philippe Mathieu-Daudé" CC: Laszlo Ersek CC: Gerd Hoffmann CC: Stefan Berger CC: Markus Armbruster CC: Michael Roth CC: qemu-block@nongnu.org CC: xen-devel@lists.xenproject.org include/qapi/error.h | 3 + scripts/coccinelle/auto-propagated-errp.cocci | 158 ++++++++++++++++++ 2 files changed, 161 insertions(+) create mode 100644 scripts/coccinelle/auto-propagated-errp.cocci diff --git a/include/qapi/error.h b/include/qapi/error.h index b9452d4806..79f8e95214 100644 --- a/include/qapi/error.h +++ b/include/qapi/error.h @@ -141,6 +141,9 @@ * ... * } * + * For mass conversion use script + * scripts/coccinelle/auto-propagated-errp.cocci + * * * Receive and accumulate multiple errors (first one wins): * Error *err = NULL, *local_err = NULL; diff --git a/scripts/coccinelle/auto-propagated-errp.cocci b/scripts/coccinelle/auto-propagated-errp.cocci new file mode 100644 index 0000000000..fb03c871cb --- /dev/null +++ b/scripts/coccinelle/auto-propagated-errp.cocci @@ -0,0 +1,158 @@ +// Use ERRP_AUTO_PROPAGATE (see include/qapi/error.h) +// +// Copyright (c) 2020 Virtuozzo International GmbH. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Usage example: +// spatch --sp-file scripts/coccinelle/auto-propagated-errp.cocci \ +// --macro-file scripts/cocci-macro-file.h --in-place --no-show-diff \ +// blockdev-nbd.c qemu-nbd.c {block/nbd*,nbd/*,include/block/nbd*}.[hc] + +@rule0@ +// Add invocation to errp-functions where necessary +// We should skip functions with "Error *const *errp" +// parameter, but how to do it with coccinelle? +// I don't know, so, I skip them by function name regex. +// It's safe: if we did not skip some functions with +// "Error *const *errp", ERRP_AUTO_PROPAGATE invocation +// will fail to compile, because of const violation. +identifier fn !~ "error_append_.*_hint"; +identifier local_err, ERRP; +@@ + + fn(..., Error **ERRP, ...) + { ++ ERRP_AUTO_PROPAGATE(); + <+... + when != ERRP_AUTO_PROPAGATE(); +( + error_append_hint(ERRP, ...); +| + error_prepend(ERRP, ...); +| + Error *local_err = NULL; +) + ...+> + } + +@@ +// Switch unusual (Error **) parameter names to errp +// (this is necessary to use ERRP_AUTO_PROPAGATE). +identifier rule0.fn; +identifier rule0.ERRP != errp; +@@ + + fn(..., +- Error **ERRP ++ Error **errp + ,...) + { + <... +- ERRP ++ errp + ...> + } + +@rule1@ +// We want to patch error propagation in functions regardless of +// whether the function already uses ERRP_AUTO_PROPAGATE prior to +// applying rule0, hence this one does not inherit from it. +identifier fn !~ "error_append_.*_hint"; +identifier local_err; +symbol errp; +@@ + + fn(..., Error **errp, ...) + { + <... +- Error *local_err = NULL; + ...> + } + +@@ +// Handle pattern with goto, otherwise we'll finish up +// with labels at function end which will not compile. +identifier rule1.fn, rule1.local_err; +identifier OUT; +@@ + + fn(...) + { + <... +- goto OUT; ++ return; + ...> +- OUT: +- error_propagate(errp, local_err); + } + +@@ +identifier rule1.fn, rule1.local_err; +expression list args; // to reindent error_propagate_prepend +@@ + + fn(...) + { + <... +( +- error_free(local_err); +- local_err = NULL; ++ error_free_errp(errp); +| +- error_free(local_err); ++ error_free_errp(errp); +| +- error_report_err(local_err); ++ error_report_errp(errp); +| +- warn_report_err(local_err); ++ warn_report_errp(errp); +| +- error_propagate_prepend(errp, local_err, args); ++ error_prepend(errp, args); +| +- error_propagate(errp, local_err); +) + ...> + } + +@@ +identifier rule1.fn, rule1.local_err; +@@ + + fn(...) + { + <... +( +- &local_err ++ errp +| +- local_err ++ *errp +) + ...> + } + +@@ +identifier rule1.fn; +@@ + + fn(...) + { + <... +- *errp != NULL ++ *errp + ...> + } From patchwork Fri Jan 31 13:01:18 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Sementsov-Ogievskiy X-Patchwork-Id: 11359871 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0E67114B4 for ; Fri, 31 Jan 2020 13:03:09 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id D215420705 for ; Fri, 31 Jan 2020 13:03:08 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org D215420705 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=virtuozzo.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1ixVve-0001OF-8j; Fri, 31 Jan 2020 13:01:46 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1ixVvc-0001O5-T4 for xen-devel@lists.xenproject.org; Fri, 31 Jan 2020 13:01:44 +0000 X-Inumbo-ID: d2bb63b4-4429-11ea-b211-bc764e2007e4 Received: from relay.sw.ru (unknown [185.231.240.75]) by us1-rack-iad1.inumbo.com (Halon) with ESMTPS id d2bb63b4-4429-11ea-b211-bc764e2007e4; Fri, 31 Jan 2020 13:01:41 +0000 (UTC) Received: from vovaso.qa.sw.ru ([10.94.3.0] helo=kvm.qa.sw.ru) by relay.sw.ru with esmtp (Exim 4.92.3) (envelope-from ) id 1ixVvK-0000zU-3v; Fri, 31 Jan 2020 16:01:26 +0300 From: Vladimir Sementsov-Ogievskiy To: qemu-devel@nongnu.org Date: Fri, 31 Jan 2020 16:01:18 +0300 Message-Id: <20200131130118.1716-12-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20200131130118.1716-1-vsementsov@virtuozzo.com> References: <20200131130118.1716-1-vsementsov@virtuozzo.com> MIME-Version: 1.0 Subject: [Xen-devel] [PATCH v7 11/11] xen: introduce ERRP_AUTO_PROPAGATE X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , qemu-block@nongnu.org, Paul Durrant , armbru@redhat.com, Greg Kurz , Stefano Stabellini , Stefan Hajnoczi , Anthony Perard , xen-devel@lists.xenproject.org, Max Reitz Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" If we want to add some info to errp (by error_prepend() or error_append_hint()), we must use the ERRP_AUTO_PROPAGATE macro. Otherwise, this info will not be added when errp == &error_fatal (the program will exit prior to the error_append_hint() or error_prepend() call). Fix such cases. If we want to check error after errp-function call, we need to introduce local_err and then propagate it to errp. Instead, use ERRP_AUTO_PROPAGATE macro, benefits are: 1. No need of explicit error_propagate call 2. No need of explicit local_err variable: use errp directly 3. ERRP_AUTO_PROPAGATE leaves errp as is if it's not NULL or &error_fatal, this means that we don't break error_abort (we'll abort on error_set, not on error_propagate) This commit is generated by command sed -n '/^X86 Xen CPUs$/,/^$/{s/^F: //p}' MAINTAINERS | \ xargs git ls-files | grep '\.[hc]$' | \ xargs spatch \ --sp-file scripts/coccinelle/auto-propagated-errp.cocci \ --macro-file scripts/cocci-macro-file.h \ --in-place --no-show-diff --max-width 80 Reported-by: Kevin Wolf Reported-by: Greg Kurz Signed-off-by: Vladimir Sementsov-Ogievskiy Acked-by: Paul Durrant --- hw/block/dataplane/xen-block.c | 17 ++--- hw/block/xen-block.c | 125 ++++++++++++++------------------- hw/pci-host/xen_igd_pt.c | 7 +- hw/xen/xen-backend.c | 7 +- hw/xen/xen-bus.c | 100 ++++++++++++-------------- hw/xen/xen-host-pci-device.c | 27 ++++--- hw/xen/xen_pt.c | 25 +++---- hw/xen/xen_pt_config_init.c | 20 +++--- 8 files changed, 142 insertions(+), 186 deletions(-) diff --git a/hw/block/dataplane/xen-block.c b/hw/block/dataplane/xen-block.c index 3b9caeb2fa..c38e3c3d85 100644 --- a/hw/block/dataplane/xen-block.c +++ b/hw/block/dataplane/xen-block.c @@ -727,8 +727,8 @@ void xen_block_dataplane_start(XenBlockDataPlane *dataplane, unsigned int protocol, Error **errp) { + ERRP_AUTO_PROPAGATE(); XenDevice *xendev = dataplane->xendev; - Error *local_err = NULL; unsigned int ring_size; unsigned int i; @@ -764,9 +764,8 @@ void xen_block_dataplane_start(XenBlockDataPlane *dataplane, } xen_device_set_max_grant_refs(xendev, dataplane->nr_ring_ref, - &local_err); - if (local_err) { - error_propagate(errp, local_err); + errp); + if (*errp) { goto stop; } @@ -774,9 +773,8 @@ void xen_block_dataplane_start(XenBlockDataPlane *dataplane, dataplane->ring_ref, dataplane->nr_ring_ref, PROT_READ | PROT_WRITE, - &local_err); - if (local_err) { - error_propagate(errp, local_err); + errp); + if (*errp) { goto stop; } @@ -809,9 +807,8 @@ void xen_block_dataplane_start(XenBlockDataPlane *dataplane, dataplane->event_channel = xen_device_bind_event_channel(xendev, dataplane->ctx, event_channel, xen_block_dataplane_event, dataplane, - &local_err); - if (local_err) { - error_propagate(errp, local_err); + errp); + if (*errp) { goto stop; } diff --git a/hw/block/xen-block.c b/hw/block/xen-block.c index 686bbc3f0d..717a80d5b5 100644 --- a/hw/block/xen-block.c +++ b/hw/block/xen-block.c @@ -194,6 +194,7 @@ static const BlockDevOps xen_block_dev_ops = { static void xen_block_realize(XenDevice *xendev, Error **errp) { + ERRP_AUTO_PROPAGATE(); XenBlockDevice *blockdev = XEN_BLOCK_DEVICE(xendev); XenBlockDeviceClass *blockdev_class = XEN_BLOCK_DEVICE_GET_CLASS(xendev); @@ -201,7 +202,6 @@ static void xen_block_realize(XenDevice *xendev, Error **errp) XenBlockVdev *vdev = &blockdev->props.vdev; BlockConf *conf = &blockdev->props.conf; BlockBackend *blk = conf->blk; - Error *local_err = NULL; if (vdev->type == XEN_BLOCK_VDEV_TYPE_INVALID) { error_setg(errp, "vdev property not set"); @@ -211,9 +211,8 @@ static void xen_block_realize(XenDevice *xendev, Error **errp) trace_xen_block_realize(type, vdev->disk, vdev->partition); if (blockdev_class->realize) { - blockdev_class->realize(blockdev, &local_err); - if (local_err) { - error_propagate(errp, local_err); + blockdev_class->realize(blockdev, errp); + if (*errp) { return; } } @@ -283,8 +282,8 @@ static void xen_block_frontend_changed(XenDevice *xendev, enum xenbus_state frontend_state, Error **errp) { + ERRP_AUTO_PROPAGATE(); enum xenbus_state backend_state = xen_device_backend_get_state(xendev); - Error *local_err = NULL; switch (frontend_state) { case XenbusStateInitialised: @@ -293,15 +292,13 @@ static void xen_block_frontend_changed(XenDevice *xendev, break; } - xen_block_disconnect(xendev, &local_err); - if (local_err) { - error_propagate(errp, local_err); + xen_block_disconnect(xendev, errp); + if (*errp) { break; } - xen_block_connect(xendev, &local_err); - if (local_err) { - error_propagate(errp, local_err); + xen_block_connect(xendev, errp); + if (*errp) { break; } @@ -314,9 +311,8 @@ static void xen_block_frontend_changed(XenDevice *xendev, case XenbusStateClosed: case XenbusStateUnknown: - xen_block_disconnect(xendev, &local_err); - if (local_err) { - error_propagate(errp, local_err); + xen_block_disconnect(xendev, errp); + if (*errp) { break; } @@ -403,10 +399,10 @@ static int vbd_name_to_disk(const char *name, const char **endp, static void xen_block_set_vdev(Object *obj, Visitor *v, const char *name, void *opaque, Error **errp) { + ERRP_AUTO_PROPAGATE(); DeviceState *dev = DEVICE(obj); Property *prop = opaque; XenBlockVdev *vdev = qdev_get_prop_ptr(dev, prop); - Error *local_err = NULL; char *str, *p; const char *end; @@ -415,9 +411,8 @@ static void xen_block_set_vdev(Object *obj, Visitor *v, const char *name, return; } - visit_type_str(v, name, &str, &local_err); - if (local_err) { - error_propagate(errp, local_err); + visit_type_str(v, name, &str, errp); + if (*errp) { return; } @@ -671,9 +666,9 @@ static void xen_block_blockdev_del(const char *node_name, Error **errp) static char *xen_block_blockdev_add(const char *id, QDict *qdict, Error **errp) { + ERRP_AUTO_PROPAGATE(); const char *driver = qdict_get_try_str(qdict, "driver"); BlockdevOptions *options = NULL; - Error *local_err = NULL; char *node_name; Visitor *v; @@ -688,18 +683,16 @@ static char *xen_block_blockdev_add(const char *id, QDict *qdict, trace_xen_block_blockdev_add(node_name); v = qobject_input_visitor_new(QOBJECT(qdict)); - visit_type_BlockdevOptions(v, NULL, &options, &local_err); + visit_type_BlockdevOptions(v, NULL, &options, errp); visit_free(v); - if (local_err) { - error_propagate(errp, local_err); + if (*errp) { goto fail; } - qmp_blockdev_add(options, &local_err); + qmp_blockdev_add(options, errp); - if (local_err) { - error_propagate(errp, local_err); + if (*errp) { goto fail; } @@ -718,14 +711,12 @@ fail: static void xen_block_drive_destroy(XenBlockDrive *drive, Error **errp) { + ERRP_AUTO_PROPAGATE(); char *node_name = drive->node_name; if (node_name) { - Error *local_err = NULL; - - xen_block_blockdev_del(node_name, &local_err); - if (local_err) { - error_propagate(errp, local_err); + xen_block_blockdev_del(node_name, errp); + if (*errp) { return; } g_free(node_name); @@ -739,6 +730,7 @@ static XenBlockDrive *xen_block_drive_create(const char *id, const char *device_type, QDict *opts, Error **errp) { + ERRP_AUTO_PROPAGATE(); const char *params = qdict_get_try_str(opts, "params"); const char *mode = qdict_get_try_str(opts, "mode"); const char *direct_io_safe = qdict_get_try_str(opts, "direct-io-safe"); @@ -746,7 +738,6 @@ static XenBlockDrive *xen_block_drive_create(const char *id, char *driver = NULL; char *filename = NULL; XenBlockDrive *drive = NULL; - Error *local_err = NULL; QDict *file_layer; QDict *driver_layer; @@ -825,13 +816,12 @@ static XenBlockDrive *xen_block_drive_create(const char *id, g_assert(!drive->node_name); drive->node_name = xen_block_blockdev_add(drive->id, driver_layer, - &local_err); + errp); qobject_unref(driver_layer); done: - if (local_err) { - error_propagate(errp, local_err); + if (*errp) { xen_block_drive_destroy(drive, NULL); return NULL; } @@ -856,15 +846,13 @@ static void xen_block_iothread_destroy(XenBlockIOThread *iothread, static XenBlockIOThread *xen_block_iothread_create(const char *id, Error **errp) { + ERRP_AUTO_PROPAGATE(); XenBlockIOThread *iothread = g_new(XenBlockIOThread, 1); - Error *local_err = NULL; iothread->id = g_strdup(id); - qmp_object_add(TYPE_IOTHREAD, id, false, NULL, &local_err); - if (local_err) { - error_propagate(errp, local_err); - + qmp_object_add(TYPE_IOTHREAD, id, false, NULL, errp); + if (*errp) { g_free(iothread->id); g_free(iothread); return NULL; @@ -876,6 +864,7 @@ static XenBlockIOThread *xen_block_iothread_create(const char *id, static void xen_block_device_create(XenBackendInstance *backend, QDict *opts, Error **errp) { + ERRP_AUTO_PROPAGATE(); XenBus *xenbus = xen_backend_get_bus(backend); const char *name = xen_backend_get_name(backend); unsigned long number; @@ -883,7 +872,6 @@ static void xen_block_device_create(XenBackendInstance *backend, XenBlockDrive *drive = NULL; XenBlockIOThread *iothread = NULL; XenDevice *xendev = NULL; - Error *local_err = NULL; const char *type; XenBlockDevice *blockdev; @@ -915,52 +903,48 @@ static void xen_block_device_create(XenBackendInstance *backend, goto fail; } - drive = xen_block_drive_create(vdev, device_type, opts, &local_err); + drive = xen_block_drive_create(vdev, device_type, opts, errp); if (!drive) { - error_propagate_prepend(errp, local_err, "failed to create drive: "); + error_prepend(errp, "failed to create drive: "); goto fail; } - iothread = xen_block_iothread_create(vdev, &local_err); - if (local_err) { - error_propagate_prepend(errp, local_err, - "failed to create iothread: "); + iothread = xen_block_iothread_create(vdev, errp); + if (*errp) { + error_prepend(errp, "failed to create iothread: "); goto fail; } xendev = XEN_DEVICE(qdev_create(BUS(xenbus), type)); blockdev = XEN_BLOCK_DEVICE(xendev); - object_property_set_str(OBJECT(xendev), vdev, "vdev", &local_err); - if (local_err) { - error_propagate_prepend(errp, local_err, "failed to set 'vdev': "); + object_property_set_str(OBJECT(xendev), vdev, "vdev", errp); + if (*errp) { + error_prepend(errp, "failed to set 'vdev': "); goto fail; } object_property_set_str(OBJECT(xendev), xen_block_drive_get_node_name(drive), "drive", - &local_err); - if (local_err) { - error_propagate_prepend(errp, local_err, "failed to set 'drive': "); + errp); + if (*errp) { + error_prepend(errp, "failed to set 'drive': "); goto fail; } object_property_set_str(OBJECT(xendev), iothread->id, "iothread", - &local_err); - if (local_err) { - error_propagate_prepend(errp, local_err, - "failed to set 'iothread': "); + errp); + if (*errp) { + error_prepend(errp, "failed to set 'iothread': "); goto fail; } blockdev->iothread = iothread; blockdev->drive = drive; - object_property_set_bool(OBJECT(xendev), true, "realized", &local_err); - if (local_err) { - error_propagate_prepend(errp, local_err, - "realization of device %s failed: ", - type); + object_property_set_bool(OBJECT(xendev), true, "realized", errp); + if (*errp) { + error_prepend(errp, "realization of device %s failed: ", type); goto fail; } @@ -984,6 +968,7 @@ fail: static void xen_block_device_destroy(XenBackendInstance *backend, Error **errp) { + ERRP_AUTO_PROPAGATE(); XenDevice *xendev = xen_backend_get_device(backend); XenBlockDevice *blockdev = XEN_BLOCK_DEVICE(xendev); XenBlockVdev *vdev = &blockdev->props.vdev; @@ -995,23 +980,17 @@ static void xen_block_device_destroy(XenBackendInstance *backend, object_unparent(OBJECT(xendev)); if (iothread) { - Error *local_err = NULL; - - xen_block_iothread_destroy(iothread, &local_err); - if (local_err) { - error_propagate_prepend(errp, local_err, - "failed to destroy iothread: "); + xen_block_iothread_destroy(iothread, errp); + if (*errp) { + error_prepend(errp, "failed to destroy iothread: "); return; } } if (drive) { - Error *local_err = NULL; - - xen_block_drive_destroy(drive, &local_err); - if (local_err) { - error_propagate_prepend(errp, local_err, - "failed to destroy drive: "); + xen_block_drive_destroy(drive, errp); + if (*errp) { + error_prepend(errp, "failed to destroy drive: "); } } } diff --git a/hw/pci-host/xen_igd_pt.c b/hw/pci-host/xen_igd_pt.c index efcc9347ff..29ade9ca25 100644 --- a/hw/pci-host/xen_igd_pt.c +++ b/hw/pci-host/xen_igd_pt.c @@ -79,17 +79,16 @@ static void host_pci_config_read(int pos, int len, uint32_t *val, Error **errp) static void igd_pt_i440fx_realize(PCIDevice *pci_dev, Error **errp) { + ERRP_AUTO_PROPAGATE(); uint32_t val = 0; size_t i; int pos, len; - Error *local_err = NULL; for (i = 0; i < ARRAY_SIZE(igd_host_bridge_infos); i++) { pos = igd_host_bridge_infos[i].offset; len = igd_host_bridge_infos[i].len; - host_pci_config_read(pos, len, &val, &local_err); - if (local_err) { - error_propagate(errp, local_err); + host_pci_config_read(pos, len, &val, errp); + if (*errp) { return; } pci_default_write_config(pci_dev, pos, val, len); diff --git a/hw/xen/xen-backend.c b/hw/xen/xen-backend.c index da065f81b7..1cc0694053 100644 --- a/hw/xen/xen-backend.c +++ b/hw/xen/xen-backend.c @@ -98,9 +98,9 @@ static void xen_backend_list_remove(XenBackendInstance *backend) void xen_backend_device_create(XenBus *xenbus, const char *type, const char *name, QDict *opts, Error **errp) { + ERRP_AUTO_PROPAGATE(); const XenBackendImpl *impl = xen_backend_table_lookup(type); XenBackendInstance *backend; - Error *local_error = NULL; if (!impl) { return; @@ -110,9 +110,8 @@ void xen_backend_device_create(XenBus *xenbus, const char *type, backend->xenbus = xenbus; backend->name = g_strdup(name); - impl->create(backend, opts, &local_error); - if (local_error) { - error_propagate(errp, local_error); + impl->create(backend, opts, errp); + if (*errp) { g_free(backend->name); g_free(backend); return; diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c index 919e66162a..7f0e91f6c0 100644 --- a/hw/xen/xen-bus.c +++ b/hw/xen/xen-bus.c @@ -53,9 +53,9 @@ static char *xen_device_get_frontend_path(XenDevice *xendev) static void xen_device_unplug(XenDevice *xendev, Error **errp) { + ERRP_AUTO_PROPAGATE(); XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); const char *type = object_get_typename(OBJECT(xendev)); - Error *local_err = NULL; xs_transaction_t tid; trace_xen_device_unplug(type, xendev->name); @@ -69,14 +69,14 @@ again: } xs_node_printf(xenbus->xsh, tid, xendev->backend_path, "online", - &local_err, "%u", 0); - if (local_err) { + errp, "%u", 0); + if (*errp) { goto abort; } xs_node_printf(xenbus->xsh, tid, xendev->backend_path, "state", - &local_err, "%u", XenbusStateClosing); - if (local_err) { + errp, "%u", XenbusStateClosing); + if (*errp) { goto abort; } @@ -96,7 +96,6 @@ abort: * from ending the transaction. */ xs_transaction_end(xenbus->xsh, tid, true); - error_propagate(errp, local_err); } static void xen_bus_print_dev(Monitor *mon, DeviceState *dev, int indent) @@ -205,15 +204,13 @@ static XenWatch *watch_list_add(XenWatchList *watch_list, const char *node, const char *key, XenWatchHandler handler, void *opaque, Error **errp) { + ERRP_AUTO_PROPAGATE(); XenWatch *watch = new_watch(node, key, handler, opaque); - Error *local_err = NULL; notifier_list_add(&watch_list->notifiers, &watch->notifier); - xs_node_watch(watch_list->xsh, node, key, watch->token, &local_err); - if (local_err) { - error_propagate(errp, local_err); - + xs_node_watch(watch_list->xsh, node, key, watch->token, errp); + if (*errp) { notifier_remove(&watch->notifier); free_watch(watch); @@ -255,11 +252,11 @@ static void xen_bus_backend_create(XenBus *xenbus, const char *type, const char *name, char *path, Error **errp) { + ERRP_AUTO_PROPAGATE(); xs_transaction_t tid; char **key; QDict *opts; unsigned int i, n; - Error *local_err = NULL; trace_xen_bus_backend_create(type, path); @@ -314,13 +311,11 @@ again: return; } - xen_backend_device_create(xenbus, type, name, opts, &local_err); + xen_backend_device_create(xenbus, type, name, opts, errp); qobject_unref(opts); - if (local_err) { - error_propagate_prepend(errp, local_err, - "failed to create '%s' device '%s': ", - type, name); + if (*errp) { + error_prepend(errp, "failed to create '%s' device '%s': ", type, name); } } @@ -451,9 +446,9 @@ static void xen_bus_unrealize(BusState *bus, Error **errp) static void xen_bus_realize(BusState *bus, Error **errp) { + ERRP_AUTO_PROPAGATE(); XenBus *xenbus = XEN_BUS(bus); unsigned int domid; - Error *local_err = NULL; trace_xen_bus_realize(); @@ -476,10 +471,10 @@ static void xen_bus_realize(BusState *bus, Error **errp) xenbus->backend_watch = xen_bus_add_watch(xenbus, "", /* domain root node */ - "backend", xen_bus_backend_changed, &local_err); - if (local_err) { + "backend", xen_bus_backend_changed, errp); + if (*errp) { /* This need not be treated as a hard error so don't propagate */ - error_reportf_err(local_err, + error_reportf_err(*errp, "failed to set up enumeration watch: "); } @@ -692,9 +687,9 @@ static void xen_device_remove_watch(XenDevice *xendev, XenWatch *watch, static void xen_device_backend_create(XenDevice *xendev, Error **errp) { + ERRP_AUTO_PROPAGATE(); XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); struct xs_permissions perms[2]; - Error *local_err = NULL; xendev->backend_path = xen_device_get_backend_path(xendev); @@ -706,30 +701,27 @@ static void xen_device_backend_create(XenDevice *xendev, Error **errp) g_assert(xenbus->xsh); xs_node_create(xenbus->xsh, XBT_NULL, xendev->backend_path, perms, - ARRAY_SIZE(perms), &local_err); - if (local_err) { - error_propagate_prepend(errp, local_err, - "failed to create backend: "); + ARRAY_SIZE(perms), errp); + if (*errp) { + error_prepend(errp, "failed to create backend: "); return; } xendev->backend_state_watch = xen_device_add_watch(xendev, xendev->backend_path, "state", xen_device_backend_changed, - &local_err); - if (local_err) { - error_propagate_prepend(errp, local_err, - "failed to watch backend state: "); + errp); + if (*errp) { + error_prepend(errp, "failed to watch backend state: "); return; } xendev->backend_online_watch = xen_device_add_watch(xendev, xendev->backend_path, "online", xen_device_backend_changed, - &local_err); - if (local_err) { - error_propagate_prepend(errp, local_err, - "failed to watch backend online: "); + errp); + if (*errp) { + error_prepend(errp, "failed to watch backend online: "); return; } } @@ -866,9 +858,9 @@ static bool xen_device_frontend_exists(XenDevice *xendev) static void xen_device_frontend_create(XenDevice *xendev, Error **errp) { + ERRP_AUTO_PROPAGATE(); XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); struct xs_permissions perms[2]; - Error *local_err = NULL; xendev->frontend_path = xen_device_get_frontend_path(xendev); @@ -885,20 +877,18 @@ static void xen_device_frontend_create(XenDevice *xendev, Error **errp) g_assert(xenbus->xsh); xs_node_create(xenbus->xsh, XBT_NULL, xendev->frontend_path, perms, - ARRAY_SIZE(perms), &local_err); - if (local_err) { - error_propagate_prepend(errp, local_err, - "failed to create frontend: "); + ARRAY_SIZE(perms), errp); + if (*errp) { + error_prepend(errp, "failed to create frontend: "); return; } } xendev->frontend_state_watch = xen_device_add_watch(xendev, xendev->frontend_path, "state", - xen_device_frontend_changed, &local_err); - if (local_err) { - error_propagate_prepend(errp, local_err, - "failed to watch frontend state: "); + xen_device_frontend_changed, errp); + if (*errp) { + error_prepend(errp, "failed to watch frontend state: "); } } @@ -1228,11 +1218,11 @@ static void xen_device_exit(Notifier *n, void *data) static void xen_device_realize(DeviceState *dev, Error **errp) { + ERRP_AUTO_PROPAGATE(); XenDevice *xendev = XEN_DEVICE(dev); XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev); XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); const char *type = object_get_typename(OBJECT(xendev)); - Error *local_err = NULL; if (xendev->frontend_id == DOMID_INVALID) { xendev->frontend_id = xen_domid; @@ -1248,10 +1238,9 @@ static void xen_device_realize(DeviceState *dev, Error **errp) goto unrealize; } - xendev->name = xendev_class->get_name(xendev, &local_err); - if (local_err) { - error_propagate_prepend(errp, local_err, - "failed to get device name: "); + xendev->name = xendev_class->get_name(xendev, errp); + if (*errp) { + error_prepend(errp, "failed to get device name: "); goto unrealize; } @@ -1274,22 +1263,19 @@ static void xen_device_realize(DeviceState *dev, Error **errp) xendev->feature_grant_copy = (xengnttab_grant_copy(xendev->xgth, 0, NULL) == 0); - xen_device_backend_create(xendev, &local_err); - if (local_err) { - error_propagate(errp, local_err); + xen_device_backend_create(xendev, errp); + if (*errp) { goto unrealize; } - xen_device_frontend_create(xendev, &local_err); - if (local_err) { - error_propagate(errp, local_err); + xen_device_frontend_create(xendev, errp); + if (*errp) { goto unrealize; } if (xendev_class->realize) { - xendev_class->realize(xendev, &local_err); - if (local_err) { - error_propagate(errp, local_err); + xendev_class->realize(xendev, errp); + if (*errp) { goto unrealize; } } diff --git a/hw/xen/xen-host-pci-device.c b/hw/xen/xen-host-pci-device.c index 1b44dcafaf..02379c341c 100644 --- a/hw/xen/xen-host-pci-device.c +++ b/hw/xen/xen-host-pci-device.c @@ -333,8 +333,8 @@ void xen_host_pci_device_get(XenHostPCIDevice *d, uint16_t domain, uint8_t bus, uint8_t dev, uint8_t func, Error **errp) { + ERRP_AUTO_PROPAGATE(); unsigned int v; - Error *err = NULL; d->config_fd = -1; d->domain = domain; @@ -342,36 +342,36 @@ void xen_host_pci_device_get(XenHostPCIDevice *d, uint16_t domain, d->dev = dev; d->func = func; - xen_host_pci_config_open(d, &err); - if (err) { + xen_host_pci_config_open(d, errp); + if (*errp) { goto error; } - xen_host_pci_get_resource(d, &err); - if (err) { + xen_host_pci_get_resource(d, errp); + if (*errp) { goto error; } - xen_host_pci_get_hex_value(d, "vendor", &v, &err); - if (err) { + xen_host_pci_get_hex_value(d, "vendor", &v, errp); + if (*errp) { goto error; } d->vendor_id = v; - xen_host_pci_get_hex_value(d, "device", &v, &err); - if (err) { + xen_host_pci_get_hex_value(d, "device", &v, errp); + if (*errp) { goto error; } d->device_id = v; - xen_host_pci_get_dec_value(d, "irq", &v, &err); - if (err) { + xen_host_pci_get_dec_value(d, "irq", &v, errp); + if (*errp) { goto error; } d->irq = v; - xen_host_pci_get_hex_value(d, "class", &v, &err); - if (err) { + xen_host_pci_get_hex_value(d, "class", &v, errp); + if (*errp) { goto error; } d->class_code = v; @@ -381,7 +381,6 @@ void xen_host_pci_device_get(XenHostPCIDevice *d, uint16_t domain, return; error: - error_propagate(errp, err); if (d->config_fd >= 0) { close(d->config_fd); diff --git a/hw/xen/xen_pt.c b/hw/xen/xen_pt.c index b91082cb8b..f57b81588e 100644 --- a/hw/xen/xen_pt.c +++ b/hw/xen/xen_pt.c @@ -767,12 +767,12 @@ static void xen_pt_destroy(PCIDevice *d) { static void xen_pt_realize(PCIDevice *d, Error **errp) { + ERRP_AUTO_PROPAGATE(); XenPCIPassthroughState *s = XEN_PT_DEVICE(d); int i, rc = 0; uint8_t machine_irq = 0, scratch; uint16_t cmd = 0; int pirq = XEN_PT_UNASSIGNED_PIRQ; - Error *err = NULL; /* register real device */ XEN_PT_LOG(d, "Assigning real physical device %02x:%02x.%d" @@ -783,10 +783,9 @@ static void xen_pt_realize(PCIDevice *d, Error **errp) xen_host_pci_device_get(&s->real_device, s->hostaddr.domain, s->hostaddr.bus, s->hostaddr.slot, s->hostaddr.function, - &err); - if (err) { - error_append_hint(&err, "Failed to \"open\" the real pci device"); - error_propagate(errp, err); + errp); + if (*errp) { + error_append_hint(errp, "Failed to \"open\" the real pci device"); return; } @@ -813,11 +812,10 @@ static void xen_pt_realize(PCIDevice *d, Error **errp) return; } - xen_pt_setup_vga(s, &s->real_device, &err); - if (err) { - error_append_hint(&err, "Setup VGA BIOS of passthrough" - " GFX failed"); - error_propagate(errp, err); + xen_pt_setup_vga(s, &s->real_device, errp); + if (*errp) { + error_append_hint(errp, "Setup VGA BIOS of passthrough" + " GFX failed"); xen_host_pci_device_put(&s->real_device); return; } @@ -830,10 +828,9 @@ static void xen_pt_realize(PCIDevice *d, Error **errp) xen_pt_register_regions(s, &cmd); /* reinitialize each config register to be emulated */ - xen_pt_config_init(s, &err); - if (err) { - error_append_hint(&err, "PCI Config space initialisation failed"); - error_propagate(errp, err); + xen_pt_config_init(s, errp); + if (*errp) { + error_append_hint(errp, "PCI Config space initialisation failed"); rc = -1; goto err_out; } diff --git a/hw/xen/xen_pt_config_init.c b/hw/xen/xen_pt_config_init.c index 31ec5add1d..af3fbd1bfb 100644 --- a/hw/xen/xen_pt_config_init.c +++ b/hw/xen/xen_pt_config_init.c @@ -2008,8 +2008,8 @@ static void xen_pt_config_reg_init(XenPCIPassthroughState *s, void xen_pt_config_init(XenPCIPassthroughState *s, Error **errp) { + ERRP_AUTO_PROPAGATE(); int i, rc; - Error *err = NULL; QLIST_INIT(&s->reg_grps); @@ -2052,10 +2052,9 @@ void xen_pt_config_init(XenPCIPassthroughState *s, Error **errp) reg_grp_offset, ®_grp_entry->size); if (rc < 0) { - error_setg(&err, "Failed to initialize %d/%zu, type = 0x%x," + error_setg(errp, "Failed to initialize %d/%zu, type = 0x%x," " rc: %d", i, ARRAY_SIZE(xen_pt_emu_reg_grps), xen_pt_emu_reg_grps[i].grp_type, rc); - error_propagate(errp, err); xen_pt_config_delete(s); return; } @@ -2068,13 +2067,14 @@ void xen_pt_config_init(XenPCIPassthroughState *s, Error **errp) /* initialize capability register */ for (j = 0; regs->size != 0; j++, regs++) { - xen_pt_config_reg_init(s, reg_grp_entry, regs, &err); - if (err) { - error_append_hint(&err, "Failed to init register %d" - " offsets 0x%x in grp_type = 0x%x (%d/%zu)", j, - regs->offset, xen_pt_emu_reg_grps[i].grp_type, - i, ARRAY_SIZE(xen_pt_emu_reg_grps)); - error_propagate(errp, err); + xen_pt_config_reg_init(s, reg_grp_entry, regs, errp); + if (*errp) { + error_append_hint(errp, "Failed to init register %d" + " offsets 0x%x in grp_type = 0x%x (%d/%zu)", + j, + regs->offset, + xen_pt_emu_reg_grps[i].grp_type, + i, ARRAY_SIZE(xen_pt_emu_reg_grps)); xen_pt_config_delete(s); return; }