diff --git a/qerror.c b/qerror.c index 3d179c87ea..8e6efafe00 100644 --- a/qerror.c +++ b/qerror.c @@ -47,6 +47,10 @@ static const QErrorStringTable qerror_table[] = { .error_fmt = QERR_ADD_CLIENT_FAILED, .desc = "Could not add client", }, + { + .error_fmt = QERR_AMBIGUOUS_PATH, + .desc = "Path '%(path)' does not uniquely identify a %(object)" + }, { .error_fmt = QERR_BAD_BUS_FOR_DEVICE, .desc = "Device '%(device)' can't go on a %(bad_bus_type) bus", diff --git a/qerror.h b/qerror.h index 8c36ddb7e1..e8718bfbab 100644 --- a/qerror.h +++ b/qerror.h @@ -54,6 +54,9 @@ QError *qobject_to_qerror(const QObject *obj); #define QERR_ADD_CLIENT_FAILED \ "{ 'class': 'AddClientFailed', 'data': {} }" +#define QERR_AMBIGUOUS_PATH \ + "{ 'class': 'AmbiguousPath', 'data': { 'path': %s } }" + #define QERR_BAD_BUS_FOR_DEVICE \ "{ 'class': 'BadBusForDevice', 'data': { 'device': %s, 'bad_bus_type': %s } }" diff --git a/qom/object.c b/qom/object.c index ea0efc662a..2bd15b81b2 100644 --- a/qom/object.c +++ b/qom/object.c @@ -840,6 +840,7 @@ static void object_set_link_property(Object *obj, Visitor *v, void *opaque, bool ambiguous = false; const char *type; char *path; + gchar *target_type; type = object_property_get_type(obj, name, NULL); @@ -847,28 +848,30 @@ static void object_set_link_property(Object *obj, Visitor *v, void *opaque, if (*child) { object_unref(*child); + *child = NULL; } if (strcmp(path, "") != 0) { Object *target; - target = object_resolve_path(path, &ambiguous); - if (target) { - /* Go from link to FOO. */ - gchar *target_type = g_strndup(&type[5], strlen(type) - 6); - if (object_dynamic_cast(target, target_type)) { - object_ref(target); - *child = target; - } else { - error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, type); - } + /* Go from link to FOO. */ + target_type = g_strndup(&type[5], strlen(type) - 6); + target = object_resolve_path_type(path, target_type, &ambiguous); - g_free(target_type); + if (ambiguous) { + error_set(errp, QERR_AMBIGUOUS_PATH, path); + } else if (target) { + object_ref(target); + *child = target; } else { - error_set(errp, QERR_DEVICE_NOT_FOUND, path); + target = object_resolve_path(path, &ambiguous); + if (target || ambiguous) { + error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, target_type); + } else { + error_set(errp, QERR_DEVICE_NOT_FOUND, path); + } } - } else { - *child = NULL; + g_free(target_type); } g_free(path);