On 06/13/2016 09:52 AM, Eduardo Habkost wrote: >> >> There is an (ugly) difference between >> >> error_setg(&local_err, ...); >> error_propagate(errp, &local_err); >> >> and >> >> error_setg(errp, ...); >> >> The latter aborts when @errp already contains an error, the former does >> nothing. > > Why the difference? Couldn't we change that so that both are equivalent? Maybe, but I think it weakens our position. An abort() on an attempt to incorrectly set an error twice helps catch errors where we are throwing away a more useful first error message. The documentation for error_propagate() already mentioned that it was an exception to the rule. > >> >> Your transformation has the error_setg() or similar hidden in F2(). It >> can add aborts. >> >> I think it can be salvaged: we know that @errp must not contain an error >> on function entry. If @errp doesn't occur elsewhere in this function, >> it cannot pick up an error on the way to the transformed spot. Can you >> add that to your when constraints? > > Do we really know that *errp is NULL on entry? Aren't we allowed to call > functions with a non-NULL *errp? Except for error_propagate(), no. > > See, e.g.: > > void qmp_guest_suspend_disk(Error **errp) > { > Error *local_err = NULL; > GuestSuspendMode *mode = g_new(GuestSuspendMode, 1); > > *mode = GUEST_SUSPEND_MODE_DISK; > check_suspend_mode(*mode, &local_err); > acquire_privilege(SE_SHUTDOWN_NAME, &local_err); > execute_async(do_suspend, mode, &local_err); That usage is a bug. A Coccinelle script to root out such buggy instances would be nice. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org