aboutsummaryrefslogtreecommitdiff
path: root/qom
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2012-02-02 12:37:53 +0100
committerPaolo Bonzini <pbonzini@redhat.com>2012-02-07 13:52:41 +0100
commit11e35bfdc7f030f65844b34239bdde16e68b2468 (patch)
treecae2862b2cb506f35a171cb33b810f243ed282f4 /qom
parent02fe2db6312ff894be9aa0b862b383cc9d94505a (diff)
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 <aliguori@us.ibm.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'qom')
-rw-r--r--qom/object.c31
1 files changed, 17 insertions, 14 deletions
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<FOO> 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<FOO> 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);