qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH] qom: abort on error in property setter if caller passed errp == NULL
@ 2013-11-28  1:24 Igor Mammedov
  2013-11-28  4:58 ` Eric Blake
                   ` (2 more replies)
  0 siblings, 3 replies; 15+ messages in thread
From: Igor Mammedov @ 2013-11-28  1:24 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, peter.crosthwaite, afaerber, anthony, mst

in case if caller setting property doesn't care about error and
passes in NULL as errp argument but error occurs in property setter,
it is silently discarded leaving object in undefined state.

As result it leads to hard to find bugs, so if caller doesn't
care about error it must be sure that property exists and
accepts provided value, otherwise it's better to abort early
since error case couldn't be handled gracefully and find
invalid usecase early.

In addition multitude of property setters will be always
guarantied to have error object present and won't be required
to handle this condition individually.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 qom/object.c | 19 ++++++++++++++-----
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/qom/object.c b/qom/object.c
index fc19cf6..2c0bb64 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -792,16 +792,25 @@ void object_property_get(Object *obj, Visitor *v, const char *name,
 void object_property_set(Object *obj, Visitor *v, const char *name,
                          Error **errp)
 {
-    ObjectProperty *prop = object_property_find(obj, name, errp);
-    if (prop == NULL) {
-        return;
+    Error *local_error = NULL;
+    ObjectProperty *prop = object_property_find(obj, name, &local_error);
+    if (local_error) {
+        goto out;
     }
 
     if (!prop->set) {
-        error_set(errp, QERR_PERMISSION_DENIED);
+        error_set(&local_error, QERR_PERMISSION_DENIED);
     } else {
-        prop->set(obj, v, prop->opaque, name, errp);
+        prop->set(obj, v, prop->opaque, name, &local_error);
     }
+out:
+    if (local_error) {
+        if (!errp) {
+            assert_no_error(local_error);
+        }
+        error_propagate(errp, local_error);
+    }
+
 }
 
 void object_property_set_str(Object *obj, const char *value,
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [Qemu-devel] [PATCH] qom: abort on error in property setter if caller passed errp == NULL
  2013-11-28  1:24 [Qemu-devel] [PATCH] qom: abort on error in property setter if caller passed errp == NULL Igor Mammedov
@ 2013-11-28  4:58 ` Eric Blake
  2013-11-28 13:01   ` Igor Mammedov
  2013-11-28  5:10 ` Peter Crosthwaite
  2013-11-28 13:42 ` Andreas Färber
  2 siblings, 1 reply; 15+ messages in thread
From: Eric Blake @ 2013-11-28  4:58 UTC (permalink / raw)
  To: Igor Mammedov, qemu-devel
  Cc: pbonzini, peter.crosthwaite, afaerber, anthony, mst

[-- Attachment #1: Type: text/plain, Size: 1276 bytes --]

On 11/27/2013 06:24 PM, Igor Mammedov wrote:
> in case if caller setting property doesn't care about error and
> passes in NULL as errp argument but error occurs in property setter,
> it is silently discarded leaving object in undefined state.
> 
> As result it leads to hard to find bugs, so if caller doesn't
> care about error it must be sure that property exists and
> accepts provided value, otherwise it's better to abort early
> since error case couldn't be handled gracefully and find
> invalid usecase early.
> 
> In addition multitude of property setters will be always
> guarantied to have error object present and won't be required

s/guarantied/guaranteed/

> to handle this condition individually.
> 
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> ---

> +out:
> +    if (local_error) {

This says local_error was set...

> +        if (!errp) {
> +            assert_no_error(local_error);

so this assert_no_error() is dead code in its current position.  To be
useful, you probably want:

if (!errp) {
    assert_no_error(local_error);
} else if (local_error) {
    error_propagate(errp, local_error);
}

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 621 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Qemu-devel] [PATCH] qom: abort on error in property setter if caller passed errp == NULL
  2013-11-28  1:24 [Qemu-devel] [PATCH] qom: abort on error in property setter if caller passed errp == NULL Igor Mammedov
  2013-11-28  4:58 ` Eric Blake
@ 2013-11-28  5:10 ` Peter Crosthwaite
  2013-11-28  7:53   ` Markus Armbruster
  2013-11-28 13:23   ` Igor Mammedov
  2013-11-28 13:42 ` Andreas Färber
  2 siblings, 2 replies; 15+ messages in thread
From: Peter Crosthwaite @ 2013-11-28  5:10 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: Paolo Bonzini, Michael S. Tsirkin,
	qemu-devel@nongnu.org Developers, Anthony Liguori,
	Andreas Färber

Hi,

On Thu, Nov 28, 2013 at 11:24 AM, Igor Mammedov <imammedo@redhat.com> wrote:
> in case if caller setting property doesn't care about error and
> passes in NULL as errp argument but error occurs in property setter,
> it is silently discarded leaving object in undefined state.
>
> As result it leads to hard to find bugs, so if caller doesn't
> care about error it must be sure that property exists and
> accepts provided value, otherwise it's better to abort early
> since error case couldn't be handled gracefully and find
> invalid usecase early.
>
> In addition multitude of property setters will be always
> guarantied to have error object present and won't be required
> to handle this condition individually.
>

So there seems to be contention between different APIs and use cases
on what to do in the NULL case. Personally, I'm of the opinion that
NULL should be a silent don't care policy. But you are right in that
checking every API call at call site is cumbersome, and its better to
have some sort of collective mechanism to implement different policys.
I think this can be done caller side efficiently by having a special
Error * that can be passed in that tells the error API to assert or
error raise.

extern error *abort_on_err;

And update your call sites to do this:

object_property_set(Foo, bar, "baz", &abort_on_err);

Error_set and friends are then taught to recognise abort_on_err and
abort accordingly and theres no need for this form of change pattern -
its all solved in the error API.

You can also implement a range of automatic error handling policies e.g:

extern Error *report_err; /* report any errors to monitor/stdout */

To report an error without the assertion.

Regards,
Peter

> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> ---
>  qom/object.c | 19 ++++++++++++++-----
>  1 file changed, 14 insertions(+), 5 deletions(-)
>
> diff --git a/qom/object.c b/qom/object.c
> index fc19cf6..2c0bb64 100644
> --- a/qom/object.c
> +++ b/qom/object.c
> @@ -792,16 +792,25 @@ void object_property_get(Object *obj, Visitor *v, const char *name,
>  void object_property_set(Object *obj, Visitor *v, const char *name,
>                           Error **errp)
>  {
> -    ObjectProperty *prop = object_property_find(obj, name, errp);
> -    if (prop == NULL) {
> -        return;
> +    Error *local_error = NULL;
> +    ObjectProperty *prop = object_property_find(obj, name, &local_error);
> +    if (local_error) {
> +        goto out;
>      }
>
>      if (!prop->set) {
> -        error_set(errp, QERR_PERMISSION_DENIED);
> +        error_set(&local_error, QERR_PERMISSION_DENIED);
>      } else {
> -        prop->set(obj, v, prop->opaque, name, errp);
> +        prop->set(obj, v, prop->opaque, name, &local_error);
>      }
> +out:
> +    if (local_error) {
> +        if (!errp) {
> +            assert_no_error(local_error);
> +        }
> +        error_propagate(errp, local_error);
> +    }
> +
>  }
>
>  void object_property_set_str(Object *obj, const char *value,
> --
> 1.8.3.1
>
>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Qemu-devel] [PATCH] qom: abort on error in property setter if caller passed errp == NULL
  2013-11-28  5:10 ` Peter Crosthwaite
@ 2013-11-28  7:53   ` Markus Armbruster
  2013-11-28 13:23   ` Igor Mammedov
  1 sibling, 0 replies; 15+ messages in thread
From: Markus Armbruster @ 2013-11-28  7:53 UTC (permalink / raw)
  To: Peter Crosthwaite
  Cc: Michael S. Tsirkin, qemu-devel@nongnu.org Developers,
	Anthony Liguori, Paolo Bonzini, Igor Mammedov,
	Andreas Färber

Peter Crosthwaite <peter.crosthwaite@xilinx.com> writes:

> Hi,
>
> On Thu, Nov 28, 2013 at 11:24 AM, Igor Mammedov <imammedo@redhat.com> wrote:
>> in case if caller setting property doesn't care about error and
>> passes in NULL as errp argument but error occurs in property setter,
>> it is silently discarded leaving object in undefined state.
>>
>> As result it leads to hard to find bugs, so if caller doesn't
>> care about error it must be sure that property exists and
>> accepts provided value, otherwise it's better to abort early
>> since error case couldn't be handled gracefully and find
>> invalid usecase early.
>>
>> In addition multitude of property setters will be always
>> guarantied to have error object present and won't be required
>> to handle this condition individually.
>>
>
> So there seems to be contention between different APIs and use cases
> on what to do in the NULL case. Personally, I'm of the opinion that
> NULL should be a silent don't care policy. But you are right in that
> checking every API call at call site is cumbersome, and its better to
> have some sort of collective mechanism to implement different policys.
> I think this can be done caller side efficiently by having a special
> Error * that can be passed in that tells the error API to assert or
> error raise.
>
> extern error *abort_on_err;
>
> And update your call sites to do this:
>
> object_property_set(Foo, bar, "baz", &abort_on_err);
>
> Error_set and friends are then taught to recognise abort_on_err and
> abort accordingly and theres no need for this form of change pattern -
> its all solved in the error API.

The existing practice is to have a pair of functions, like this one:

    Foo *foo(int arg, Error **errp)
    {
    ...
    }

    Foo *foo_nofail(int arg)
    {
        Error *local_err = NULL;
        Foo *f = foo(arg, &local_err);
        assert_no_error(local_err);
        return f;
    }

The asserting function's name is intentionally longer.

Passing NULL is still temptingly short.  Code review has to catch abuse
of it.

Your proposal is more flexible.  If we adopt it, we may want to retire
the _nofail idiom.

> You can also implement a range of automatic error handling policies e.g:
>
> extern Error *report_err; /* report any errors to monitor/stdout */
>
> To report an error without the assertion.

monitor/stderr, you mean.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Qemu-devel] [PATCH] qom: abort on error in property setter if caller passed errp == NULL
  2013-11-28  4:58 ` Eric Blake
@ 2013-11-28 13:01   ` Igor Mammedov
  0 siblings, 0 replies; 15+ messages in thread
From: Igor Mammedov @ 2013-11-28 13:01 UTC (permalink / raw)
  To: Eric Blake
  Cc: peter.crosthwaite, mst, qemu-devel, anthony, pbonzini, afaerber

On Wed, 27 Nov 2013 21:58:18 -0700
Eric Blake <eblake@redhat.com> wrote:

> On 11/27/2013 06:24 PM, Igor Mammedov wrote:
> > in case if caller setting property doesn't care about error and
> > passes in NULL as errp argument but error occurs in property setter,
> > it is silently discarded leaving object in undefined state.
> > 
> > As result it leads to hard to find bugs, so if caller doesn't
> > care about error it must be sure that property exists and
> > accepts provided value, otherwise it's better to abort early
> > since error case couldn't be handled gracefully and find
> > invalid usecase early.
> > 
> > In addition multitude of property setters will be always
> > guarantied to have error object present and won't be required
> 
> s/guarantied/guaranteed/
thanks, I'll fix it.

> 
> > to handle this condition individually.
> > 
> > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > ---
> 
> > +out:
> > +    if (local_error) {
> 
> This says local_error was set...
> 
> > +        if (!errp) {
> > +            assert_no_error(local_error);
> 
> so this assert_no_error() is dead code in its current position.  To be
> useful, you probably want:
it is not, retested it again and it still fails when errp == NULL but
there is a error in local_error.

> 
> if (!errp) {
>     assert_no_error(local_error);
> } else if (local_error) {
>     error_propagate(errp, local_error);
> }
this's just another way to do the same thing.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Qemu-devel] [PATCH] qom: abort on error in property setter if caller passed errp == NULL
  2013-11-28  5:10 ` Peter Crosthwaite
  2013-11-28  7:53   ` Markus Armbruster
@ 2013-11-28 13:23   ` Igor Mammedov
  2013-11-28 13:41     ` Paolo Bonzini
  2013-11-28 15:00     ` Markus Armbruster
  1 sibling, 2 replies; 15+ messages in thread
From: Igor Mammedov @ 2013-11-28 13:23 UTC (permalink / raw)
  To: Peter Crosthwaite
  Cc: Paolo Bonzini, Michael S. Tsirkin,
	qemu-devel@nongnu.org Developers, Anthony Liguori,
	Andreas Färber

On Thu, 28 Nov 2013 15:10:50 +1000
Peter Crosthwaite <peter.crosthwaite@xilinx.com> wrote:

> Hi,
> 
> On Thu, Nov 28, 2013 at 11:24 AM, Igor Mammedov <imammedo@redhat.com> wrote:
> > in case if caller setting property doesn't care about error and
> > passes in NULL as errp argument but error occurs in property setter,
> > it is silently discarded leaving object in undefined state.
> >
> > As result it leads to hard to find bugs, so if caller doesn't
> > care about error it must be sure that property exists and
> > accepts provided value, otherwise it's better to abort early
> > since error case couldn't be handled gracefully and find
> > invalid usecase early.
> >
> > In addition multitude of property setters will be always
> > guarantied to have error object present and won't be required
> > to handle this condition individually.
> >
> 
> So there seems to be contention between different APIs and use cases
> on what to do in the NULL case. Personally, I'm of the opinion that
> NULL should be a silent don't care policy. But you are right in that
If caller doesn't care about setting property was successful, it perhaps
shouldn't call property setter at all or pass a dummy errp for special
case if he really doesn't care about error (I can't really come up with
use case though).

Otherwise there is chance that property setter fails and object won't be
in state it's supposed to be. If developer passes NULL for errp, that
should mean that he is sure call will succeed, if it fails/aborts
developer will find about error much earlier than when in field deployment
starts misbehaving in unpredicable way.

Doing it in object_property_set() also would allow
to remove a bunch of duplicate code like:
Error *err = NULL;
...
assert_no_error(err);

in device_post_init(), qdev_prop_set_...() and other places


> checking every API call at call site is cumbersome, and its better to
> have some sort of collective mechanism to implement different policys.
> I think this can be done caller side efficiently by having a special
> Error * that can be passed in that tells the error API to assert or
> error raise.
> 
> extern error *abort_on_err;
> 
> And update your call sites to do this:
> 
> object_property_set(Foo, bar, "baz", &abort_on_err);
that is just another way to put burden on caller, instead of doing it
in one place.

> 
> Error_set and friends are then taught to recognise abort_on_err and
> abort accordingly and theres no need for this form of change pattern -
> its all solved in the error API.
> 
> You can also implement a range of automatic error handling policies e.g:
> 
> extern Error *report_err; /* report any errors to monitor/stdout */
> 
> To report an error without the assertion.
> 
> Regards,
> Peter
> 
> > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > ---
> >  qom/object.c | 19 ++++++++++++++-----
> >  1 file changed, 14 insertions(+), 5 deletions(-)
> >
> > diff --git a/qom/object.c b/qom/object.c
> > index fc19cf6..2c0bb64 100644
> > --- a/qom/object.c
> > +++ b/qom/object.c
> > @@ -792,16 +792,25 @@ void object_property_get(Object *obj, Visitor *v, const char *name,
> >  void object_property_set(Object *obj, Visitor *v, const char *name,
> >                           Error **errp)
> >  {
> > -    ObjectProperty *prop = object_property_find(obj, name, errp);
> > -    if (prop == NULL) {
> > -        return;
> > +    Error *local_error = NULL;
> > +    ObjectProperty *prop = object_property_find(obj, name, &local_error);
> > +    if (local_error) {
> > +        goto out;
> >      }
> >
> >      if (!prop->set) {
> > -        error_set(errp, QERR_PERMISSION_DENIED);
> > +        error_set(&local_error, QERR_PERMISSION_DENIED);
> >      } else {
> > -        prop->set(obj, v, prop->opaque, name, errp);
> > +        prop->set(obj, v, prop->opaque, name, &local_error);
> >      }
> > +out:
> > +    if (local_error) {
> > +        if (!errp) {
> > +            assert_no_error(local_error);
> > +        }
> > +        error_propagate(errp, local_error);
> > +    }
> > +
> >  }
> >
> >  void object_property_set_str(Object *obj, const char *value,
> > --
> > 1.8.3.1
> >
> >

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Qemu-devel] [PATCH] qom: abort on error in property setter if caller passed errp == NULL
  2013-11-28 13:23   ` Igor Mammedov
@ 2013-11-28 13:41     ` Paolo Bonzini
  2013-11-28 15:03       ` Markus Armbruster
  2013-11-28 15:00     ` Markus Armbruster
  1 sibling, 1 reply; 15+ messages in thread
From: Paolo Bonzini @ 2013-11-28 13:41 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: Peter Crosthwaite, Michael S. Tsirkin,
	qemu-devel@nongnu.org Developers, Anthony Liguori,
	Andreas Färber

Il 28/11/2013 14:23, Igor Mammedov ha scritto:
> > object_property_set(Foo, bar, "baz", &abort_on_err);
> 
> that is just another way to put burden on caller, instead of doing it
> in one place.

It's also much more self-documenting.

The problem is that there is one very good case where you want the
silent-don't-care behavior: when you don't care about the exact error,
and you can figure out whether there was an error from the returned
value of the function.  This doesn't apply to object_property_set of
course, but it is the reason why NULL Error* has silent-don't-care behavior.

Now, let's look at the alternatives:

* keep silent don't care
  + consistent
  + predictable
  - not always handy

* only modify object_property_set
  + mostly does the right thing
  - inconsistent with other Error* functions
  - inconsistent with _nofail functions

* Peter's alternative
  + self-documenting
  + consistent
  + predictable

* make Error* mandatory for all void functions
  + consistent
  + almost predictable (because in C you can ignore return values)
  - not necessarily does the right thing (e.g. cleanup functions)
  - requires manual effort to abide to the policy

I vote for Peter's proposal, or for adding object_property_set_nofail.
No particular preference.

Another variant: modify object_property_set to add a g_warning.  I think
it's fine.  It reduces the inconsistency, and still simplifies debugging.

Paolo

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Qemu-devel] [PATCH] qom: abort on error in property setter if caller passed errp == NULL
  2013-11-28  1:24 [Qemu-devel] [PATCH] qom: abort on error in property setter if caller passed errp == NULL Igor Mammedov
  2013-11-28  4:58 ` Eric Blake
  2013-11-28  5:10 ` Peter Crosthwaite
@ 2013-11-28 13:42 ` Andreas Färber
  2013-11-28 13:48   ` Igor Mammedov
  2 siblings, 1 reply; 15+ messages in thread
From: Andreas Färber @ 2013-11-28 13:42 UTC (permalink / raw)
  To: Igor Mammedov, qemu-devel
  Cc: Peter Maydell, peter.crosthwaite, mst, Markus Armbruster, anthony,
	pbonzini

Am 28.11.2013 02:24, schrieb Igor Mammedov:
> in case if caller setting property doesn't care about error and
> passes in NULL as errp argument but error occurs in property setter,
> it is silently discarded leaving object in undefined state.
> 
> As result it leads to hard to find bugs, so if caller doesn't
> care about error it must be sure that property exists and
> accepts provided value, otherwise it's better to abort early
> since error case couldn't be handled gracefully and find
> invalid usecase early.
> 
> In addition multitude of property setters will be always
> guarantied to have error object present and won't be required
> to handle this condition individually.
> 
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> ---
>  qom/object.c | 19 ++++++++++++++-----
>  1 file changed, 14 insertions(+), 5 deletions(-)
> 
> diff --git a/qom/object.c b/qom/object.c
> index fc19cf6..2c0bb64 100644
> --- a/qom/object.c
> +++ b/qom/object.c
> @@ -792,16 +792,25 @@ void object_property_get(Object *obj, Visitor *v, const char *name,
>  void object_property_set(Object *obj, Visitor *v, const char *name,
>                           Error **errp)
>  {
> -    ObjectProperty *prop = object_property_find(obj, name, errp);
> -    if (prop == NULL) {
> -        return;
> +    Error *local_error = NULL;
> +    ObjectProperty *prop = object_property_find(obj, name, &local_error);
> +    if (local_error) {
> +        goto out;
>      }
>  
>      if (!prop->set) {
> -        error_set(errp, QERR_PERMISSION_DENIED);
> +        error_set(&local_error, QERR_PERMISSION_DENIED);
>      } else {
> -        prop->set(obj, v, prop->opaque, name, errp);
> +        prop->set(obj, v, prop->opaque, name, &local_error);
>      }
> +out:
> +    if (local_error) {
> +        if (!errp) {
> +            assert_no_error(local_error);
> +        }
> +        error_propagate(errp, local_error);
> +    }
> +
>  }
>  
>  void object_property_set_str(Object *obj, const char *value,

Aborting on NULL errp considered dangerous by me.

This function seems to work just fine with NULL errp, so your focus
seems to be on the callers.

Promoting *not* to abort has been one appeal of the new QOM-style APIs
to me, so making this implicitly assert feels like a step backwards.
The old qdev_prop_set_*() API, which most users are still using, does
assert, as discussed with PMM recently.

Also, why only for setting properties? Either all or none should behave
like this - and I guess none is going to be easier to achieve.
For instance, adding dynamic properties is a use case where in
instance_init I've seen NULL errp passed in (because instance_init API
cannot fail).

I will be more than happy to review and apply your patch (or contribute
further ones) going through (mis)uses of error_is_set().

Regards,
Andreas

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Qemu-devel] [PATCH] qom: abort on error in property setter if caller passed errp == NULL
  2013-11-28 13:42 ` Andreas Färber
@ 2013-11-28 13:48   ` Igor Mammedov
  2013-11-28 14:00     ` Andreas Färber
  0 siblings, 1 reply; 15+ messages in thread
From: Igor Mammedov @ 2013-11-28 13:48 UTC (permalink / raw)
  To: Andreas Färber
  Cc: Peter Maydell, peter.crosthwaite, mst, qemu-devel,
	Markus Armbruster, anthony, pbonzini

On Thu, 28 Nov 2013 14:42:38 +0100
Andreas Färber <afaerber@suse.de> wrote:

> Am 28.11.2013 02:24, schrieb Igor Mammedov:
> > in case if caller setting property doesn't care about error and
> > passes in NULL as errp argument but error occurs in property setter,
> > it is silently discarded leaving object in undefined state.
> > 
> > As result it leads to hard to find bugs, so if caller doesn't
> > care about error it must be sure that property exists and
> > accepts provided value, otherwise it's better to abort early
> > since error case couldn't be handled gracefully and find
> > invalid usecase early.
> > 
> > In addition multitude of property setters will be always
> > guarantied to have error object present and won't be required
> > to handle this condition individually.
> > 
> > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > ---
> >  qom/object.c | 19 ++++++++++++++-----
> >  1 file changed, 14 insertions(+), 5 deletions(-)
> > 
> > diff --git a/qom/object.c b/qom/object.c
> > index fc19cf6..2c0bb64 100644
> > --- a/qom/object.c
> > +++ b/qom/object.c
> > @@ -792,16 +792,25 @@ void object_property_get(Object *obj, Visitor *v, const char *name,
> >  void object_property_set(Object *obj, Visitor *v, const char *name,
> >                           Error **errp)
> >  {
> > -    ObjectProperty *prop = object_property_find(obj, name, errp);
> > -    if (prop == NULL) {
> > -        return;
> > +    Error *local_error = NULL;
> > +    ObjectProperty *prop = object_property_find(obj, name, &local_error);
> > +    if (local_error) {
> > +        goto out;
> >      }
> >  
> >      if (!prop->set) {
> > -        error_set(errp, QERR_PERMISSION_DENIED);
> > +        error_set(&local_error, QERR_PERMISSION_DENIED);
> >      } else {
> > -        prop->set(obj, v, prop->opaque, name, errp);
> > +        prop->set(obj, v, prop->opaque, name, &local_error);
> >      }
> > +out:
> > +    if (local_error) {
> > +        if (!errp) {
> > +            assert_no_error(local_error);
> > +        }
> > +        error_propagate(errp, local_error);
> > +    }
> > +
> >  }
> >  
> >  void object_property_set_str(Object *obj, const char *value,
> 
> Aborting on NULL errp considered dangerous by me.
> 
> This function seems to work just fine with NULL errp, so your focus
> seems to be on the callers.
> 
> Promoting *not* to abort has been one appeal of the new QOM-style APIs
> to me, so making this implicitly assert feels like a step backwards.
> The old qdev_prop_set_*() API, which most users are still using, does
> assert, as discussed with PMM recently.
> 
> Also, why only for setting properties? Either all or none should behave
> like this - and I guess none is going to be easier to achieve.
> For instance, adding dynamic properties is a use case where in
> instance_init I've seen NULL errp passed in (because instance_init API
> cannot fail).
> 
> I will be more than happy to review and apply your patch (or contribute
> further ones) going through (mis)uses of error_is_set().
I've sent such one for target-i386/cpu.c see last patch in x86-properties.v10,
I've posted today.

> 
> Regards,
> Andreas
> 

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Qemu-devel] [PATCH] qom: abort on error in property setter if caller passed errp == NULL
  2013-11-28 13:48   ` Igor Mammedov
@ 2013-11-28 14:00     ` Andreas Färber
  0 siblings, 0 replies; 15+ messages in thread
From: Andreas Färber @ 2013-11-28 14:00 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: Peter Maydell, peter.crosthwaite, mst, qemu-devel,
	Markus Armbruster, anthony, pbonzini

Am 28.11.2013 14:48, schrieb Igor Mammedov:
> On Thu, 28 Nov 2013 14:42:38 +0100
> Andreas Färber <afaerber@suse.de> wrote:
> 
>> I will be more than happy to review and apply your patch (or contribute
>> further ones) going through (mis)uses of error_is_set().
> I've sent such one for target-i386/cpu.c see last patch in x86-properties.v10,
> I've posted today.

Yes, that's what I meant with "your patch". :-)

Andreas

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Qemu-devel] [PATCH] qom: abort on error in property setter if caller passed errp == NULL
  2013-11-28 13:23   ` Igor Mammedov
  2013-11-28 13:41     ` Paolo Bonzini
@ 2013-11-28 15:00     ` Markus Armbruster
  1 sibling, 0 replies; 15+ messages in thread
From: Markus Armbruster @ 2013-11-28 15:00 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: Peter Crosthwaite, Michael S. Tsirkin,
	qemu-devel@nongnu.org Developers, Anthony Liguori, Paolo Bonzini,
	Andreas Färber

Igor Mammedov <imammedo@redhat.com> writes:

> On Thu, 28 Nov 2013 15:10:50 +1000
> Peter Crosthwaite <peter.crosthwaite@xilinx.com> wrote:
>
>> Hi,
>> 
>> On Thu, Nov 28, 2013 at 11:24 AM, Igor Mammedov <imammedo@redhat.com> wrote:
>> > in case if caller setting property doesn't care about error and
>> > passes in NULL as errp argument but error occurs in property setter,
>> > it is silently discarded leaving object in undefined state.
>> >
>> > As result it leads to hard to find bugs, so if caller doesn't
>> > care about error it must be sure that property exists and
>> > accepts provided value, otherwise it's better to abort early
>> > since error case couldn't be handled gracefully and find
>> > invalid usecase early.
>> >
>> > In addition multitude of property setters will be always
>> > guarantied to have error object present and won't be required
>> > to handle this condition individually.
>> >
>> 
>> So there seems to be contention between different APIs and use cases
>> on what to do in the NULL case. Personally, I'm of the opinion that
>> NULL should be a silent don't care policy. But you are right in that
> If caller doesn't care about setting property was successful, it perhaps
> shouldn't call property setter at all or pass a dummy errp for special
> case if he really doesn't care about error (I can't really come up with
> use case though).
>
> Otherwise there is chance that property setter fails and object won't be
> in state it's supposed to be. If developer passes NULL for errp, that
> should mean that he is sure call will succeed, if it fails/aborts
> developer will find about error much earlier than when in field deployment
> starts misbehaving in unpredicable way.

When you're sure the call can't fail, you really, really want an
assertion failure when it does.

There's a use for "I don't want an error object, thank you": when you
can detect failure in another way, say return value, and aren't
interested in details, and the notational overhead that comes with it.

This case is distinct from "I know this can't fail".

[...]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Qemu-devel] [PATCH] qom: abort on error in property setter if caller passed errp == NULL
  2013-11-28 13:41     ` Paolo Bonzini
@ 2013-11-28 15:03       ` Markus Armbruster
  2013-11-29  0:21         ` Peter Crosthwaite
  0 siblings, 1 reply; 15+ messages in thread
From: Markus Armbruster @ 2013-11-28 15:03 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: Peter Crosthwaite, Michael S. Tsirkin,
	qemu-devel@nongnu.org Developers, Anthony Liguori, Igor Mammedov,
	Andreas Färber

Paolo Bonzini <pbonzini@redhat.com> writes:

> Il 28/11/2013 14:23, Igor Mammedov ha scritto:
>> > object_property_set(Foo, bar, "baz", &abort_on_err);
>> 
>> that is just another way to put burden on caller, instead of doing it
>> in one place.
>
> It's also much more self-documenting.
>
> The problem is that there is one very good case where you want the
> silent-don't-care behavior: when you don't care about the exact error,
> and you can figure out whether there was an error from the returned
> value of the function.  This doesn't apply to object_property_set of
> course, but it is the reason why NULL Error* has silent-don't-care behavior.
>
> Now, let's look at the alternatives:
>
> * keep silent don't care
>   + consistent
>   + predictable
>   - not always handy
>
> * only modify object_property_set
>   + mostly does the right thing
>   - inconsistent with other Error* functions
>   - inconsistent with _nofail functions
>
> * Peter's alternative
>   + self-documenting
>   + consistent
>   + predictable
>
> * make Error* mandatory for all void functions
>   + consistent
>   + almost predictable (because in C you can ignore return values)
>   - not necessarily does the right thing (e.g. cleanup functions)
>   - requires manual effort to abide to the policy
>
> I vote for Peter's proposal, or for adding object_property_set_nofail.
> No particular preference.
>
> Another variant: modify object_property_set to add a g_warning.  I think
> it's fine.  It reduces the inconsistency, and still simplifies debugging.

I like Peter's proposal, provided we use it to get rid of the _nofail
pattern.

Second preference is adding another _nofail wrapper.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Qemu-devel] [PATCH] qom: abort on error in property setter if caller passed errp == NULL
  2013-11-28 15:03       ` Markus Armbruster
@ 2013-11-29  0:21         ` Peter Crosthwaite
  2013-11-29  7:56           ` Markus Armbruster
  0 siblings, 1 reply; 15+ messages in thread
From: Peter Crosthwaite @ 2013-11-29  0:21 UTC (permalink / raw)
  To: Markus Armbruster
  Cc: Michael S. Tsirkin, qemu-devel@nongnu.org Developers,
	Anthony Liguori, Igor Mammedov, Paolo Bonzini,
	Andreas Färber

On Fri, Nov 29, 2013 at 1:03 AM, Markus Armbruster <armbru@redhat.com> wrote:
> Paolo Bonzini <pbonzini@redhat.com> writes:
>
>> Il 28/11/2013 14:23, Igor Mammedov ha scritto:
>>> > object_property_set(Foo, bar, "baz", &abort_on_err);
>>>
>>> that is just another way to put burden on caller, instead of doing it
>>> in one place.
>>
>> It's also much more self-documenting.
>>
>> The problem is that there is one very good case where you want the
>> silent-don't-care behavior: when you don't care about the exact error,
>> and you can figure out whether there was an error from the returned
>> value of the function.  This doesn't apply to object_property_set of
>> course, but it is the reason why NULL Error* has silent-don't-care behavior.
>>
>> Now, let's look at the alternatives:
>>
>> * keep silent don't care
>>   + consistent
>>   + predictable
>>   - not always handy
>>
>> * only modify object_property_set
>>   + mostly does the right thing
>>   - inconsistent with other Error* functions
>>   - inconsistent with _nofail functions
>>
>> * Peter's alternative
>>   + self-documenting
>>   + consistent
>>   + predictable
>>
>> * make Error* mandatory for all void functions
>>   + consistent
>>   + almost predictable (because in C you can ignore return values)
>>   - not necessarily does the right thing (e.g. cleanup functions)
>>   - requires manual effort to abide to the policy
>>
>> I vote for Peter's proposal, or for adding object_property_set_nofail.
>> No particular preference.
>>
>> Another variant: modify object_property_set to add a g_warning.  I think
>> it's fine.  It reduces the inconsistency, and still simplifies debugging.
>
> I like Peter's proposal, provided we use it to get rid of the _nofail
> pattern.
>
> Second preference is adding another _nofail wrapper.
>

So this issue with _nofail is that if you are doing it properly, every
API needed both normal and _nofail version of every function. APIs
generally have no bussiness dictating failure policy so by extension,
normal and _nofail should exist for every API that accepts an Error *.
With my proposal, its fixed once, in one place and we can torch all
the _nofail boilerplate all over the tree as you have suggested.

These is another subtle advantage to my proposal, and that is that
assertions can happen at the point of failure in the offending API,
not after the fact in the caller. If the caller does an
assert_no_error, then the abort() happens after return from the API
call. This makes debugging awkward cause the stack frames into the API
call where the issue actually occured are lost. Whereas if error_set
does the abort() you will get all stack frames into the API call where
the issue occured when gdb traps the abort().

Regards,
Peter

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Qemu-devel] [PATCH] qom: abort on error in property setter if caller passed errp == NULL
  2013-11-29  0:21         ` Peter Crosthwaite
@ 2013-11-29  7:56           ` Markus Armbruster
  2013-12-03  5:51             ` Peter Crosthwaite
  0 siblings, 1 reply; 15+ messages in thread
From: Markus Armbruster @ 2013-11-29  7:56 UTC (permalink / raw)
  To: Peter Crosthwaite
  Cc: Michael S. Tsirkin, qemu-devel@nongnu.org Developers,
	Anthony Liguori, Igor Mammedov, Paolo Bonzini,
	Andreas Färber

Peter Crosthwaite <peter.crosthwaite@xilinx.com> writes:

> On Fri, Nov 29, 2013 at 1:03 AM, Markus Armbruster <armbru@redhat.com> wrote:
>> Paolo Bonzini <pbonzini@redhat.com> writes:
>>
>>> Il 28/11/2013 14:23, Igor Mammedov ha scritto:
>>>> > object_property_set(Foo, bar, "baz", &abort_on_err);
>>>>
>>>> that is just another way to put burden on caller, instead of doing it
>>>> in one place.
>>>
>>> It's also much more self-documenting.
>>>
>>> The problem is that there is one very good case where you want the
>>> silent-don't-care behavior: when you don't care about the exact error,
>>> and you can figure out whether there was an error from the returned
>>> value of the function.  This doesn't apply to object_property_set of
>>> course, but it is the reason why NULL Error* has silent-don't-care behavior.
>>>
>>> Now, let's look at the alternatives:
>>>
>>> * keep silent don't care
>>>   + consistent
>>>   + predictable
>>>   - not always handy
>>>
>>> * only modify object_property_set
>>>   + mostly does the right thing
>>>   - inconsistent with other Error* functions
>>>   - inconsistent with _nofail functions
>>>
>>> * Peter's alternative
>>>   + self-documenting
>>>   + consistent
>>>   + predictable
>>>
>>> * make Error* mandatory for all void functions
>>>   + consistent
>>>   + almost predictable (because in C you can ignore return values)
>>>   - not necessarily does the right thing (e.g. cleanup functions)
>>>   - requires manual effort to abide to the policy
>>>
>>> I vote for Peter's proposal, or for adding object_property_set_nofail.
>>> No particular preference.
>>>
>>> Another variant: modify object_property_set to add a g_warning.  I think
>>> it's fine.  It reduces the inconsistency, and still simplifies debugging.
>>
>> I like Peter's proposal, provided we use it to get rid of the _nofail
>> pattern.
>>
>> Second preference is adding another _nofail wrapper.
>>
>
> So this issue with _nofail is that if you are doing it properly, every
> API needed both normal and _nofail version of every function. APIs
> generally have no bussiness dictating failure policy so by extension,
> normal and _nofail should exist for every API that accepts an Error *.
> With my proposal, its fixed once, in one place and we can torch all
> the _nofail boilerplate all over the tree as you have suggested.
>
> These is another subtle advantage to my proposal, and that is that
> assertions can happen at the point of failure in the offending API,
> not after the fact in the caller. If the caller does an
> assert_no_error, then the abort() happens after return from the API
> call. This makes debugging awkward cause the stack frames into the API
> call where the issue actually occured are lost. Whereas if error_set
> does the abort() you will get all stack frames into the API call where
> the issue occured when gdb traps the abort().

To make further progress, we need a patch.  Care to cook one up?

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Qemu-devel] [PATCH] qom: abort on error in property setter if caller passed errp == NULL
  2013-11-29  7:56           ` Markus Armbruster
@ 2013-12-03  5:51             ` Peter Crosthwaite
  0 siblings, 0 replies; 15+ messages in thread
From: Peter Crosthwaite @ 2013-12-03  5:51 UTC (permalink / raw)
  To: Markus Armbruster
  Cc: Michael S. Tsirkin, qemu-devel@nongnu.org Developers,
	Anthony Liguori, Paolo Bonzini, Igor Mammedov,
	Andreas Färber

On Fri, Nov 29, 2013 at 5:56 PM, Markus Armbruster <armbru@redhat.com> wrote:
> Peter Crosthwaite <peter.crosthwaite@xilinx.com> writes:
>
>> On Fri, Nov 29, 2013 at 1:03 AM, Markus Armbruster <armbru@redhat.com> wrote:
>>> Paolo Bonzini <pbonzini@redhat.com> writes:
>>>
>>>> Il 28/11/2013 14:23, Igor Mammedov ha scritto:
>>>>> > object_property_set(Foo, bar, "baz", &abort_on_err);
>>>>>
>>>>> that is just another way to put burden on caller, instead of doing it
>>>>> in one place.
>>>>
>>>> It's also much more self-documenting.
>>>>
>>>> The problem is that there is one very good case where you want the
>>>> silent-don't-care behavior: when you don't care about the exact error,
>>>> and you can figure out whether there was an error from the returned
>>>> value of the function.  This doesn't apply to object_property_set of
>>>> course, but it is the reason why NULL Error* has silent-don't-care behavior.
>>>>
>>>> Now, let's look at the alternatives:
>>>>
>>>> * keep silent don't care
>>>>   + consistent
>>>>   + predictable
>>>>   - not always handy
>>>>
>>>> * only modify object_property_set
>>>>   + mostly does the right thing
>>>>   - inconsistent with other Error* functions
>>>>   - inconsistent with _nofail functions
>>>>
>>>> * Peter's alternative
>>>>   + self-documenting
>>>>   + consistent
>>>>   + predictable
>>>>
>>>> * make Error* mandatory for all void functions
>>>>   + consistent
>>>>   + almost predictable (because in C you can ignore return values)
>>>>   - not necessarily does the right thing (e.g. cleanup functions)
>>>>   - requires manual effort to abide to the policy
>>>>
>>>> I vote for Peter's proposal, or for adding object_property_set_nofail.
>>>> No particular preference.
>>>>
>>>> Another variant: modify object_property_set to add a g_warning.  I think
>>>> it's fine.  It reduces the inconsistency, and still simplifies debugging.
>>>
>>> I like Peter's proposal, provided we use it to get rid of the _nofail
>>> pattern.
>>>
>>> Second preference is adding another _nofail wrapper.
>>>
>>
>> So this issue with _nofail is that if you are doing it properly, every
>> API needed both normal and _nofail version of every function. APIs
>> generally have no bussiness dictating failure policy so by extension,
>> normal and _nofail should exist for every API that accepts an Error *.
>> With my proposal, its fixed once, in one place and we can torch all
>> the _nofail boilerplate all over the tree as you have suggested.
>>
>> These is another subtle advantage to my proposal, and that is that
>> assertions can happen at the point of failure in the offending API,
>> not after the fact in the caller. If the caller does an
>> assert_no_error, then the abort() happens after return from the API
>> call. This makes debugging awkward cause the stack frames into the API
>> call where the issue actually occured are lost. Whereas if error_set
>> does the abort() you will get all stack frames into the API call where
>> the issue occured when gdb traps the abort().
>
> To make further progress, we need a patch.  Care to cook one up?
>

Done.

Regards,
Peter

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2013-12-03  5:51 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-11-28  1:24 [Qemu-devel] [PATCH] qom: abort on error in property setter if caller passed errp == NULL Igor Mammedov
2013-11-28  4:58 ` Eric Blake
2013-11-28 13:01   ` Igor Mammedov
2013-11-28  5:10 ` Peter Crosthwaite
2013-11-28  7:53   ` Markus Armbruster
2013-11-28 13:23   ` Igor Mammedov
2013-11-28 13:41     ` Paolo Bonzini
2013-11-28 15:03       ` Markus Armbruster
2013-11-29  0:21         ` Peter Crosthwaite
2013-11-29  7:56           ` Markus Armbruster
2013-12-03  5:51             ` Peter Crosthwaite
2013-11-28 15:00     ` Markus Armbruster
2013-11-28 13:42 ` Andreas Färber
2013-11-28 13:48   ` Igor Mammedov
2013-11-28 14:00     ` Andreas Färber

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).