diff --git a/include/qemu/object.h b/include/qemu/object.h index b27f80e0bd98b440aa111641ac2564072ee39cdc..6c36345814b9b88f7bcd752201b1d4f29df0140d 100644 --- a/include/qemu/object.h +++ b/include/qemu/object.h @@ -749,13 +749,34 @@ gchar *object_get_canonical_path(Object *obj); * specifying objects easy. At each level of the composition tree, the partial * path is matched as an absolute path. The first match is not returned. At * least two matches are searched for. A successful result is only returned if - * only one match is founded. If more than one match is found, a flag is - * return to indicate that the match was ambiguous. + * only one match is found. If more than one match is found, a flag is + * returned to indicate that the match was ambiguous. * * Returns: The matched object or NULL on path lookup failure. */ Object *object_resolve_path(const char *path, bool *ambiguous); +/** + * object_resolve_path_type: + * @path: the path to resolve + * @typename: the type to look for. + * @ambiguous: returns true if the path resolution failed because of an + * ambiguous match + * + * This is similar to object_resolve_path. However, when looking for a + * partial path only matches that implement the given type are considered. + * This restricts the search and avoids spuriously flagging matches as + * ambiguous. + * + * For both partial and absolute paths, the return value goes through + * a dynamic cast to @typename. This is important if either the link, + * or the typename itself are of interface types. + * + * Returns: The matched object or NULL on path lookup failure. + */ +Object *object_resolve_path_type(const char *path, const char *typename, + bool *ambiguous); + /** * object_property_add_child: * @obj: the object to add a property to diff --git a/qom/object.c b/qom/object.c index 7fd37cb879a0051e346590ba7b92baf3dc0606a0..ea0efc662ac5d92d6bfbe185c29e79c67ef23dc3 100644 --- a/qom/object.c +++ b/qom/object.c @@ -930,17 +930,18 @@ gchar *object_get_canonical_path(Object *obj) static Object *object_resolve_abs_path(Object *parent, gchar **parts, + const char *typename, int index) { ObjectProperty *prop; Object *child; if (parts[index] == NULL) { - return parent; + return object_dynamic_cast(parent, typename); } if (strcmp(parts[index], "") == 0) { - return object_resolve_abs_path(parent, parts, index + 1); + return object_resolve_abs_path(parent, parts, typename, index + 1); } prop = object_property_find(parent, parts[index]); @@ -962,17 +963,18 @@ static Object *object_resolve_abs_path(Object *parent, return NULL; } - return object_resolve_abs_path(child, parts, index + 1); + return object_resolve_abs_path(child, parts, typename, index + 1); } static Object *object_resolve_partial_path(Object *parent, gchar **parts, + const char *typename, bool *ambiguous) { Object *obj; ObjectProperty *prop; - obj = object_resolve_abs_path(parent, parts, 0); + obj = object_resolve_abs_path(parent, parts, typename, 0); QTAILQ_FOREACH(prop, &parent->properties, node) { Object *found; @@ -981,7 +983,8 @@ static Object *object_resolve_partial_path(Object *parent, continue; } - found = object_resolve_partial_path(prop->opaque, parts, ambiguous); + found = object_resolve_partial_path(prop->opaque, parts, + typename, ambiguous); if (found) { if (obj) { if (ambiguous) { @@ -1000,7 +1003,8 @@ static Object *object_resolve_partial_path(Object *parent, return obj; } -Object *object_resolve_path(const char *path, bool *ambiguous) +Object *object_resolve_path_type(const char *path, const char *typename, + bool *ambiguous) { bool partial_path = true; Object *obj; @@ -1020,9 +1024,10 @@ Object *object_resolve_path(const char *path, bool *ambiguous) if (ambiguous) { *ambiguous = false; } - obj = object_resolve_partial_path(object_get_root(), parts, ambiguous); + obj = object_resolve_partial_path(object_get_root(), parts, + typename, ambiguous); } else { - obj = object_resolve_abs_path(object_get_root(), parts, 1); + obj = object_resolve_abs_path(object_get_root(), parts, typename, 1); } g_strfreev(parts); @@ -1030,6 +1035,11 @@ Object *object_resolve_path(const char *path, bool *ambiguous) return obj; } +Object *object_resolve_path(const char *path, bool *ambiguous) +{ + return object_resolve_path_type(path, TYPE_OBJECT, ambiguous); +} + typedef struct StringProperty { char *(*get)(Object *, Error **);