qemu/qom/object.c
<<
>>
Prefs
   1/*
   2 * QEMU Object Model
   3 *
   4 * Copyright IBM, Corp. 2011
   5 *
   6 * Authors:
   7 *  Anthony Liguori   <aliguori@us.ibm.com>
   8 *
   9 * This work is licensed under the terms of the GNU GPL, version 2 or later.
  10 * See the COPYING file in the top-level directory.
  11 */
  12
  13#include "qemu/osdep.h"
  14#include "qapi/error.h"
  15#include "qom/object.h"
  16#include "qom/object_interfaces.h"
  17#include "qemu/cutils.h"
  18#include "qapi/visitor.h"
  19#include "qapi/string-input-visitor.h"
  20#include "qapi/string-output-visitor.h"
  21#include "qapi/qapi-builtin-visit.h"
  22#include "qapi/qmp/qerror.h"
  23#include "trace.h"
  24
  25/* TODO: replace QObject with a simpler visitor to avoid a dependency
  26 * of the QOM core on QObject?  */
  27#include "qom/qom-qobject.h"
  28#include "qapi/qmp/qbool.h"
  29#include "qapi/qmp/qnum.h"
  30#include "qapi/qmp/qstring.h"
  31
  32#define MAX_INTERFACES 32
  33
  34typedef struct InterfaceImpl InterfaceImpl;
  35typedef struct TypeImpl TypeImpl;
  36
  37struct InterfaceImpl
  38{
  39    const char *typename;
  40};
  41
  42struct TypeImpl
  43{
  44    const char *name;
  45
  46    size_t class_size;
  47
  48    size_t instance_size;
  49
  50    void (*class_init)(ObjectClass *klass, void *data);
  51    void (*class_base_init)(ObjectClass *klass, void *data);
  52    void (*class_finalize)(ObjectClass *klass, void *data);
  53
  54    void *class_data;
  55
  56    void (*instance_init)(Object *obj);
  57    void (*instance_post_init)(Object *obj);
  58    void (*instance_finalize)(Object *obj);
  59
  60    bool abstract;
  61
  62    const char *parent;
  63    TypeImpl *parent_type;
  64
  65    ObjectClass *class;
  66
  67    int num_interfaces;
  68    InterfaceImpl interfaces[MAX_INTERFACES];
  69};
  70
  71static Type type_interface;
  72
  73static GHashTable *type_table_get(void)
  74{
  75    static GHashTable *type_table;
  76
  77    if (type_table == NULL) {
  78        type_table = g_hash_table_new(g_str_hash, g_str_equal);
  79    }
  80
  81    return type_table;
  82}
  83
  84static bool enumerating_types;
  85
  86static void type_table_add(TypeImpl *ti)
  87{
  88    assert(!enumerating_types);
  89    g_hash_table_insert(type_table_get(), (void *)ti->name, ti);
  90}
  91
  92static TypeImpl *type_table_lookup(const char *name)
  93{
  94    return g_hash_table_lookup(type_table_get(), name);
  95}
  96
  97static TypeImpl *type_new(const TypeInfo *info)
  98{
  99    TypeImpl *ti = g_malloc0(sizeof(*ti));
 100    int i;
 101
 102    g_assert(info->name != NULL);
 103
 104    if (type_table_lookup(info->name) != NULL) {
 105        fprintf(stderr, "Registering `%s' which already exists\n", info->name);
 106        abort();
 107    }
 108
 109    ti->name = g_strdup(info->name);
 110    ti->parent = g_strdup(info->parent);
 111
 112    ti->class_size = info->class_size;
 113    ti->instance_size = info->instance_size;
 114
 115    ti->class_init = info->class_init;
 116    ti->class_base_init = info->class_base_init;
 117    ti->class_finalize = info->class_finalize;
 118    ti->class_data = info->class_data;
 119
 120    ti->instance_init = info->instance_init;
 121    ti->instance_post_init = info->instance_post_init;
 122    ti->instance_finalize = info->instance_finalize;
 123
 124    ti->abstract = info->abstract;
 125
 126    for (i = 0; info->interfaces && info->interfaces[i].type; i++) {
 127        ti->interfaces[i].typename = g_strdup(info->interfaces[i].type);
 128    }
 129    ti->num_interfaces = i;
 130
 131    return ti;
 132}
 133
 134static TypeImpl *type_register_internal(const TypeInfo *info)
 135{
 136    TypeImpl *ti;
 137    ti = type_new(info);
 138
 139    type_table_add(ti);
 140    return ti;
 141}
 142
 143TypeImpl *type_register(const TypeInfo *info)
 144{
 145    assert(info->parent);
 146    return type_register_internal(info);
 147}
 148
 149TypeImpl *type_register_static(const TypeInfo *info)
 150{
 151    return type_register(info);
 152}
 153
 154void type_register_static_array(const TypeInfo *infos, int nr_infos)
 155{
 156    int i;
 157
 158    for (i = 0; i < nr_infos; i++) {
 159        type_register_static(&infos[i]);
 160    }
 161}
 162
 163static TypeImpl *type_get_by_name(const char *name)
 164{
 165    if (name == NULL) {
 166        return NULL;
 167    }
 168
 169    return type_table_lookup(name);
 170}
 171
 172static TypeImpl *type_get_parent(TypeImpl *type)
 173{
 174    if (!type->parent_type && type->parent) {
 175        type->parent_type = type_get_by_name(type->parent);
 176        g_assert(type->parent_type != NULL);
 177    }
 178
 179    return type->parent_type;
 180}
 181
 182static bool type_has_parent(TypeImpl *type)
 183{
 184    return (type->parent != NULL);
 185}
 186
 187static size_t type_class_get_size(TypeImpl *ti)
 188{
 189    if (ti->class_size) {
 190        return ti->class_size;
 191    }
 192
 193    if (type_has_parent(ti)) {
 194        return type_class_get_size(type_get_parent(ti));
 195    }
 196
 197    return sizeof(ObjectClass);
 198}
 199
 200static size_t type_object_get_size(TypeImpl *ti)
 201{
 202    if (ti->instance_size) {
 203        return ti->instance_size;
 204    }
 205
 206    if (type_has_parent(ti)) {
 207        return type_object_get_size(type_get_parent(ti));
 208    }
 209
 210    return 0;
 211}
 212
 213size_t object_type_get_instance_size(const char *typename)
 214{
 215    TypeImpl *type = type_get_by_name(typename);
 216
 217    g_assert(type != NULL);
 218    return type_object_get_size(type);
 219}
 220
 221static bool type_is_ancestor(TypeImpl *type, TypeImpl *target_type)
 222{
 223    assert(target_type);
 224
 225    /* Check if target_type is a direct ancestor of type */
 226    while (type) {
 227        if (type == target_type) {
 228            return true;
 229        }
 230
 231        type = type_get_parent(type);
 232    }
 233
 234    return false;
 235}
 236
 237static void type_initialize(TypeImpl *ti);
 238
 239static void type_initialize_interface(TypeImpl *ti, TypeImpl *interface_type,
 240                                      TypeImpl *parent_type)
 241{
 242    InterfaceClass *new_iface;
 243    TypeInfo info = { };
 244    TypeImpl *iface_impl;
 245
 246    info.parent = parent_type->name;
 247    info.name = g_strdup_printf("%s::%s", ti->name, interface_type->name);
 248    info.abstract = true;
 249
 250    iface_impl = type_new(&info);
 251    iface_impl->parent_type = parent_type;
 252    type_initialize(iface_impl);
 253    g_free((char *)info.name);
 254
 255    new_iface = (InterfaceClass *)iface_impl->class;
 256    new_iface->concrete_class = ti->class;
 257    new_iface->interface_type = interface_type;
 258
 259    ti->class->interfaces = g_slist_append(ti->class->interfaces,
 260                                           iface_impl->class);
 261}
 262
 263static void object_property_free(gpointer data)
 264{
 265    ObjectProperty *prop = data;
 266
 267    g_free(prop->name);
 268    g_free(prop->type);
 269    g_free(prop->description);
 270    g_free(prop);
 271}
 272
 273static void type_initialize(TypeImpl *ti)
 274{
 275    TypeImpl *parent;
 276
 277    if (ti->class) {
 278        return;
 279    }
 280
 281    ti->class_size = type_class_get_size(ti);
 282    ti->instance_size = type_object_get_size(ti);
 283    /* Any type with zero instance_size is implicitly abstract.
 284     * This means interface types are all abstract.
 285     */
 286    if (ti->instance_size == 0) {
 287        ti->abstract = true;
 288    }
 289    if (type_is_ancestor(ti, type_interface)) {
 290        assert(ti->instance_size == 0);
 291        assert(ti->abstract);
 292        assert(!ti->instance_init);
 293        assert(!ti->instance_post_init);
 294        assert(!ti->instance_finalize);
 295        assert(!ti->num_interfaces);
 296    }
 297    ti->class = g_malloc0(ti->class_size);
 298
 299    parent = type_get_parent(ti);
 300    if (parent) {
 301        type_initialize(parent);
 302        GSList *e;
 303        int i;
 304
 305        g_assert(parent->class_size <= ti->class_size);
 306        memcpy(ti->class, parent->class, parent->class_size);
 307        ti->class->interfaces = NULL;
 308        ti->class->properties = g_hash_table_new_full(
 309            g_str_hash, g_str_equal, g_free, object_property_free);
 310
 311        for (e = parent->class->interfaces; e; e = e->next) {
 312            InterfaceClass *iface = e->data;
 313            ObjectClass *klass = OBJECT_CLASS(iface);
 314
 315            type_initialize_interface(ti, iface->interface_type, klass->type);
 316        }
 317
 318        for (i = 0; i < ti->num_interfaces; i++) {
 319            TypeImpl *t = type_get_by_name(ti->interfaces[i].typename);
 320            for (e = ti->class->interfaces; e; e = e->next) {
 321                TypeImpl *target_type = OBJECT_CLASS(e->data)->type;
 322
 323                if (type_is_ancestor(target_type, t)) {
 324                    break;
 325                }
 326            }
 327
 328            if (e) {
 329                continue;
 330            }
 331
 332            type_initialize_interface(ti, t, t);
 333        }
 334    } else {
 335        ti->class->properties = g_hash_table_new_full(
 336            g_str_hash, g_str_equal, g_free, object_property_free);
 337    }
 338
 339    ti->class->type = ti;
 340
 341    while (parent) {
 342        if (parent->class_base_init) {
 343            parent->class_base_init(ti->class, ti->class_data);
 344        }
 345        parent = type_get_parent(parent);
 346    }
 347
 348    if (ti->class_init) {
 349        ti->class_init(ti->class, ti->class_data);
 350    }
 351}
 352
 353static void object_init_with_type(Object *obj, TypeImpl *ti)
 354{
 355    if (type_has_parent(ti)) {
 356        object_init_with_type(obj, type_get_parent(ti));
 357    }
 358
 359    if (ti->instance_init) {
 360        ti->instance_init(obj);
 361    }
 362}
 363
 364static void object_post_init_with_type(Object *obj, TypeImpl *ti)
 365{
 366    if (ti->instance_post_init) {
 367        ti->instance_post_init(obj);
 368    }
 369
 370    if (type_has_parent(ti)) {
 371        object_post_init_with_type(obj, type_get_parent(ti));
 372    }
 373}
 374
 375static void object_initialize_with_type(void *data, size_t size, TypeImpl *type)
 376{
 377    Object *obj = data;
 378
 379    g_assert(type != NULL);
 380    type_initialize(type);
 381
 382    g_assert(type->instance_size >= sizeof(Object));
 383    g_assert(type->abstract == false);
 384    g_assert(size >= type->instance_size);
 385
 386    memset(obj, 0, type->instance_size);
 387    obj->class = type->class;
 388    object_ref(obj);
 389    obj->properties = g_hash_table_new_full(g_str_hash, g_str_equal,
 390                                            NULL, object_property_free);
 391    object_init_with_type(obj, type);
 392    object_post_init_with_type(obj, type);
 393}
 394
 395void object_initialize(void *data, size_t size, const char *typename)
 396{
 397    TypeImpl *type = type_get_by_name(typename);
 398
 399    object_initialize_with_type(data, size, type);
 400}
 401
 402void object_initialize_child(Object *parentobj, const char *propname,
 403                             void *childobj, size_t size, const char *type,
 404                             Error **errp, ...)
 405{
 406    va_list vargs;
 407
 408    va_start(vargs, errp);
 409    object_initialize_childv(parentobj, propname, childobj, size, type, errp,
 410                             vargs);
 411    va_end(vargs);
 412}
 413
 414void object_initialize_childv(Object *parentobj, const char *propname,
 415                              void *childobj, size_t size, const char *type,
 416                              Error **errp, va_list vargs)
 417{
 418    Error *local_err = NULL;
 419    Object *obj;
 420
 421    object_initialize(childobj, size, type);
 422    obj = OBJECT(childobj);
 423
 424    object_set_propv(obj, &local_err, vargs);
 425    if (local_err) {
 426        goto out;
 427    }
 428
 429    object_property_add_child(parentobj, propname, obj, &local_err);
 430    if (local_err) {
 431        goto out;
 432    }
 433
 434    if (object_dynamic_cast(obj, TYPE_USER_CREATABLE)) {
 435        user_creatable_complete(obj, &local_err);
 436        if (local_err) {
 437            object_unparent(obj);
 438            goto out;
 439        }
 440    }
 441
 442    /*
 443     * Since object_property_add_child added a reference to the child object,
 444     * we can drop the reference added by object_initialize(), so the child
 445     * property will own the only reference to the object.
 446     */
 447    object_unref(obj);
 448
 449out:
 450    if (local_err) {
 451        error_propagate(errp, local_err);
 452        object_unref(obj);
 453    }
 454}
 455
 456static inline bool object_property_is_child(ObjectProperty *prop)
 457{
 458    return strstart(prop->type, "child<", NULL);
 459}
 460
 461static void object_property_del_all(Object *obj)
 462{
 463    ObjectProperty *prop;
 464    GHashTableIter iter;
 465    gpointer key, value;
 466    bool released;
 467
 468    do {
 469        released = false;
 470        g_hash_table_iter_init(&iter, obj->properties);
 471        while (g_hash_table_iter_next(&iter, &key, &value)) {
 472            prop = value;
 473            if (prop->release) {
 474                prop->release(obj, prop->name, prop->opaque);
 475                prop->release = NULL;
 476                released = true;
 477                break;
 478            }
 479            g_hash_table_iter_remove(&iter);
 480        }
 481    } while (released);
 482
 483    g_hash_table_unref(obj->properties);
 484}
 485
 486static void object_property_del_child(Object *obj, Object *child, Error **errp)
 487{
 488    ObjectProperty *prop;
 489    GHashTableIter iter;
 490    gpointer key, value;
 491
 492    g_hash_table_iter_init(&iter, obj->properties);
 493    while (g_hash_table_iter_next(&iter, &key, &value)) {
 494        prop = value;
 495        if (object_property_is_child(prop) && prop->opaque == child) {
 496            if (prop->release) {
 497                prop->release(obj, prop->name, prop->opaque);
 498                prop->release = NULL;
 499            }
 500            break;
 501        }
 502    }
 503    g_hash_table_iter_init(&iter, obj->properties);
 504    while (g_hash_table_iter_next(&iter, &key, &value)) {
 505        prop = value;
 506        if (object_property_is_child(prop) && prop->opaque == child) {
 507            g_hash_table_iter_remove(&iter);
 508            break;
 509        }
 510    }
 511}
 512
 513void object_unparent(Object *obj)
 514{
 515    if (obj->parent) {
 516        object_property_del_child(obj->parent, obj, NULL);
 517    }
 518}
 519
 520static void object_deinit(Object *obj, TypeImpl *type)
 521{
 522    if (type->instance_finalize) {
 523        type->instance_finalize(obj);
 524    }
 525
 526    if (type_has_parent(type)) {
 527        object_deinit(obj, type_get_parent(type));
 528    }
 529}
 530
 531static void object_finalize(void *data)
 532{
 533    Object *obj = data;
 534    TypeImpl *ti = obj->class->type;
 535
 536    object_property_del_all(obj);
 537    object_deinit(obj, ti);
 538
 539    g_assert(obj->ref == 0);
 540    if (obj->free) {
 541        obj->free(obj);
 542    }
 543}
 544
 545static Object *object_new_with_type(Type type)
 546{
 547    Object *obj;
 548
 549    g_assert(type != NULL);
 550    type_initialize(type);
 551
 552    obj = g_malloc(type->instance_size);
 553    object_initialize_with_type(obj, type->instance_size, type);
 554    obj->free = g_free;
 555
 556    return obj;
 557}
 558
 559Object *object_new(const char *typename)
 560{
 561    TypeImpl *ti = type_get_by_name(typename);
 562
 563    return object_new_with_type(ti);
 564}
 565
 566
 567Object *object_new_with_props(const char *typename,
 568                              Object *parent,
 569                              const char *id,
 570                              Error **errp,
 571                              ...)
 572{
 573    va_list vargs;
 574    Object *obj;
 575
 576    va_start(vargs, errp);
 577    obj = object_new_with_propv(typename, parent, id, errp, vargs);
 578    va_end(vargs);
 579
 580    return obj;
 581}
 582
 583
 584Object *object_new_with_propv(const char *typename,
 585                              Object *parent,
 586                              const char *id,
 587                              Error **errp,
 588                              va_list vargs)
 589{
 590    Object *obj;
 591    ObjectClass *klass;
 592    Error *local_err = NULL;
 593
 594    klass = object_class_by_name(typename);
 595    if (!klass) {
 596        error_setg(errp, "invalid object type: %s", typename);
 597        return NULL;
 598    }
 599
 600    if (object_class_is_abstract(klass)) {
 601        error_setg(errp, "object type '%s' is abstract", typename);
 602        return NULL;
 603    }
 604    obj = object_new(typename);
 605
 606    if (object_set_propv(obj, &local_err, vargs) < 0) {
 607        goto error;
 608    }
 609
 610    object_property_add_child(parent, id, obj, &local_err);
 611    if (local_err) {
 612        goto error;
 613    }
 614
 615    if (object_dynamic_cast(obj, TYPE_USER_CREATABLE)) {
 616        user_creatable_complete(obj, &local_err);
 617        if (local_err) {
 618            object_unparent(obj);
 619            goto error;
 620        }
 621    }
 622
 623    object_unref(OBJECT(obj));
 624    return obj;
 625
 626 error:
 627    error_propagate(errp, local_err);
 628    object_unref(obj);
 629    return NULL;
 630}
 631
 632
 633int object_set_props(Object *obj,
 634                     Error **errp,
 635                     ...)
 636{
 637    va_list vargs;
 638    int ret;
 639
 640    va_start(vargs, errp);
 641    ret = object_set_propv(obj, errp, vargs);
 642    va_end(vargs);
 643
 644    return ret;
 645}
 646
 647
 648int object_set_propv(Object *obj,
 649                     Error **errp,
 650                     va_list vargs)
 651{
 652    const char *propname;
 653    Error *local_err = NULL;
 654
 655    propname = va_arg(vargs, char *);
 656    while (propname != NULL) {
 657        const char *value = va_arg(vargs, char *);
 658
 659        g_assert(value != NULL);
 660        object_property_parse(obj, value, propname, &local_err);
 661        if (local_err) {
 662            error_propagate(errp, local_err);
 663            return -1;
 664        }
 665        propname = va_arg(vargs, char *);
 666    }
 667
 668    return 0;
 669}
 670
 671
 672Object *object_dynamic_cast(Object *obj, const char *typename)
 673{
 674    if (obj && object_class_dynamic_cast(object_get_class(obj), typename)) {
 675        return obj;
 676    }
 677
 678    return NULL;
 679}
 680
 681Object *object_dynamic_cast_assert(Object *obj, const char *typename,
 682                                   const char *file, int line, const char *func)
 683{
 684    trace_object_dynamic_cast_assert(obj ? obj->class->type->name : "(null)",
 685                                     typename, file, line, func);
 686
 687#ifdef CONFIG_QOM_CAST_DEBUG
 688    int i;
 689    Object *inst;
 690
 691    for (i = 0; obj && i < OBJECT_CLASS_CAST_CACHE; i++) {
 692        if (atomic_read(&obj->class->object_cast_cache[i]) == typename) {
 693            goto out;
 694        }
 695    }
 696
 697    inst = object_dynamic_cast(obj, typename);
 698
 699    if (!inst && obj) {
 700        fprintf(stderr, "%s:%d:%s: Object %p is not an instance of type %s\n",
 701                file, line, func, obj, typename);
 702        abort();
 703    }
 704
 705    assert(obj == inst);
 706
 707    if (obj && obj == inst) {
 708        for (i = 1; i < OBJECT_CLASS_CAST_CACHE; i++) {
 709            atomic_set(&obj->class->object_cast_cache[i - 1],
 710                       atomic_read(&obj->class->object_cast_cache[i]));
 711        }
 712        atomic_set(&obj->class->object_cast_cache[i - 1], typename);
 713    }
 714
 715out:
 716#endif
 717    return obj;
 718}
 719
 720ObjectClass *object_class_dynamic_cast(ObjectClass *class,
 721                                       const char *typename)
 722{
 723    ObjectClass *ret = NULL;
 724    TypeImpl *target_type;
 725    TypeImpl *type;
 726
 727    if (!class) {
 728        return NULL;
 729    }
 730
 731    /* A simple fast path that can trigger a lot for leaf classes.  */
 732    type = class->type;
 733    if (type->name == typename) {
 734        return class;
 735    }
 736
 737    target_type = type_get_by_name(typename);
 738    if (!target_type) {
 739        /* target class type unknown, so fail the cast */
 740        return NULL;
 741    }
 742
 743    if (type->class->interfaces &&
 744            type_is_ancestor(target_type, type_interface)) {
 745        int found = 0;
 746        GSList *i;
 747
 748        for (i = class->interfaces; i; i = i->next) {
 749            ObjectClass *target_class = i->data;
 750
 751            if (type_is_ancestor(target_class->type, target_type)) {
 752                ret = target_class;
 753                found++;
 754            }
 755         }
 756
 757        /* The match was ambiguous, don't allow a cast */
 758        if (found > 1) {
 759            ret = NULL;
 760        }
 761    } else if (type_is_ancestor(type, target_type)) {
 762        ret = class;
 763    }
 764
 765    return ret;
 766}
 767
 768ObjectClass *object_class_dynamic_cast_assert(ObjectClass *class,
 769                                              const char *typename,
 770                                              const char *file, int line,
 771                                              const char *func)
 772{
 773    ObjectClass *ret;
 774
 775    trace_object_class_dynamic_cast_assert(class ? class->type->name : "(null)",
 776                                           typename, file, line, func);
 777
 778#ifdef CONFIG_QOM_CAST_DEBUG
 779    int i;
 780
 781    for (i = 0; class && i < OBJECT_CLASS_CAST_CACHE; i++) {
 782        if (atomic_read(&class->class_cast_cache[i]) == typename) {
 783            ret = class;
 784            goto out;
 785        }
 786    }
 787#else
 788    if (!class || !class->interfaces) {
 789        return class;
 790    }
 791#endif
 792
 793    ret = object_class_dynamic_cast(class, typename);
 794    if (!ret && class) {
 795        fprintf(stderr, "%s:%d:%s: Object %p is not an instance of type %s\n",
 796                file, line, func, class, typename);
 797        abort();
 798    }
 799
 800#ifdef CONFIG_QOM_CAST_DEBUG
 801    if (class && ret == class) {
 802        for (i = 1; i < OBJECT_CLASS_CAST_CACHE; i++) {
 803            atomic_set(&class->class_cast_cache[i - 1],
 804                       atomic_read(&class->class_cast_cache[i]));
 805        }
 806        atomic_set(&class->class_cast_cache[i - 1], typename);
 807    }
 808out:
 809#endif
 810    return ret;
 811}
 812
 813const char *object_get_typename(const Object *obj)
 814{
 815    return obj->class->type->name;
 816}
 817
 818ObjectClass *object_get_class(Object *obj)
 819{
 820    return obj->class;
 821}
 822
 823bool object_class_is_abstract(ObjectClass *klass)
 824{
 825    return klass->type->abstract;
 826}
 827
 828const char *object_class_get_name(ObjectClass *klass)
 829{
 830    return klass->type->name;
 831}
 832
 833ObjectClass *object_class_by_name(const char *typename)
 834{
 835    TypeImpl *type = type_get_by_name(typename);
 836
 837    if (!type) {
 838        return NULL;
 839    }
 840
 841    type_initialize(type);
 842
 843    return type->class;
 844}
 845
 846ObjectClass *object_class_get_parent(ObjectClass *class)
 847{
 848    TypeImpl *type = type_get_parent(class->type);
 849
 850    if (!type) {
 851        return NULL;
 852    }
 853
 854    type_initialize(type);
 855
 856    return type->class;
 857}
 858
 859typedef struct OCFData
 860{
 861    void (*fn)(ObjectClass *klass, void *opaque);
 862    const char *implements_type;
 863    bool include_abstract;
 864    void *opaque;
 865} OCFData;
 866
 867static void object_class_foreach_tramp(gpointer key, gpointer value,
 868                                       gpointer opaque)
 869{
 870    OCFData *data = opaque;
 871    TypeImpl *type = value;
 872    ObjectClass *k;
 873
 874    type_initialize(type);
 875    k = type->class;
 876
 877    if (!data->include_abstract && type->abstract) {
 878        return;
 879    }
 880
 881    if (data->implements_type && 
 882        !object_class_dynamic_cast(k, data->implements_type)) {
 883        return;
 884    }
 885
 886    data->fn(k, data->opaque);
 887}
 888
 889void object_class_foreach(void (*fn)(ObjectClass *klass, void *opaque),
 890                          const char *implements_type, bool include_abstract,
 891                          void *opaque)
 892{
 893    OCFData data = { fn, implements_type, include_abstract, opaque };
 894
 895    enumerating_types = true;
 896    g_hash_table_foreach(type_table_get(), object_class_foreach_tramp, &data);
 897    enumerating_types = false;
 898}
 899
 900static int do_object_child_foreach(Object *obj,
 901                                   int (*fn)(Object *child, void *opaque),
 902                                   void *opaque, bool recurse)
 903{
 904    GHashTableIter iter;
 905    ObjectProperty *prop;
 906    int ret = 0;
 907
 908    g_hash_table_iter_init(&iter, obj->properties);
 909    while (g_hash_table_iter_next(&iter, NULL, (gpointer *)&prop)) {
 910        if (object_property_is_child(prop)) {
 911            Object *child = prop->opaque;
 912
 913            ret = fn(child, opaque);
 914            if (ret != 0) {
 915                break;
 916            }
 917            if (recurse) {
 918                do_object_child_foreach(child, fn, opaque, true);
 919            }
 920        }
 921    }
 922    return ret;
 923}
 924
 925int object_child_foreach(Object *obj, int (*fn)(Object *child, void *opaque),
 926                         void *opaque)
 927{
 928    return do_object_child_foreach(obj, fn, opaque, false);
 929}
 930
 931int object_child_foreach_recursive(Object *obj,
 932                                   int (*fn)(Object *child, void *opaque),
 933                                   void *opaque)
 934{
 935    return do_object_child_foreach(obj, fn, opaque, true);
 936}
 937
 938static void object_class_get_list_tramp(ObjectClass *klass, void *opaque)
 939{
 940    GSList **list = opaque;
 941
 942    *list = g_slist_prepend(*list, klass);
 943}
 944
 945GSList *object_class_get_list(const char *implements_type,
 946                              bool include_abstract)
 947{
 948    GSList *list = NULL;
 949
 950    object_class_foreach(object_class_get_list_tramp,
 951                         implements_type, include_abstract, &list);
 952    return list;
 953}
 954
 955static gint object_class_cmp(gconstpointer a, gconstpointer b)
 956{
 957    return strcasecmp(object_class_get_name((ObjectClass *)a),
 958                      object_class_get_name((ObjectClass *)b));
 959}
 960
 961GSList *object_class_get_list_sorted(const char *implements_type,
 962                                     bool include_abstract)
 963{
 964    return g_slist_sort(object_class_get_list(implements_type, include_abstract),
 965                        object_class_cmp);
 966}
 967
 968void object_ref(Object *obj)
 969{
 970    if (!obj) {
 971        return;
 972    }
 973    atomic_inc(&obj->ref);
 974}
 975
 976void object_unref(Object *obj)
 977{
 978    if (!obj) {
 979        return;
 980    }
 981    g_assert(obj->ref > 0);
 982
 983    /* parent always holds a reference to its children */
 984    if (atomic_fetch_dec(&obj->ref) == 1) {
 985        object_finalize(obj);
 986    }
 987}
 988
 989ObjectProperty *
 990object_property_add(Object *obj, const char *name, const char *type,
 991                    ObjectPropertyAccessor *get,
 992                    ObjectPropertyAccessor *set,
 993                    ObjectPropertyRelease *release,
 994                    void *opaque, Error **errp)
 995{
 996    ObjectProperty *prop;
 997    size_t name_len = strlen(name);
 998
 999    if (name_len >= 3 && !memcmp(name + name_len - 3, "[*]", 4)) {
1000        int i;
1001        ObjectProperty *ret;
1002        char *name_no_array = g_strdup(name);
1003
1004        name_no_array[name_len - 3] = '\0';
1005        for (i = 0; ; ++i) {
1006            char *full_name = g_strdup_printf("%s[%d]", name_no_array, i);
1007
1008            ret = object_property_add(obj, full_name, type, get, set,
1009                                      release, opaque, NULL);
1010            g_free(full_name);
1011            if (ret) {
1012                break;
1013            }
1014        }
1015        g_free(name_no_array);
1016        return ret;
1017    }
1018
1019    if (object_property_find(obj, name, NULL) != NULL) {
1020        error_setg(errp, "attempt to add duplicate property '%s'"
1021                   " to object (type '%s')", name,
1022                   object_get_typename(obj));
1023        return NULL;
1024    }
1025
1026    prop = g_malloc0(sizeof(*prop));
1027
1028    prop->name = g_strdup(name);
1029    prop->type = g_strdup(type);
1030
1031    prop->get = get;
1032    prop->set = set;
1033    prop->release = release;
1034    prop->opaque = opaque;
1035
1036    g_hash_table_insert(obj->properties, prop->name, prop);
1037    return prop;
1038}
1039
1040ObjectProperty *
1041object_class_property_add(ObjectClass *klass,
1042                          const char *name,
1043                          const char *type,
1044                          ObjectPropertyAccessor *get,
1045                          ObjectPropertyAccessor *set,
1046                          ObjectPropertyRelease *release,
1047                          void *opaque,
1048                          Error **errp)
1049{
1050    ObjectProperty *prop;
1051
1052    if (object_class_property_find(klass, name, NULL) != NULL) {
1053        error_setg(errp, "attempt to add duplicate property '%s'"
1054                   " to object (type '%s')", name,
1055                   object_class_get_name(klass));
1056        return NULL;
1057    }
1058
1059    prop = g_malloc0(sizeof(*prop));
1060
1061    prop->name = g_strdup(name);
1062    prop->type = g_strdup(type);
1063
1064    prop->get = get;
1065    prop->set = set;
1066    prop->release = release;
1067    prop->opaque = opaque;
1068
1069    g_hash_table_insert(klass->properties, g_strdup(name), prop);
1070
1071    return prop;
1072}
1073
1074ObjectProperty *object_property_find(Object *obj, const char *name,
1075                                     Error **errp)
1076{
1077    ObjectProperty *prop;
1078    ObjectClass *klass = object_get_class(obj);
1079
1080    prop = object_class_property_find(klass, name, NULL);
1081    if (prop) {
1082        return prop;
1083    }
1084
1085    prop = g_hash_table_lookup(obj->properties, name);
1086    if (prop) {
1087        return prop;
1088    }
1089
1090    error_setg(errp, "Property '.%s' not found", name);
1091    return NULL;
1092}
1093
1094void object_property_iter_init(ObjectPropertyIterator *iter,
1095                               Object *obj)
1096{
1097    g_hash_table_iter_init(&iter->iter, obj->properties);
1098    iter->nextclass = object_get_class(obj);
1099}
1100
1101ObjectProperty *object_property_iter_next(ObjectPropertyIterator *iter)
1102{
1103    gpointer key, val;
1104    while (!g_hash_table_iter_next(&iter->iter, &key, &val)) {
1105        if (!iter->nextclass) {
1106            return NULL;
1107        }
1108        g_hash_table_iter_init(&iter->iter, iter->nextclass->properties);
1109        iter->nextclass = object_class_get_parent(iter->nextclass);
1110    }
1111    return val;
1112}
1113
1114void object_class_property_iter_init(ObjectPropertyIterator *iter,
1115                                     ObjectClass *klass)
1116{
1117    g_hash_table_iter_init(&iter->iter, klass->properties);
1118    iter->nextclass = object_class_get_parent(klass);
1119}
1120
1121ObjectProperty *object_class_property_find(ObjectClass *klass, const char *name,
1122                                           Error **errp)
1123{
1124    ObjectProperty *prop;
1125    ObjectClass *parent_klass;
1126
1127    parent_klass = object_class_get_parent(klass);
1128    if (parent_klass) {
1129        prop = object_class_property_find(parent_klass, name, NULL);
1130        if (prop) {
1131            return prop;
1132        }
1133    }
1134
1135    prop = g_hash_table_lookup(klass->properties, name);
1136    if (!prop) {
1137        error_setg(errp, "Property '.%s' not found", name);
1138    }
1139    return prop;
1140}
1141
1142void object_property_del(Object *obj, const char *name, Error **errp)
1143{
1144    ObjectProperty *prop = g_hash_table_lookup(obj->properties, name);
1145
1146    if (!prop) {
1147        error_setg(errp, "Property '.%s' not found", name);
1148        return;
1149    }
1150
1151    if (prop->release) {
1152        prop->release(obj, name, prop->opaque);
1153    }
1154    g_hash_table_remove(obj->properties, name);
1155}
1156
1157void object_property_get(Object *obj, Visitor *v, const char *name,
1158                         Error **errp)
1159{
1160    ObjectProperty *prop = object_property_find(obj, name, errp);
1161    if (prop == NULL) {
1162        return;
1163    }
1164
1165    if (!prop->get) {
1166        error_setg(errp, QERR_PERMISSION_DENIED);
1167    } else {
1168        prop->get(obj, v, name, prop->opaque, errp);
1169    }
1170}
1171
1172void object_property_set(Object *obj, Visitor *v, const char *name,
1173                         Error **errp)
1174{
1175    ObjectProperty *prop = object_property_find(obj, name, errp);
1176    if (prop == NULL) {
1177        return;
1178    }
1179
1180    if (!prop->set) {
1181        error_setg(errp, QERR_PERMISSION_DENIED);
1182    } else {
1183        prop->set(obj, v, name, prop->opaque, errp);
1184    }
1185}
1186
1187void object_property_set_str(Object *obj, const char *value,
1188                             const char *name, Error **errp)
1189{
1190    QString *qstr = qstring_from_str(value);
1191    object_property_set_qobject(obj, QOBJECT(qstr), name, errp);
1192
1193    qobject_unref(qstr);
1194}
1195
1196char *object_property_get_str(Object *obj, const char *name,
1197                              Error **errp)
1198{
1199    QObject *ret = object_property_get_qobject(obj, name, errp);
1200    char *retval;
1201
1202    if (!ret) {
1203        return NULL;
1204    }
1205
1206    retval = g_strdup(qobject_get_try_str(ret));
1207    if (!retval) {
1208        error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name, "string");
1209    }
1210
1211    qobject_unref(ret);
1212    return retval;
1213}
1214
1215void object_property_set_link(Object *obj, Object *value,
1216                              const char *name, Error **errp)
1217{
1218    if (value) {
1219        gchar *path = object_get_canonical_path(value);
1220        object_property_set_str(obj, path, name, errp);
1221        g_free(path);
1222    } else {
1223        object_property_set_str(obj, "", name, errp);
1224    }
1225}
1226
1227Object *object_property_get_link(Object *obj, const char *name,
1228                                 Error **errp)
1229{
1230    char *str = object_property_get_str(obj, name, errp);
1231    Object *target = NULL;
1232
1233    if (str && *str) {
1234        target = object_resolve_path(str, NULL);
1235        if (!target) {
1236            error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
1237                      "Device '%s' not found", str);
1238        }
1239    }
1240
1241    g_free(str);
1242    return target;
1243}
1244
1245void object_property_set_bool(Object *obj, bool value,
1246                              const char *name, Error **errp)
1247{
1248    QBool *qbool = qbool_from_bool(value);
1249    object_property_set_qobject(obj, QOBJECT(qbool), name, errp);
1250
1251    qobject_unref(qbool);
1252}
1253
1254bool object_property_get_bool(Object *obj, const char *name,
1255                              Error **errp)
1256{
1257    QObject *ret = object_property_get_qobject(obj, name, errp);
1258    QBool *qbool;
1259    bool retval;
1260
1261    if (!ret) {
1262        return false;
1263    }
1264    qbool = qobject_to(QBool, ret);
1265    if (!qbool) {
1266        error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name, "boolean");
1267        retval = false;
1268    } else {
1269        retval = qbool_get_bool(qbool);
1270    }
1271
1272    qobject_unref(ret);
1273    return retval;
1274}
1275
1276void object_property_set_int(Object *obj, int64_t value,
1277                             const char *name, Error **errp)
1278{
1279    QNum *qnum = qnum_from_int(value);
1280    object_property_set_qobject(obj, QOBJECT(qnum), name, errp);
1281
1282    qobject_unref(qnum);
1283}
1284
1285int64_t object_property_get_int(Object *obj, const char *name,
1286                                Error **errp)
1287{
1288    QObject *ret = object_property_get_qobject(obj, name, errp);
1289    QNum *qnum;
1290    int64_t retval;
1291
1292    if (!ret) {
1293        return -1;
1294    }
1295
1296    qnum = qobject_to(QNum, ret);
1297    if (!qnum || !qnum_get_try_int(qnum, &retval)) {
1298        error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name, "int");
1299        retval = -1;
1300    }
1301
1302    qobject_unref(ret);
1303    return retval;
1304}
1305
1306void object_property_set_uint(Object *obj, uint64_t value,
1307                              const char *name, Error **errp)
1308{
1309    QNum *qnum = qnum_from_uint(value);
1310
1311    object_property_set_qobject(obj, QOBJECT(qnum), name, errp);
1312    qobject_unref(qnum);
1313}
1314
1315uint64_t object_property_get_uint(Object *obj, const char *name,
1316                                  Error **errp)
1317{
1318    QObject *ret = object_property_get_qobject(obj, name, errp);
1319    QNum *qnum;
1320    uint64_t retval;
1321
1322    if (!ret) {
1323        return 0;
1324    }
1325    qnum = qobject_to(QNum, ret);
1326    if (!qnum || !qnum_get_try_uint(qnum, &retval)) {
1327        error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name, "uint");
1328        retval = 0;
1329    }
1330
1331    qobject_unref(ret);
1332    return retval;
1333}
1334
1335typedef struct EnumProperty {
1336    const QEnumLookup *lookup;
1337    int (*get)(Object *, Error **);
1338    void (*set)(Object *, int, Error **);
1339} EnumProperty;
1340
1341int object_property_get_enum(Object *obj, const char *name,
1342                             const char *typename, Error **errp)
1343{
1344    Error *err = NULL;
1345    Visitor *v;
1346    char *str;
1347    int ret;
1348    ObjectProperty *prop = object_property_find(obj, name, errp);
1349    EnumProperty *enumprop;
1350
1351    if (prop == NULL) {
1352        return 0;
1353    }
1354
1355    if (!g_str_equal(prop->type, typename)) {
1356        error_setg(errp, "Property %s on %s is not '%s' enum type",
1357                   name, object_class_get_name(
1358                       object_get_class(obj)), typename);
1359        return 0;
1360    }
1361
1362    enumprop = prop->opaque;
1363
1364    v = string_output_visitor_new(false, &str);
1365    object_property_get(obj, v, name, &err);
1366    if (err) {
1367        error_propagate(errp, err);
1368        visit_free(v);
1369        return 0;
1370    }
1371    visit_complete(v, &str);
1372    visit_free(v);
1373    v = string_input_visitor_new(str);
1374    visit_type_enum(v, name, &ret, enumprop->lookup, errp);
1375
1376    g_free(str);
1377    visit_free(v);
1378
1379    return ret;
1380}
1381
1382void object_property_get_uint16List(Object *obj, const char *name,
1383                                    uint16List **list, Error **errp)
1384{
1385    Error *err = NULL;
1386    Visitor *v;
1387    char *str;
1388
1389    v = string_output_visitor_new(false, &str);
1390    object_property_get(obj, v, name, &err);
1391    if (err) {
1392        error_propagate(errp, err);
1393        goto out;
1394    }
1395    visit_complete(v, &str);
1396    visit_free(v);
1397    v = string_input_visitor_new(str);
1398    visit_type_uint16List(v, NULL, list, errp);
1399
1400    g_free(str);
1401out:
1402    visit_free(v);
1403}
1404
1405void object_property_parse(Object *obj, const char *string,
1406                           const char *name, Error **errp)
1407{
1408    Visitor *v = string_input_visitor_new(string);
1409    object_property_set(obj, v, name, errp);
1410    visit_free(v);
1411}
1412
1413char *object_property_print(Object *obj, const char *name, bool human,
1414                            Error **errp)
1415{
1416    Visitor *v;
1417    char *string = NULL;
1418    Error *local_err = NULL;
1419
1420    v = string_output_visitor_new(human, &string);
1421    object_property_get(obj, v, name, &local_err);
1422    if (local_err) {
1423        error_propagate(errp, local_err);
1424        goto out;
1425    }
1426
1427    visit_complete(v, &string);
1428
1429out:
1430    visit_free(v);
1431    return string;
1432}
1433
1434const char *object_property_get_type(Object *obj, const char *name, Error **errp)
1435{
1436    ObjectProperty *prop = object_property_find(obj, name, errp);
1437    if (prop == NULL) {
1438        return NULL;
1439    }
1440
1441    return prop->type;
1442}
1443
1444Object *object_get_root(void)
1445{
1446    static Object *root;
1447
1448    if (!root) {
1449        root = object_new("container");
1450    }
1451
1452    return root;
1453}
1454
1455Object *object_get_objects_root(void)
1456{
1457    return container_get(object_get_root(), "/objects");
1458}
1459
1460Object *object_get_internal_root(void)
1461{
1462    static Object *internal_root;
1463
1464    if (!internal_root) {
1465        internal_root = object_new("container");
1466    }
1467
1468    return internal_root;
1469}
1470
1471static void object_get_child_property(Object *obj, Visitor *v,
1472                                      const char *name, void *opaque,
1473                                      Error **errp)
1474{
1475    Object *child = opaque;
1476    gchar *path;
1477
1478    path = object_get_canonical_path(child);
1479    visit_type_str(v, name, &path, errp);
1480    g_free(path);
1481}
1482
1483static Object *object_resolve_child_property(Object *parent, void *opaque, const gchar *part)
1484{
1485    return opaque;
1486}
1487
1488static void object_finalize_child_property(Object *obj, const char *name,
1489                                           void *opaque)
1490{
1491    Object *child = opaque;
1492
1493    if (child->class->unparent) {
1494        (child->class->unparent)(child);
1495    }
1496    child->parent = NULL;
1497    object_unref(child);
1498}
1499
1500void object_property_add_child(Object *obj, const char *name,
1501                               Object *child, Error **errp)
1502{
1503    Error *local_err = NULL;
1504    gchar *type;
1505    ObjectProperty *op;
1506
1507    if (child->parent != NULL) {
1508        error_setg(errp, "child object is already parented");
1509        return;
1510    }
1511
1512    type = g_strdup_printf("child<%s>", object_get_typename(OBJECT(child)));
1513
1514    op = object_property_add(obj, name, type, object_get_child_property, NULL,
1515                             object_finalize_child_property, child, &local_err);
1516    if (local_err) {
1517        error_propagate(errp, local_err);
1518        goto out;
1519    }
1520
1521    op->resolve = object_resolve_child_property;
1522    object_ref(child);
1523    child->parent = obj;
1524
1525out:
1526    g_free(type);
1527}
1528
1529void object_property_allow_set_link(const Object *obj, const char *name,
1530                                    Object *val, Error **errp)
1531{
1532    /* Allow the link to be set, always */
1533}
1534
1535typedef struct {
1536    Object **child;
1537    void (*check)(const Object *, const char *, Object *, Error **);
1538    ObjectPropertyLinkFlags flags;
1539} LinkProperty;
1540
1541static void object_get_link_property(Object *obj, Visitor *v,
1542                                     const char *name, void *opaque,
1543                                     Error **errp)
1544{
1545    LinkProperty *lprop = opaque;
1546    Object **child = lprop->child;
1547    gchar *path;
1548
1549    if (*child) {
1550        path = object_get_canonical_path(*child);
1551        visit_type_str(v, name, &path, errp);
1552        g_free(path);
1553    } else {
1554        path = (gchar *)"";
1555        visit_type_str(v, name, &path, errp);
1556    }
1557}
1558
1559/*
1560 * object_resolve_link:
1561 *
1562 * Lookup an object and ensure its type matches the link property type.  This
1563 * is similar to object_resolve_path() except type verification against the
1564 * link property is performed.
1565 *
1566 * Returns: The matched object or NULL on path lookup failures.
1567 */
1568static Object *object_resolve_link(Object *obj, const char *name,
1569                                   const char *path, Error **errp)
1570{
1571    const char *type;
1572    gchar *target_type;
1573    bool ambiguous = false;
1574    Object *target;
1575
1576    /* Go from link<FOO> to FOO.  */
1577    type = object_property_get_type(obj, name, NULL);
1578    target_type = g_strndup(&type[5], strlen(type) - 6);
1579    target = object_resolve_path_type(path, target_type, &ambiguous);
1580
1581    if (ambiguous) {
1582        error_setg(errp, "Path '%s' does not uniquely identify an object",
1583                   path);
1584    } else if (!target) {
1585        target = object_resolve_path(path, &ambiguous);
1586        if (target || ambiguous) {
1587            error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name, target_type);
1588        } else {
1589            error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
1590                      "Device '%s' not found", path);
1591        }
1592        target = NULL;
1593    }
1594    g_free(target_type);
1595
1596    return target;
1597}
1598
1599static void object_set_link_property(Object *obj, Visitor *v,
1600                                     const char *name, void *opaque,
1601                                     Error **errp)
1602{
1603    Error *local_err = NULL;
1604    LinkProperty *prop = opaque;
1605    Object **child = prop->child;
1606    Object *old_target = *child;
1607    Object *new_target = NULL;
1608    char *path = NULL;
1609
1610    visit_type_str(v, name, &path, &local_err);
1611
1612    if (!local_err && strcmp(path, "") != 0) {
1613        new_target = object_resolve_link(obj, name, path, &local_err);
1614    }
1615
1616    g_free(path);
1617    if (local_err) {
1618        error_propagate(errp, local_err);
1619        return;
1620    }
1621
1622    prop->check(obj, name, new_target, &local_err);
1623    if (local_err) {
1624        error_propagate(errp, local_err);
1625        return;
1626    }
1627
1628    *child = new_target;
1629    if (prop->flags == OBJ_PROP_LINK_STRONG) {
1630        object_ref(new_target);
1631        object_unref(old_target);
1632    }
1633}
1634
1635static Object *object_resolve_link_property(Object *parent, void *opaque, const gchar *part)
1636{
1637    LinkProperty *lprop = opaque;
1638
1639    return *lprop->child;
1640}
1641
1642static void object_release_link_property(Object *obj, const char *name,
1643                                         void *opaque)
1644{
1645    LinkProperty *prop = opaque;
1646
1647    if ((prop->flags & OBJ_PROP_LINK_STRONG) && *prop->child) {
1648        object_unref(*prop->child);
1649    }
1650    g_free(prop);
1651}
1652
1653void object_property_add_link(Object *obj, const char *name,
1654                              const char *type, Object **child,
1655                              void (*check)(const Object *, const char *,
1656                                            Object *, Error **),
1657                              ObjectPropertyLinkFlags flags,
1658                              Error **errp)
1659{
1660    Error *local_err = NULL;
1661    LinkProperty *prop = g_malloc(sizeof(*prop));
1662    gchar *full_type;
1663    ObjectProperty *op;
1664
1665    prop->child = child;
1666    prop->check = check;
1667    prop->flags = flags;
1668
1669    full_type = g_strdup_printf("link<%s>", type);
1670
1671    op = object_property_add(obj, name, full_type,
1672                             object_get_link_property,
1673                             check ? object_set_link_property : NULL,
1674                             object_release_link_property,
1675                             prop,
1676                             &local_err);
1677    if (local_err) {
1678        error_propagate(errp, local_err);
1679        g_free(prop);
1680        goto out;
1681    }
1682
1683    op->resolve = object_resolve_link_property;
1684
1685out:
1686    g_free(full_type);
1687}
1688
1689void object_property_add_const_link(Object *obj, const char *name,
1690                                    Object *target, Error **errp)
1691{
1692    char *link_type;
1693    ObjectProperty *op;
1694
1695    link_type = g_strdup_printf("link<%s>", object_get_typename(target));
1696    op = object_property_add(obj, name, link_type,
1697                             object_get_child_property, NULL,
1698                             NULL, target, errp);
1699    if (op != NULL) {
1700        op->resolve = object_resolve_child_property;
1701    }
1702    g_free(link_type);
1703}
1704
1705gchar *object_get_canonical_path_component(Object *obj)
1706{
1707    ObjectProperty *prop = NULL;
1708    GHashTableIter iter;
1709
1710    if (obj->parent == NULL) {
1711        return NULL;
1712    }
1713
1714    g_hash_table_iter_init(&iter, obj->parent->properties);
1715    while (g_hash_table_iter_next(&iter, NULL, (gpointer *)&prop)) {
1716        if (!object_property_is_child(prop)) {
1717            continue;
1718        }
1719
1720        if (prop->opaque == obj) {
1721            return g_strdup(prop->name);
1722        }
1723    }
1724
1725    /* obj had a parent but was not a child, should never happen */
1726    g_assert_not_reached();
1727    return NULL;
1728}
1729
1730gchar *object_get_canonical_path(Object *obj)
1731{
1732    Object *root = object_get_root();
1733    char *newpath, *path = NULL;
1734
1735    if (obj == root) {
1736        return g_strdup("/");
1737    }
1738
1739    do {
1740        char *component = object_get_canonical_path_component(obj);
1741
1742        if (!component) {
1743            /* A canonical path must be complete, so discard what was
1744             * collected so far.
1745             */
1746            g_free(path);
1747            return NULL;
1748        }
1749
1750        newpath = g_strdup_printf("/%s%s", component, path ? path : "");
1751        g_free(path);
1752        g_free(component);
1753        path = newpath;
1754        obj = obj->parent;
1755    } while (obj != root);
1756
1757    return path;
1758}
1759
1760Object *object_resolve_path_component(Object *parent, const gchar *part)
1761{
1762    ObjectProperty *prop = object_property_find(parent, part, NULL);
1763    if (prop == NULL) {
1764        return NULL;
1765    }
1766
1767    if (prop->resolve) {
1768        return prop->resolve(parent, prop->opaque, part);
1769    } else {
1770        return NULL;
1771    }
1772}
1773
1774static Object *object_resolve_abs_path(Object *parent,
1775                                          gchar **parts,
1776                                          const char *typename,
1777                                          int index)
1778{
1779    Object *child;
1780
1781    if (parts[index] == NULL) {
1782        return object_dynamic_cast(parent, typename);
1783    }
1784
1785    if (strcmp(parts[index], "") == 0) {
1786        return object_resolve_abs_path(parent, parts, typename, index + 1);
1787    }
1788
1789    child = object_resolve_path_component(parent, parts[index]);
1790    if (!child) {
1791        return NULL;
1792    }
1793
1794    return object_resolve_abs_path(child, parts, typename, index + 1);
1795}
1796
1797static Object *object_resolve_partial_path(Object *parent,
1798                                              gchar **parts,
1799                                              const char *typename,
1800                                              bool *ambiguous)
1801{
1802    Object *obj;
1803    GHashTableIter iter;
1804    ObjectProperty *prop;
1805
1806    obj = object_resolve_abs_path(parent, parts, typename, 0);
1807
1808    g_hash_table_iter_init(&iter, parent->properties);
1809    while (g_hash_table_iter_next(&iter, NULL, (gpointer *)&prop)) {
1810        Object *found;
1811
1812        if (!object_property_is_child(prop)) {
1813            continue;
1814        }
1815
1816        found = object_resolve_partial_path(prop->opaque, parts,
1817                                            typename, ambiguous);
1818        if (found) {
1819            if (obj) {
1820                *ambiguous = true;
1821                return NULL;
1822            }
1823            obj = found;
1824        }
1825
1826        if (*ambiguous) {
1827            return NULL;
1828        }
1829    }
1830
1831    return obj;
1832}
1833
1834Object *object_resolve_path_type(const char *path, const char *typename,
1835                                 bool *ambiguousp)
1836{
1837    Object *obj;
1838    gchar **parts;
1839
1840    parts = g_strsplit(path, "/", 0);
1841    assert(parts);
1842
1843    if (parts[0] == NULL || strcmp(parts[0], "") != 0) {
1844        bool ambiguous = false;
1845        obj = object_resolve_partial_path(object_get_root(), parts,
1846                                          typename, &ambiguous);
1847        if (ambiguousp) {
1848            *ambiguousp = ambiguous;
1849        }
1850    } else {
1851        obj = object_resolve_abs_path(object_get_root(), parts, typename, 1);
1852    }
1853
1854    g_strfreev(parts);
1855
1856    return obj;
1857}
1858
1859Object *object_resolve_path(const char *path, bool *ambiguous)
1860{
1861    return object_resolve_path_type(path, TYPE_OBJECT, ambiguous);
1862}
1863
1864typedef struct StringProperty
1865{
1866    char *(*get)(Object *, Error **);
1867    void (*set)(Object *, const char *, Error **);
1868} StringProperty;
1869
1870static void property_get_str(Object *obj, Visitor *v, const char *name,
1871                             void *opaque, Error **errp)
1872{
1873    StringProperty *prop = opaque;
1874    char *value;
1875    Error *err = NULL;
1876
1877    value = prop->get(obj, &err);
1878    if (err) {
1879        error_propagate(errp, err);
1880        return;
1881    }
1882
1883    visit_type_str(v, name, &value, errp);
1884    g_free(value);
1885}
1886
1887static void property_set_str(Object *obj, Visitor *v, const char *name,
1888                             void *opaque, Error **errp)
1889{
1890    StringProperty *prop = opaque;
1891    char *value;
1892    Error *local_err = NULL;
1893
1894    visit_type_str(v, name, &value, &local_err);
1895    if (local_err) {
1896        error_propagate(errp, local_err);
1897        return;
1898    }
1899
1900    prop->set(obj, value, errp);
1901    g_free(value);
1902}
1903
1904static void property_release_str(Object *obj, const char *name,
1905                                 void *opaque)
1906{
1907    StringProperty *prop = opaque;
1908    g_free(prop);
1909}
1910
1911void object_property_add_str(Object *obj, const char *name,
1912                           char *(*get)(Object *, Error **),
1913                           void (*set)(Object *, const char *, Error **),
1914                           Error **errp)
1915{
1916    Error *local_err = NULL;
1917    StringProperty *prop = g_malloc0(sizeof(*prop));
1918
1919    prop->get = get;
1920    prop->set = set;
1921
1922    object_property_add(obj, name, "string",
1923                        get ? property_get_str : NULL,
1924                        set ? property_set_str : NULL,
1925                        property_release_str,
1926                        prop, &local_err);
1927    if (local_err) {
1928        error_propagate(errp, local_err);
1929        g_free(prop);
1930    }
1931}
1932
1933void object_class_property_add_str(ObjectClass *klass, const char *name,
1934                                   char *(*get)(Object *, Error **),
1935                                   void (*set)(Object *, const char *,
1936                                               Error **),
1937                                   Error **errp)
1938{
1939    Error *local_err = NULL;
1940    StringProperty *prop = g_malloc0(sizeof(*prop));
1941
1942    prop->get = get;
1943    prop->set = set;
1944
1945    object_class_property_add(klass, name, "string",
1946                              get ? property_get_str : NULL,
1947                              set ? property_set_str : NULL,
1948                              property_release_str,
1949                              prop, &local_err);
1950    if (local_err) {
1951        error_propagate(errp, local_err);
1952        g_free(prop);
1953    }
1954}
1955
1956typedef struct BoolProperty
1957{
1958    bool (*get)(Object *, Error **);
1959    void (*set)(Object *, bool, Error **);
1960} BoolProperty;
1961
1962static void property_get_bool(Object *obj, Visitor *v, const char *name,
1963                              void *opaque, Error **errp)
1964{
1965    BoolProperty *prop = opaque;
1966    bool value;
1967    Error *err = NULL;
1968
1969    value = prop->get(obj, &err);
1970    if (err) {
1971        error_propagate(errp, err);
1972        return;
1973    }
1974
1975    visit_type_bool(v, name, &value, errp);
1976}
1977
1978static void property_set_bool(Object *obj, Visitor *v, const char *name,
1979                              void *opaque, Error **errp)
1980{
1981    BoolProperty *prop = opaque;
1982    bool value;
1983    Error *local_err = NULL;
1984
1985    visit_type_bool(v, name, &value, &local_err);
1986    if (local_err) {
1987        error_propagate(errp, local_err);
1988        return;
1989    }
1990
1991    prop->set(obj, value, errp);
1992}
1993
1994static void property_release_bool(Object *obj, const char *name,
1995                                  void *opaque)
1996{
1997    BoolProperty *prop = opaque;
1998    g_free(prop);
1999}
2000
2001void object_property_add_bool(Object *obj, const char *name,
2002                              bool (*get)(Object *, Error **),
2003                              void (*set)(Object *, bool, Error **),
2004                              Error **errp)
2005{
2006    Error *local_err = NULL;
2007    BoolProperty *prop = g_malloc0(sizeof(*prop));
2008
2009    prop->get = get;
2010    prop->set = set;
2011
2012    object_property_add(obj, name, "bool",
2013                        get ? property_get_bool : NULL,
2014                        set ? property_set_bool : NULL,
2015                        property_release_bool,
2016                        prop, &local_err);
2017    if (local_err) {
2018        error_propagate(errp, local_err);
2019        g_free(prop);
2020    }
2021}
2022
2023void object_class_property_add_bool(ObjectClass *klass, const char *name,
2024                                    bool (*get)(Object *, Error **),
2025                                    void (*set)(Object *, bool, Error **),
2026                                    Error **errp)
2027{
2028    Error *local_err = NULL;
2029    BoolProperty *prop = g_malloc0(sizeof(*prop));
2030
2031    prop->get = get;
2032    prop->set = set;
2033
2034    object_class_property_add(klass, name, "bool",
2035                              get ? property_get_bool : NULL,
2036                              set ? property_set_bool : NULL,
2037                              property_release_bool,
2038                              prop, &local_err);
2039    if (local_err) {
2040        error_propagate(errp, local_err);
2041        g_free(prop);
2042    }
2043}
2044
2045static void property_get_enum(Object *obj, Visitor *v, const char *name,
2046                              void *opaque, Error **errp)
2047{
2048    EnumProperty *prop = opaque;
2049    int value;
2050    Error *err = NULL;
2051
2052    value = prop->get(obj, &err);
2053    if (err) {
2054        error_propagate(errp, err);
2055        return;
2056    }
2057
2058    visit_type_enum(v, name, &value, prop->lookup, errp);
2059}
2060
2061static void property_set_enum(Object *obj, Visitor *v, const char *name,
2062                              void *opaque, Error **errp)
2063{
2064    EnumProperty *prop = opaque;
2065    int value;
2066    Error *err = NULL;
2067
2068    visit_type_enum(v, name, &value, prop->lookup, &err);
2069    if (err) {
2070        error_propagate(errp, err);
2071        return;
2072    }
2073    prop->set(obj, value, errp);
2074}
2075
2076static void property_release_enum(Object *obj, const char *name,
2077                                  void *opaque)
2078{
2079    EnumProperty *prop = opaque;
2080    g_free(prop);
2081}
2082
2083void object_property_add_enum(Object *obj, const char *name,
2084                              const char *typename,
2085                              const QEnumLookup *lookup,
2086                              int (*get)(Object *, Error **),
2087                              void (*set)(Object *, int, Error **),
2088                              Error **errp)
2089{
2090    Error *local_err = NULL;
2091    EnumProperty *prop = g_malloc(sizeof(*prop));
2092
2093    prop->lookup = lookup;
2094    prop->get = get;
2095    prop->set = set;
2096
2097    object_property_add(obj, name, typename,
2098                        get ? property_get_enum : NULL,
2099                        set ? property_set_enum : NULL,
2100                        property_release_enum,
2101                        prop, &local_err);
2102    if (local_err) {
2103        error_propagate(errp, local_err);
2104        g_free(prop);
2105    }
2106}
2107
2108void object_class_property_add_enum(ObjectClass *klass, const char *name,
2109                                    const char *typename,
2110                                    const QEnumLookup *lookup,
2111                                    int (*get)(Object *, Error **),
2112                                    void (*set)(Object *, int, Error **),
2113                                    Error **errp)
2114{
2115    Error *local_err = NULL;
2116    EnumProperty *prop = g_malloc(sizeof(*prop));
2117
2118    prop->lookup = lookup;
2119    prop->get = get;
2120    prop->set = set;
2121
2122    object_class_property_add(klass, name, typename,
2123                              get ? property_get_enum : NULL,
2124                              set ? property_set_enum : NULL,
2125                              property_release_enum,
2126                              prop, &local_err);
2127    if (local_err) {
2128        error_propagate(errp, local_err);
2129        g_free(prop);
2130    }
2131}
2132
2133typedef struct TMProperty {
2134    void (*get)(Object *, struct tm *, Error **);
2135} TMProperty;
2136
2137static void property_get_tm(Object *obj, Visitor *v, const char *name,
2138                            void *opaque, Error **errp)
2139{
2140    TMProperty *prop = opaque;
2141    Error *err = NULL;
2142    struct tm value;
2143
2144    prop->get(obj, &value, &err);
2145    if (err) {
2146        goto out;
2147    }
2148
2149    visit_start_struct(v, name, NULL, 0, &err);
2150    if (err) {
2151        goto out;
2152    }
2153    visit_type_int32(v, "tm_year", &value.tm_year, &err);
2154    if (err) {
2155        goto out_end;
2156    }
2157    visit_type_int32(v, "tm_mon", &value.tm_mon, &err);
2158    if (err) {
2159        goto out_end;
2160    }
2161    visit_type_int32(v, "tm_mday", &value.tm_mday, &err);
2162    if (err) {
2163        goto out_end;
2164    }
2165    visit_type_int32(v, "tm_hour", &value.tm_hour, &err);
2166    if (err) {
2167        goto out_end;
2168    }
2169    visit_type_int32(v, "tm_min", &value.tm_min, &err);
2170    if (err) {
2171        goto out_end;
2172    }
2173    visit_type_int32(v, "tm_sec", &value.tm_sec, &err);
2174    if (err) {
2175        goto out_end;
2176    }
2177    visit_check_struct(v, &err);
2178out_end:
2179    visit_end_struct(v, NULL);
2180out:
2181    error_propagate(errp, err);
2182
2183}
2184
2185static void property_release_tm(Object *obj, const char *name,
2186                                void *opaque)
2187{
2188    TMProperty *prop = opaque;
2189    g_free(prop);
2190}
2191
2192void object_property_add_tm(Object *obj, const char *name,
2193                            void (*get)(Object *, struct tm *, Error **),
2194                            Error **errp)
2195{
2196    Error *local_err = NULL;
2197    TMProperty *prop = g_malloc0(sizeof(*prop));
2198
2199    prop->get = get;
2200
2201    object_property_add(obj, name, "struct tm",
2202                        get ? property_get_tm : NULL, NULL,
2203                        property_release_tm,
2204                        prop, &local_err);
2205    if (local_err) {
2206        error_propagate(errp, local_err);
2207        g_free(prop);
2208    }
2209}
2210
2211void object_class_property_add_tm(ObjectClass *klass, const char *name,
2212                                  void (*get)(Object *, struct tm *, Error **),
2213                                  Error **errp)
2214{
2215    Error *local_err = NULL;
2216    TMProperty *prop = g_malloc0(sizeof(*prop));
2217
2218    prop->get = get;
2219
2220    object_class_property_add(klass, name, "struct tm",
2221                              get ? property_get_tm : NULL, NULL,
2222                              property_release_tm,
2223                              prop, &local_err);
2224    if (local_err) {
2225        error_propagate(errp, local_err);
2226        g_free(prop);
2227    }
2228}
2229
2230static char *qdev_get_type(Object *obj, Error **errp)
2231{
2232    return g_strdup(object_get_typename(obj));
2233}
2234
2235static void property_get_uint8_ptr(Object *obj, Visitor *v, const char *name,
2236                                   void *opaque, Error **errp)
2237{
2238    uint8_t value = *(uint8_t *)opaque;
2239    visit_type_uint8(v, name, &value, errp);
2240}
2241
2242static void property_get_uint16_ptr(Object *obj, Visitor *v, const char *name,
2243                                    void *opaque, Error **errp)
2244{
2245    uint16_t value = *(uint16_t *)opaque;
2246    visit_type_uint16(v, name, &value, errp);
2247}
2248
2249static void property_get_uint32_ptr(Object *obj, Visitor *v, const char *name,
2250                                    void *opaque, Error **errp)
2251{
2252    uint32_t value = *(uint32_t *)opaque;
2253    visit_type_uint32(v, name, &value, errp);
2254}
2255
2256static void property_get_uint64_ptr(Object *obj, Visitor *v, const char *name,
2257                                    void *opaque, Error **errp)
2258{
2259    uint64_t value = *(uint64_t *)opaque;
2260    visit_type_uint64(v, name, &value, errp);
2261}
2262
2263void object_property_add_uint8_ptr(Object *obj, const char *name,
2264                                   const uint8_t *v, Error **errp)
2265{
2266    object_property_add(obj, name, "uint8", property_get_uint8_ptr,
2267                        NULL, NULL, (void *)v, errp);
2268}
2269
2270void object_class_property_add_uint8_ptr(ObjectClass *klass, const char *name,
2271                                         const uint8_t *v, Error **errp)
2272{
2273    object_class_property_add(klass, name, "uint8", property_get_uint8_ptr,
2274                              NULL, NULL, (void *)v, errp);
2275}
2276
2277void object_property_add_uint16_ptr(Object *obj, const char *name,
2278                                    const uint16_t *v, Error **errp)
2279{
2280    object_property_add(obj, name, "uint16", property_get_uint16_ptr,
2281                        NULL, NULL, (void *)v, errp);
2282}
2283
2284void object_class_property_add_uint16_ptr(ObjectClass *klass, const char *name,
2285                                          const uint16_t *v, Error **errp)
2286{
2287    object_class_property_add(klass, name, "uint16", property_get_uint16_ptr,
2288                              NULL, NULL, (void *)v, errp);
2289}
2290
2291void object_property_add_uint32_ptr(Object *obj, const char *name,
2292                                    const uint32_t *v, Error **errp)
2293{
2294    object_property_add(obj, name, "uint32", property_get_uint32_ptr,
2295                        NULL, NULL, (void *)v, errp);
2296}
2297
2298void object_class_property_add_uint32_ptr(ObjectClass *klass, const char *name,
2299                                          const uint32_t *v, Error **errp)
2300{
2301    object_class_property_add(klass, name, "uint32", property_get_uint32_ptr,
2302                              NULL, NULL, (void *)v, errp);
2303}
2304
2305void object_property_add_uint64_ptr(Object *obj, const char *name,
2306                                    const uint64_t *v, Error **errp)
2307{
2308    object_property_add(obj, name, "uint64", property_get_uint64_ptr,
2309                        NULL, NULL, (void *)v, errp);
2310}
2311
2312void object_class_property_add_uint64_ptr(ObjectClass *klass, const char *name,
2313                                          const uint64_t *v, Error **errp)
2314{
2315    object_class_property_add(klass, name, "uint64", property_get_uint64_ptr,
2316                              NULL, NULL, (void *)v, errp);
2317}
2318
2319typedef struct {
2320    Object *target_obj;
2321    char *target_name;
2322} AliasProperty;
2323
2324static void property_get_alias(Object *obj, Visitor *v, const char *name,
2325                               void *opaque, Error **errp)
2326{
2327    AliasProperty *prop = opaque;
2328
2329    object_property_get(prop->target_obj, v, prop->target_name, errp);
2330}
2331
2332static void property_set_alias(Object *obj, Visitor *v, const char *name,
2333                               void *opaque, Error **errp)
2334{
2335    AliasProperty *prop = opaque;
2336
2337    object_property_set(prop->target_obj, v, prop->target_name, errp);
2338}
2339
2340static Object *property_resolve_alias(Object *obj, void *opaque,
2341                                      const gchar *part)
2342{
2343    AliasProperty *prop = opaque;
2344
2345    return object_resolve_path_component(prop->target_obj, prop->target_name);
2346}
2347
2348static void property_release_alias(Object *obj, const char *name, void *opaque)
2349{
2350    AliasProperty *prop = opaque;
2351
2352    g_free(prop->target_name);
2353    g_free(prop);
2354}
2355
2356void object_property_add_alias(Object *obj, const char *name,
2357                               Object *target_obj, const char *target_name,
2358                               Error **errp)
2359{
2360    AliasProperty *prop;
2361    ObjectProperty *op;
2362    ObjectProperty *target_prop;
2363    gchar *prop_type;
2364    Error *local_err = NULL;
2365
2366    target_prop = object_property_find(target_obj, target_name, errp);
2367    if (!target_prop) {
2368        return;
2369    }
2370
2371    if (object_property_is_child(target_prop)) {
2372        prop_type = g_strdup_printf("link%s",
2373                                    target_prop->type + strlen("child"));
2374    } else {
2375        prop_type = g_strdup(target_prop->type);
2376    }
2377
2378    prop = g_malloc(sizeof(*prop));
2379    prop->target_obj = target_obj;
2380    prop->target_name = g_strdup(target_name);
2381
2382    op = object_property_add(obj, name, prop_type,
2383                             property_get_alias,
2384                             property_set_alias,
2385                             property_release_alias,
2386                             prop, &local_err);
2387    if (local_err) {
2388        error_propagate(errp, local_err);
2389        g_free(prop);
2390        goto out;
2391    }
2392    op->resolve = property_resolve_alias;
2393
2394    object_property_set_description(obj, op->name,
2395                                    target_prop->description,
2396                                    &error_abort);
2397
2398out:
2399    g_free(prop_type);
2400}
2401
2402void object_property_set_description(Object *obj, const char *name,
2403                                     const char *description, Error **errp)
2404{
2405    ObjectProperty *op;
2406
2407    op = object_property_find(obj, name, errp);
2408    if (!op) {
2409        return;
2410    }
2411
2412    g_free(op->description);
2413    op->description = g_strdup(description);
2414}
2415
2416void object_class_property_set_description(ObjectClass *klass,
2417                                           const char *name,
2418                                           const char *description,
2419                                           Error **errp)
2420{
2421    ObjectProperty *op;
2422
2423    op = g_hash_table_lookup(klass->properties, name);
2424    if (!op) {
2425        error_setg(errp, "Property '.%s' not found", name);
2426        return;
2427    }
2428
2429    g_free(op->description);
2430    op->description = g_strdup(description);
2431}
2432
2433static void object_class_init(ObjectClass *klass, void *data)
2434{
2435    object_class_property_add_str(klass, "type", qdev_get_type,
2436                                  NULL, &error_abort);
2437}
2438
2439static void register_types(void)
2440{
2441    static TypeInfo interface_info = {
2442        .name = TYPE_INTERFACE,
2443        .class_size = sizeof(InterfaceClass),
2444        .abstract = true,
2445    };
2446
2447    static TypeInfo object_info = {
2448        .name = TYPE_OBJECT,
2449        .instance_size = sizeof(Object),
2450        .class_init = object_class_init,
2451        .abstract = true,
2452    };
2453
2454    type_interface = type_register_internal(&interface_info);
2455    type_register_internal(&object_info);
2456}
2457
2458type_init(register_types)
2459