Commit f5ec6704 authored by Stefan Hajnoczi's avatar Stefan Hajnoczi Committed by Andreas Färber
Browse files

qom: Split object_property_set_link()



The path resolution logic in object_property_set_link() should be a
separate function.  This makes the code easier to read and maintain.

Signed-off-by: default avatarStefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
Signed-off-by: default avatarAndreas Färber <afaerber@suse.de>
parent c8897e8e
Loading
Loading
Loading
Loading
+40 −20
Original line number Diff line number Diff line
@@ -1039,44 +1039,64 @@ static void object_get_link_property(Object *obj, Visitor *v, void *opaque,
    }
}

static void object_set_link_property(Object *obj, Visitor *v, void *opaque,
                                     const char *name, Error **errp)
/*
 * object_resolve_link:
 *
 * Lookup an object and ensure its type matches the link property type.  This
 * is similar to object_resolve_path() except type verification against the
 * link property is performed.
 *
 * Returns: The matched object or NULL on path lookup failures.
 */
static Object *object_resolve_link(Object *obj, const char *name,
                                   const char *path, Error **errp)
{
    Object **child = opaque;
    Object *old_target;
    bool ambiguous = false;
    const char *type;
    char *path;
    gchar *target_type;

    type = object_property_get_type(obj, name, NULL);

    visit_type_str(v, &path, name, errp);

    old_target = *child;
    *child = NULL;

    if (strcmp(path, "") != 0) {
    bool ambiguous = false;
    Object *target;

    /* Go from link<FOO> to FOO.  */
    type = object_property_get_type(obj, name, NULL);
    target_type = g_strndup(&type[5], strlen(type) - 6);
    target = object_resolve_path_type(path, target_type, &ambiguous);

    if (ambiguous) {
        error_set(errp, QERR_AMBIGUOUS_PATH, path);
        } else if (target) {
            object_ref(target);
            *child = target;
        } else {
    } else if (!target) {
        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);
        }
        target = NULL;
    }
    g_free(target_type);

    return target;
}

static void object_set_link_property(Object *obj, Visitor *v, void *opaque,
                                     const char *name, Error **errp)
{
    Object **child = opaque;
    Object *old_target;
    char *path;

    visit_type_str(v, &path, name, errp);

    old_target = *child;
    *child = NULL;

    if (strcmp(path, "") != 0) {
        Object *target;

        target = object_resolve_link(obj, name, path, errp);
        if (target) {
            object_ref(target);
            *child = target;
        }
    }

    g_free(path);