On Wed, Nov 30, 2011 at 03:03:32PM -0600, Anthony Liguori wrote: > +static void qdev_set_legacy_property(DeviceState *dev, Visitor *v, void > *opaque, > + const char *name, Error **errp) > +{ > + Property *prop = opaque; > + > + if (dev->state != DEV_STATE_CREATED) { > + error_set(errp, QERR_PERMISSION_DENIED); > + return; > + } > + > + if (prop->info->parse) { > + Error *local_err = NULL; > + char *ptr = NULL; > + > + visit_type_str(v, &ptr, name, &local_err); > + if (!local_err) { > + int ret; > + ret = prop->info->parse(dev, prop, ptr); > + if (ret != 0) { > + error_set(errp, QERR_INVALID_PARAMETER_VALUE, > + name, prop->info->name); > + } > + g_free(ptr); > + } else { > + error_propagate(errp, local_err); > + }
I noticed something subtle about Error** here. Your code is correct but I (incorrectly) wanted to eliminate local_err and use errp directly: if (prop->info->parse) { char *ptr = NULL; visit_type_str(v, &ptr, name, errp); if (!error_is_set(errp)) { int ret; ret = prop->info->parse(dev, prop, ptr); if (ret != 0) { error_set(errp, QERR_INVALID_PARAMETER_VALUE, name, prop->info->name); } g_free(ptr); } } else { ... Turns out you cannot do this because error_is_set(errp) will be false if the caller passed in a NULL errp. That means we wouldn't detect the error from visit_type_str()! So it's not okay to depend on the caller's errp. We always need to juggle around a local_err with propagation :(. Just wanted to share.