From 11e35bfdc7f030f65844b34239bdde16e68b2468 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 2 Feb 2012 12:37:53 +0100 Subject: [PATCH] qom: use object_resolve_path_type for links This allows to restrict partial matches to objects of the expected type. It will let people use bare names to reference drives even though their name might be the same as a device's (e.g. -drive id=hd0,if=none,... -device ...,drive=hd0,id=hd0). As a useful byproduct, this fixes a problem with links of interface type. When a link property's type is an interface, the code expects the implementation object (not the parent object) to be stored in the variable. The parent object does not contain the right vtable. Reviewed-by: Anthony Liguori Signed-off-by: Paolo Bonzini --- qerror.c | 4 ++++ qerror.h | 3 +++ qom/object.c | 31 +++++++++++++++++-------------- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/qerror.c b/qerror.c index 3d179c87ea8..8e6efafe00d 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 8c36ddb7e10..e8718bfbabd 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 ea0efc662ac..2bd15b81b2c 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); -- 2.39.5