qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Markus Armbruster <armbru@redhat.com>
To: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Cc: Kevin Wolf <kwolf@redhat.com>,
	"qemu-devel@nongnu.org" <qemu-devel@nongnu.org>,
	"qemu-block@nongnu.org" <qemu-block@nongnu.org>,
	Max Reitz <mreitz@redhat.com>
Subject: Re: [PATCH v7 21/21] nbd: assert that Error** is not NULL in nbd_iter_channel_error
Date: Fri, 06 Dec 2019 09:54:20 +0100	[thread overview]
Message-ID: <87sglxltqb.fsf@dusky.pond.sub.org> (raw)
In-Reply-To: <93046486-1580-14a1-520d-08abdf74da0e@virtuozzo.com> (Vladimir Sementsov-Ogievskiy's message of "Thu, 5 Dec 2019 17:39:21 +0000")

Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> writes:

> 05.12.2019 20:14, Eric Blake wrote:
>> On 12/5/19 9:20 AM, Vladimir Sementsov-Ogievskiy wrote:
>>> The local_err parameter is not here to return information about
>>> nbd_iter_channel_error failure. Instead it's assumed to be filled when
>>> passed to the function. This is already stressed by its name
>>> (local_err, instead of classic errp). Stress it additionally by
>>> assertion.
>>>
>>> Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
>>> ---
>>>   block/nbd.c | 1 +
>>>   1 file changed, 1 insertion(+)
>>>
>>> diff --git a/block/nbd.c b/block/nbd.c
>>> index 5f18f78a94..d085554f21 100644
>>> --- a/block/nbd.c
>>> +++ b/block/nbd.c
>>> @@ -866,6 +866,7 @@ typedef struct NBDReplyChunkIter {
>>>   static void nbd_iter_channel_error(NBDReplyChunkIter *iter,
>>>                                      int ret, Error **local_err)
>>>   {
>>> +    assert(local_err && *local_err);
>> 
>> Why are we forbidding grandparent callers from passing NULL when they want to ignore an error?  We are called by several parent functions that get an errp from the grandparent, and use this function to do some common grunt work.  Let's look at the possibilities:
>> 
>> 1. grandparent passes address of a local error: we want to append to the error message, parent will then deal with the error how it wants (report it, ignore it, propagate it, whatever)
>> 
>> 2. grandparent passes &error_fatal: we want to append a hint, but before ERRP_AUTO_PROPAGATE, the parent has already exited.  After ERRP_AUTO_PROPAGATE, this looks like case 1.
>> 
>> 3. grandparent passes &error_abort: we should never be reached (failure earlier in the parent should have already aborted) - true whether or not ERRP_AUTO_PROPAGATE is applied
>> 
>> 4. grandparent passes NULL to ignore the error. Does not currently happen in any of the grandparent callers, because if it did, your assertion in this patch would now fire.  After ERRP_AUTO_PROPAGATE, this would look like case 1.
>> 
>> Would it be better to assert(!local_err || *local_err)?  The assertion as written is too strict without ERRP_AUTO_PROPAGATE, but you get away with it because none of the grandparents pass NULL; but is appropriate as written for after after the macro conversion so then we wonder if churn on the macro is worth it.
>
> We don't have any grandparents, this function is always called on local_err. And it's argument named local_err to stress it.
> The function is an API to report error, and it wants filled local_err object.
>
> It will crash anyway if local_err is NULL, as it dereferences it.

Yes.

We already assert ret < 0 explicitly, and we rely on !local_err
implicitly.  Making that explicit is obviously safe.

The code doesn't actually rely on !*local_err.  But when ret < 0, and
!local_err, surely local_err should point to an Error object.  Asserting
that makes sense to me.

> I just want to place an assertion at start of functions like this,
> which will be easily recognizable by coccinelle.

That's not a convincing argument.  Doesn't matter as long as we have
convincing ones :)

>
> ---
>
> We can improve the API, to support local_err==NULL, for the case when original request was called with
> errp==NULL, but for this we'll need more changes, like, pass errp to NBD_FOREACH_REPLY_CHUNK and save
> it into iter object...
>
> But how to detect it in code? Something like
>
>
> --- a/block/nbd.c
> +++ b/block/nbd.c
> @@ -1059,8 +1059,10 @@ static int nbd_co_receive_blockstatus_reply(BDRVNBDState *s,
>           case NBD_REPLY_TYPE_BLOCK_STATUS:
>               if (received) {
>                   nbd_channel_error(s, -EINVAL);
> -                error_setg(&local_err, "Several BLOCK_STATUS chunks in reply");
> -                nbd_iter_channel_error(&iter, -EINVAL, &local_err);
> +                if (errp) {
> +                    error_setg(&local_err, "Several BLOCK_STATUS chunks in reply");
> +                }
> +                nbd_iter_channel_error(&iter, -EINVAL, errp ? &local_err : NULL);
>               }
>               received = true;
>
>
> is ugly..
>
>
> So, to support original errp=NULL the whole thing should be refactored.. Not worth it, I think.

The only change I'd consider in addition to the assertion is this
simplification:

diff --git a/block/nbd.c b/block/nbd.c
index 5f18f78a94..7bbac1e5b8 100644
--- a/block/nbd.c
+++ b/block/nbd.c
@@ -870,11 +870,9 @@ static void nbd_iter_channel_error(NBDReplyChunkIter *iter,
 
     if (!iter->ret) {
         iter->ret = ret;
-        error_propagate(&iter->err, *local_err);
-    } else {
-        error_free(*local_err);
     }
 
+    error_propagate(&iter->err, *local_err);
     *local_err = NULL;
 }
 



  parent reply	other threads:[~2019-12-06 16:26 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-12-05 15:19 [PATCH v7 00/21] error: prepare for auto propagated local_err Vladimir Sementsov-Ogievskiy
2019-12-05 15:19 ` [PATCH v7 01/21] hw/core/loader-fit: fix freeing errp in fit_load_fdt Vladimir Sementsov-Ogievskiy
2019-12-05 15:20 ` [PATCH v7 02/21] net/net: Clean up variable shadowing in net_client_init() Vladimir Sementsov-Ogievskiy
2019-12-05 15:20 ` [PATCH v7 03/21] error: rename errp to errp_in where it is IN-argument Vladimir Sementsov-Ogievskiy
2019-12-05 17:03   ` Greg Kurz
2019-12-05 15:20 ` [PATCH v7 04/21] hmp: drop Error pointer indirection in hmp_handle_error Vladimir Sementsov-Ogievskiy
2019-12-05 15:20 ` [PATCH v7 05/21] vnc: drop Error pointer indirection in vnc_client_io_error Vladimir Sementsov-Ogievskiy
2019-12-05 15:20 ` [PATCH v7 06/21] qdev-monitor: well form error hint helpers Vladimir Sementsov-Ogievskiy
2019-12-05 16:58   ` Eric Blake
2019-12-05 17:02     ` Vladimir Sementsov-Ogievskiy
2019-12-05 15:20 ` [PATCH v7 07/21] ppc: well form kvmppc_hint_smt_possible error hint helper Vladimir Sementsov-Ogievskiy
2019-12-05 17:15   ` Greg Kurz
2019-12-06  0:02   ` David Gibson
2019-12-06 10:28     ` Vladimir Sementsov-Ogievskiy
2019-12-05 15:20 ` [PATCH v7 08/21] 9pfs: well form error hint helpers Vladimir Sementsov-Ogievskiy
2019-12-05 17:08   ` Greg Kurz
2019-12-05 17:13     ` Greg Kurz
2019-12-05 15:20 ` [PATCH v7 09/21] hw/core/qdev: cleanup Error ** variables Vladimir Sementsov-Ogievskiy
2019-12-05 15:20 ` [PATCH v7 10/21] block/snapshot: rename Error ** parameter to more common errp Vladimir Sementsov-Ogievskiy
2019-12-05 15:20 ` [PATCH v7 11/21] hw/i386/amd_iommu: " Vladimir Sementsov-Ogievskiy
2019-12-05 15:20 ` [PATCH v7 12/21] qga: " Vladimir Sementsov-Ogievskiy
2019-12-05 15:20 ` [PATCH v7 13/21] monitor/qmp-cmds: " Vladimir Sementsov-Ogievskiy
2019-12-05 15:20 ` [PATCH v7 14/21] hw/s390x: " Vladimir Sementsov-Ogievskiy
2019-12-05 15:20 ` [PATCH v7 15/21] hw/sd: drop extra whitespace in sdhci_sysbus_realize() header Vladimir Sementsov-Ogievskiy
2019-12-05 15:20 ` [PATCH v7 16/21] hw/tpm: rename Error ** parameter to more common errp Vladimir Sementsov-Ogievskiy
2019-12-05 15:20 ` [PATCH v7 17/21] hw/usb: " Vladimir Sementsov-Ogievskiy
2019-12-05 15:20 ` [PATCH v7 18/21] include/qom/object.h: " Vladimir Sementsov-Ogievskiy
2019-12-05 15:20 ` [PATCH v7 19/21] backends/cryptodev: drop local_err from cryptodev_backend_complete() Vladimir Sementsov-Ogievskiy
2019-12-05 15:20 ` [PATCH v7 20/21] hw/vfio/ap: drop local_err from vfio_ap_realize Vladimir Sementsov-Ogievskiy
2019-12-05 16:09   ` Cornelia Huck
2019-12-05 15:20 ` [PATCH v7 21/21] nbd: assert that Error** is not NULL in nbd_iter_channel_error Vladimir Sementsov-Ogievskiy
2019-12-05 17:14   ` Eric Blake
2019-12-05 17:39     ` Vladimir Sementsov-Ogievskiy
2019-12-05 17:49       ` Eric Blake
2019-12-05 18:09         ` Vladimir Sementsov-Ogievskiy
2019-12-05 19:56           ` Eric Blake
2019-12-06  8:54       ` Markus Armbruster [this message]
2019-12-06 10:26         ` Vladimir Sementsov-Ogievskiy
2019-12-05 15:26 ` [PATCH v7 00/21] error: prepare for auto propagated local_err Cornelia Huck
2019-12-05 16:03   ` Vladimir Sementsov-Ogievskiy
2019-12-06  8:44     ` Markus Armbruster

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87sglxltqb.fsf@dusky.pond.sub.org \
    --to=armbru@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=mreitz@redhat.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=vsementsov@virtuozzo.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).