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 "qom/object.h" 14 #include "qemu-common.h" 15 #include "qapi/visitor.h" 16 #include "qapi-visit.h" 17 #include "qapi/string-input-visitor.h" 18 #include "qapi/string-output-visitor.h" 19 #include "qapi/qmp/qerror.h" 20 #include "trace.h" 21 22 /* TODO: replace QObject with a simpler visitor to avoid a dependency 23 * of the QOM core on QObject? */ 24 #include "qom/qom-qobject.h" 25 #include "qapi/qmp/qobject.h" 26 #include "qapi/qmp/qbool.h" 27 #include "qapi/qmp/qint.h" 28 #include "qapi/qmp/qstring.h" 29 30 #define MAX_INTERFACES 32 31 32 typedef struct InterfaceImpl InterfaceImpl; 33 typedef struct TypeImpl TypeImpl; 34 35 struct InterfaceImpl 36 { 37 const char *typename; 38 }; 39 40 struct TypeImpl 41 { 42 const char *name; 43 44 size_t class_size; 45 46 size_t instance_size; 47 48 void (*class_init)(ObjectClass *klass, void *data); 49 void (*class_base_init)(ObjectClass *klass, void *data); 50 void (*class_finalize)(ObjectClass *klass, void *data); 51 52 void *class_data; 53 54 void (*instance_init)(Object *obj); 55 void (*instance_post_init)(Object *obj); 56 void (*instance_finalize)(Object *obj); 57 58 bool abstract; 59 60 const char *parent; 61 TypeImpl *parent_type; 62 63 ObjectClass *class; 64 65 int num_interfaces; 66 InterfaceImpl interfaces[MAX_INTERFACES]; 67 }; 68 69 static Type type_interface; 70 71 static GHashTable *type_table_get(void) 72 { 73 static GHashTable *type_table; 74 75 if (type_table == NULL) { 76 type_table = g_hash_table_new(g_str_hash, g_str_equal); 77 } 78 79 return type_table; 80 } 81 82 static bool enumerating_types; 83 84 static void type_table_add(TypeImpl *ti) 85 { 86 assert(!enumerating_types); 87 g_hash_table_insert(type_table_get(), (void *)ti->name, ti); 88 } 89 90 static TypeImpl *type_table_lookup(const char *name) 91 { 92 return g_hash_table_lookup(type_table_get(), name); 93 } 94 95 static TypeImpl *type_new(const TypeInfo *info) 96 { 97 TypeImpl *ti = g_malloc0(sizeof(*ti)); 98 int i; 99 100 g_assert(info->name != NULL); 101 102 if (type_table_lookup(info->name) != NULL) { 103 fprintf(stderr, "Registering `%s' which already exists\n", info->name); 104 abort(); 105 } 106 107 ti->name = g_strdup(info->name); 108 ti->parent = g_strdup(info->parent); 109 110 ti->class_size = info->class_size; 111 ti->instance_size = info->instance_size; 112 113 ti->class_init = info->class_init; 114 ti->class_base_init = info->class_base_init; 115 ti->class_finalize = info->class_finalize; 116 ti->class_data = info->class_data; 117 118 ti->instance_init = info->instance_init; 119 ti->instance_post_init = info->instance_post_init; 120 ti->instance_finalize = info->instance_finalize; 121 122 ti->abstract = info->abstract; 123 124 for (i = 0; info->interfaces && info->interfaces[i].type; i++) { 125 ti->interfaces[i].typename = g_strdup(info->interfaces[i].type); 126 } 127 ti->num_interfaces = i; 128 129 return ti; 130 } 131 132 static TypeImpl *type_register_internal(const TypeInfo *info) 133 { 134 TypeImpl *ti; 135 ti = type_new(info); 136 137 type_table_add(ti); 138 return ti; 139 } 140 141 TypeImpl *type_register(const TypeInfo *info) 142 { 143 assert(info->parent); 144 return type_register_internal(info); 145 } 146 147 TypeImpl *type_register_static(const TypeInfo *info) 148 { 149 return type_register(info); 150 } 151 152 static TypeImpl *type_get_by_name(const char *name) 153 { 154 if (name == NULL) { 155 return NULL; 156 } 157 158 return type_table_lookup(name); 159 } 160 161 static TypeImpl *type_get_parent(TypeImpl *type) 162 { 163 if (!type->parent_type && type->parent) { 164 type->parent_type = type_get_by_name(type->parent); 165 g_assert(type->parent_type != NULL); 166 } 167 168 return type->parent_type; 169 } 170 171 static bool type_has_parent(TypeImpl *type) 172 { 173 return (type->parent != NULL); 174 } 175 176 static size_t type_class_get_size(TypeImpl *ti) 177 { 178 if (ti->class_size) { 179 return ti->class_size; 180 } 181 182 if (type_has_parent(ti)) { 183 return type_class_get_size(type_get_parent(ti)); 184 } 185 186 return sizeof(ObjectClass); 187 } 188 189 static size_t type_object_get_size(TypeImpl *ti) 190 { 191 if (ti->instance_size) { 192 return ti->instance_size; 193 } 194 195 if (type_has_parent(ti)) { 196 return type_object_get_size(type_get_parent(ti)); 197 } 198 199 return 0; 200 } 201 202 static bool type_is_ancestor(TypeImpl *type, TypeImpl *target_type) 203 { 204 assert(target_type); 205 206 /* Check if typename is a direct ancestor of type */ 207 while (type) { 208 if (type == target_type) { 209 return true; 210 } 211 212 type = type_get_parent(type); 213 } 214 215 return false; 216 } 217 218 static void type_initialize(TypeImpl *ti); 219 220 static void type_initialize_interface(TypeImpl *ti, TypeImpl *interface_type, 221 TypeImpl *parent_type) 222 { 223 InterfaceClass *new_iface; 224 TypeInfo info = { }; 225 TypeImpl *iface_impl; 226 227 info.parent = parent_type->name; 228 info.name = g_strdup_printf("%s::%s", ti->name, interface_type->name); 229 info.abstract = true; 230 231 iface_impl = type_new(&info); 232 iface_impl->parent_type = parent_type; 233 type_initialize(iface_impl); 234 g_free((char *)info.name); 235 236 new_iface = (InterfaceClass *)iface_impl->class; 237 new_iface->concrete_class = ti->class; 238 new_iface->interface_type = interface_type; 239 240 ti->class->interfaces = g_slist_append(ti->class->interfaces, 241 iface_impl->class); 242 } 243 244 static void type_initialize(TypeImpl *ti) 245 { 246 TypeImpl *parent; 247 248 if (ti->class) { 249 return; 250 } 251 252 ti->class_size = type_class_get_size(ti); 253 ti->instance_size = type_object_get_size(ti); 254 255 ti->class = g_malloc0(ti->class_size); 256 257 parent = type_get_parent(ti); 258 if (parent) { 259 type_initialize(parent); 260 GSList *e; 261 int i; 262 263 g_assert(parent->class_size <= ti->class_size); 264 memcpy(ti->class, parent->class, parent->class_size); 265 ti->class->interfaces = NULL; 266 267 for (e = parent->class->interfaces; e; e = e->next) { 268 InterfaceClass *iface = e->data; 269 ObjectClass *klass = OBJECT_CLASS(iface); 270 271 type_initialize_interface(ti, iface->interface_type, klass->type); 272 } 273 274 for (i = 0; i < ti->num_interfaces; i++) { 275 TypeImpl *t = type_get_by_name(ti->interfaces[i].typename); 276 for (e = ti->class->interfaces; e; e = e->next) { 277 TypeImpl *target_type = OBJECT_CLASS(e->data)->type; 278 279 if (type_is_ancestor(target_type, t)) { 280 break; 281 } 282 } 283 284 if (e) { 285 continue; 286 } 287 288 type_initialize_interface(ti, t, t); 289 } 290 } 291 292 ti->class->type = ti; 293 294 while (parent) { 295 if (parent->class_base_init) { 296 parent->class_base_init(ti->class, ti->class_data); 297 } 298 parent = type_get_parent(parent); 299 } 300 301 if (ti->class_init) { 302 ti->class_init(ti->class, ti->class_data); 303 } 304 } 305 306 static void object_init_with_type(Object *obj, TypeImpl *ti) 307 { 308 if (type_has_parent(ti)) { 309 object_init_with_type(obj, type_get_parent(ti)); 310 } 311 312 if (ti->instance_init) { 313 ti->instance_init(obj); 314 } 315 } 316 317 static void object_post_init_with_type(Object *obj, TypeImpl *ti) 318 { 319 if (ti->instance_post_init) { 320 ti->instance_post_init(obj); 321 } 322 323 if (type_has_parent(ti)) { 324 object_post_init_with_type(obj, type_get_parent(ti)); 325 } 326 } 327 328 void object_initialize_with_type(void *data, size_t size, TypeImpl *type) 329 { 330 Object *obj = data; 331 332 g_assert(type != NULL); 333 type_initialize(type); 334 335 g_assert(type->instance_size >= sizeof(Object)); 336 g_assert(type->abstract == false); 337 g_assert(size >= type->instance_size); 338 339 memset(obj, 0, type->instance_size); 340 obj->class = type->class; 341 object_ref(obj); 342 QTAILQ_INIT(&obj->properties); 343 object_init_with_type(obj, type); 344 object_post_init_with_type(obj, type); 345 } 346 347 void object_initialize(void *data, size_t size, const char *typename) 348 { 349 TypeImpl *type = type_get_by_name(typename); 350 351 object_initialize_with_type(data, size, type); 352 } 353 354 static inline bool object_property_is_child(ObjectProperty *prop) 355 { 356 return strstart(prop->type, "child<", NULL); 357 } 358 359 static void object_property_del_all(Object *obj) 360 { 361 while (!QTAILQ_EMPTY(&obj->properties)) { 362 ObjectProperty *prop = QTAILQ_FIRST(&obj->properties); 363 364 QTAILQ_REMOVE(&obj->properties, prop, node); 365 366 if (prop->release) { 367 prop->release(obj, prop->name, prop->opaque); 368 } 369 370 g_free(prop->name); 371 g_free(prop->type); 372 g_free(prop); 373 } 374 } 375 376 static void object_property_del_child(Object *obj, Object *child, Error **errp) 377 { 378 ObjectProperty *prop; 379 380 QTAILQ_FOREACH(prop, &obj->properties, node) { 381 if (object_property_is_child(prop) && prop->opaque == child) { 382 object_property_del(obj, prop->name, errp); 383 break; 384 } 385 } 386 } 387 388 void object_unparent(Object *obj) 389 { 390 if (obj->parent) { 391 object_property_del_child(obj->parent, obj, NULL); 392 } 393 } 394 395 static void object_deinit(Object *obj, TypeImpl *type) 396 { 397 if (type->instance_finalize) { 398 type->instance_finalize(obj); 399 } 400 401 if (type_has_parent(type)) { 402 object_deinit(obj, type_get_parent(type)); 403 } 404 } 405 406 static void object_finalize(void *data) 407 { 408 Object *obj = data; 409 TypeImpl *ti = obj->class->type; 410 411 object_property_del_all(obj); 412 object_deinit(obj, ti); 413 414 g_assert(obj->ref == 0); 415 if (obj->free) { 416 obj->free(obj); 417 } 418 } 419 420 Object *object_new_with_type(Type type) 421 { 422 Object *obj; 423 424 g_assert(type != NULL); 425 type_initialize(type); 426 427 obj = g_malloc(type->instance_size); 428 object_initialize_with_type(obj, type->instance_size, type); 429 obj->free = g_free; 430 431 return obj; 432 } 433 434 Object *object_new(const char *typename) 435 { 436 TypeImpl *ti = type_get_by_name(typename); 437 438 return object_new_with_type(ti); 439 } 440 441 Object *object_dynamic_cast(Object *obj, const char *typename) 442 { 443 if (obj && object_class_dynamic_cast(object_get_class(obj), typename)) { 444 return obj; 445 } 446 447 return NULL; 448 } 449 450 Object *object_dynamic_cast_assert(Object *obj, const char *typename, 451 const char *file, int line, const char *func) 452 { 453 trace_object_dynamic_cast_assert(obj ? obj->class->type->name : "(null)", 454 typename, file, line, func); 455 456 #ifdef CONFIG_QOM_CAST_DEBUG 457 int i; 458 Object *inst; 459 460 for (i = 0; obj && i < OBJECT_CLASS_CAST_CACHE; i++) { 461 if (obj->class->object_cast_cache[i] == typename) { 462 goto out; 463 } 464 } 465 466 inst = object_dynamic_cast(obj, typename); 467 468 if (!inst && obj) { 469 fprintf(stderr, "%s:%d:%s: Object %p is not an instance of type %s\n", 470 file, line, func, obj, typename); 471 abort(); 472 } 473 474 assert(obj == inst); 475 476 if (obj && obj == inst) { 477 for (i = 1; i < OBJECT_CLASS_CAST_CACHE; i++) { 478 obj->class->object_cast_cache[i - 1] = 479 obj->class->object_cast_cache[i]; 480 } 481 obj->class->object_cast_cache[i - 1] = typename; 482 } 483 484 out: 485 #endif 486 return obj; 487 } 488 489 ObjectClass *object_class_dynamic_cast(ObjectClass *class, 490 const char *typename) 491 { 492 ObjectClass *ret = NULL; 493 TypeImpl *target_type; 494 TypeImpl *type; 495 496 if (!class) { 497 return NULL; 498 } 499 500 /* A simple fast path that can trigger a lot for leaf classes. */ 501 type = class->type; 502 if (type->name == typename) { 503 return class; 504 } 505 506 target_type = type_get_by_name(typename); 507 if (!target_type) { 508 /* target class type unknown, so fail the cast */ 509 return NULL; 510 } 511 512 if (type->class->interfaces && 513 type_is_ancestor(target_type, type_interface)) { 514 int found = 0; 515 GSList *i; 516 517 for (i = class->interfaces; i; i = i->next) { 518 ObjectClass *target_class = i->data; 519 520 if (type_is_ancestor(target_class->type, target_type)) { 521 ret = target_class; 522 found++; 523 } 524 } 525 526 /* The match was ambiguous, don't allow a cast */ 527 if (found > 1) { 528 ret = NULL; 529 } 530 } else if (type_is_ancestor(type, target_type)) { 531 ret = class; 532 } 533 534 return ret; 535 } 536 537 ObjectClass *object_class_dynamic_cast_assert(ObjectClass *class, 538 const char *typename, 539 const char *file, int line, 540 const char *func) 541 { 542 ObjectClass *ret; 543 544 trace_object_class_dynamic_cast_assert(class ? class->type->name : "(null)", 545 typename, file, line, func); 546 547 #ifdef CONFIG_QOM_CAST_DEBUG 548 int i; 549 550 for (i = 0; class && i < OBJECT_CLASS_CAST_CACHE; i++) { 551 if (class->class_cast_cache[i] == typename) { 552 ret = class; 553 goto out; 554 } 555 } 556 #else 557 if (!class || !class->interfaces) { 558 return class; 559 } 560 #endif 561 562 ret = object_class_dynamic_cast(class, typename); 563 if (!ret && class) { 564 fprintf(stderr, "%s:%d:%s: Object %p is not an instance of type %s\n", 565 file, line, func, class, typename); 566 abort(); 567 } 568 569 #ifdef CONFIG_QOM_CAST_DEBUG 570 if (class && ret == class) { 571 for (i = 1; i < OBJECT_CLASS_CAST_CACHE; i++) { 572 class->class_cast_cache[i - 1] = class->class_cast_cache[i]; 573 } 574 class->class_cast_cache[i - 1] = typename; 575 } 576 out: 577 #endif 578 return ret; 579 } 580 581 const char *object_get_typename(Object *obj) 582 { 583 return obj->class->type->name; 584 } 585 586 ObjectClass *object_get_class(Object *obj) 587 { 588 return obj->class; 589 } 590 591 bool object_class_is_abstract(ObjectClass *klass) 592 { 593 return klass->type->abstract; 594 } 595 596 const char *object_class_get_name(ObjectClass *klass) 597 { 598 return klass->type->name; 599 } 600 601 ObjectClass *object_class_by_name(const char *typename) 602 { 603 TypeImpl *type = type_get_by_name(typename); 604 605 if (!type) { 606 return NULL; 607 } 608 609 type_initialize(type); 610 611 return type->class; 612 } 613 614 ObjectClass *object_class_get_parent(ObjectClass *class) 615 { 616 TypeImpl *type = type_get_parent(class->type); 617 618 if (!type) { 619 return NULL; 620 } 621 622 type_initialize(type); 623 624 return type->class; 625 } 626 627 typedef struct OCFData 628 { 629 void (*fn)(ObjectClass *klass, void *opaque); 630 const char *implements_type; 631 bool include_abstract; 632 void *opaque; 633 } OCFData; 634 635 static void object_class_foreach_tramp(gpointer key, gpointer value, 636 gpointer opaque) 637 { 638 OCFData *data = opaque; 639 TypeImpl *type = value; 640 ObjectClass *k; 641 642 type_initialize(type); 643 k = type->class; 644 645 if (!data->include_abstract && type->abstract) { 646 return; 647 } 648 649 if (data->implements_type && 650 !object_class_dynamic_cast(k, data->implements_type)) { 651 return; 652 } 653 654 data->fn(k, data->opaque); 655 } 656 657 void object_class_foreach(void (*fn)(ObjectClass *klass, void *opaque), 658 const char *implements_type, bool include_abstract, 659 void *opaque) 660 { 661 OCFData data = { fn, implements_type, include_abstract, opaque }; 662 663 enumerating_types = true; 664 g_hash_table_foreach(type_table_get(), object_class_foreach_tramp, &data); 665 enumerating_types = false; 666 } 667 668 int object_child_foreach(Object *obj, int (*fn)(Object *child, void *opaque), 669 void *opaque) 670 { 671 ObjectProperty *prop; 672 int ret = 0; 673 674 QTAILQ_FOREACH(prop, &obj->properties, node) { 675 if (object_property_is_child(prop)) { 676 ret = fn(prop->opaque, opaque); 677 if (ret != 0) { 678 break; 679 } 680 } 681 } 682 return ret; 683 } 684 685 static void object_class_get_list_tramp(ObjectClass *klass, void *opaque) 686 { 687 GSList **list = opaque; 688 689 *list = g_slist_prepend(*list, klass); 690 } 691 692 GSList *object_class_get_list(const char *implements_type, 693 bool include_abstract) 694 { 695 GSList *list = NULL; 696 697 object_class_foreach(object_class_get_list_tramp, 698 implements_type, include_abstract, &list); 699 return list; 700 } 701 702 void object_ref(Object *obj) 703 { 704 if (!obj) { 705 return; 706 } 707 atomic_inc(&obj->ref); 708 } 709 710 void object_unref(Object *obj) 711 { 712 if (!obj) { 713 return; 714 } 715 g_assert(obj->ref > 0); 716 717 /* parent always holds a reference to its children */ 718 if (atomic_fetch_dec(&obj->ref) == 1) { 719 object_finalize(obj); 720 } 721 } 722 723 ObjectProperty * 724 object_property_add(Object *obj, const char *name, const char *type, 725 ObjectPropertyAccessor *get, 726 ObjectPropertyAccessor *set, 727 ObjectPropertyRelease *release, 728 void *opaque, Error **errp) 729 { 730 ObjectProperty *prop; 731 732 QTAILQ_FOREACH(prop, &obj->properties, node) { 733 if (strcmp(prop->name, name) == 0) { 734 error_setg(errp, "attempt to add duplicate property '%s'" 735 " to object (type '%s')", name, 736 object_get_typename(obj)); 737 return NULL; 738 } 739 } 740 741 prop = g_malloc0(sizeof(*prop)); 742 743 prop->name = g_strdup(name); 744 prop->type = g_strdup(type); 745 746 prop->get = get; 747 prop->set = set; 748 prop->release = release; 749 prop->opaque = opaque; 750 751 QTAILQ_INSERT_TAIL(&obj->properties, prop, node); 752 return prop; 753 } 754 755 ObjectProperty *object_property_find(Object *obj, const char *name, 756 Error **errp) 757 { 758 ObjectProperty *prop; 759 760 QTAILQ_FOREACH(prop, &obj->properties, node) { 761 if (strcmp(prop->name, name) == 0) { 762 return prop; 763 } 764 } 765 766 error_setg(errp, "Property '.%s' not found", name); 767 return NULL; 768 } 769 770 void object_property_del(Object *obj, const char *name, Error **errp) 771 { 772 ObjectProperty *prop = object_property_find(obj, name, errp); 773 if (prop == NULL) { 774 return; 775 } 776 777 if (prop->release) { 778 prop->release(obj, name, prop->opaque); 779 } 780 781 QTAILQ_REMOVE(&obj->properties, prop, node); 782 783 g_free(prop->name); 784 g_free(prop->type); 785 g_free(prop); 786 } 787 788 void object_property_get(Object *obj, Visitor *v, const char *name, 789 Error **errp) 790 { 791 ObjectProperty *prop = object_property_find(obj, name, errp); 792 if (prop == NULL) { 793 return; 794 } 795 796 if (!prop->get) { 797 error_set(errp, QERR_PERMISSION_DENIED); 798 } else { 799 prop->get(obj, v, prop->opaque, name, errp); 800 } 801 } 802 803 void object_property_set(Object *obj, Visitor *v, const char *name, 804 Error **errp) 805 { 806 ObjectProperty *prop = object_property_find(obj, name, errp); 807 if (prop == NULL) { 808 return; 809 } 810 811 if (!prop->set) { 812 error_set(errp, QERR_PERMISSION_DENIED); 813 } else { 814 prop->set(obj, v, prop->opaque, name, errp); 815 } 816 } 817 818 void object_property_set_str(Object *obj, const char *value, 819 const char *name, Error **errp) 820 { 821 QString *qstr = qstring_from_str(value); 822 object_property_set_qobject(obj, QOBJECT(qstr), name, errp); 823 824 QDECREF(qstr); 825 } 826 827 char *object_property_get_str(Object *obj, const char *name, 828 Error **errp) 829 { 830 QObject *ret = object_property_get_qobject(obj, name, errp); 831 QString *qstring; 832 char *retval; 833 834 if (!ret) { 835 return NULL; 836 } 837 qstring = qobject_to_qstring(ret); 838 if (!qstring) { 839 error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, "string"); 840 retval = NULL; 841 } else { 842 retval = g_strdup(qstring_get_str(qstring)); 843 } 844 845 QDECREF(qstring); 846 return retval; 847 } 848 849 void object_property_set_link(Object *obj, Object *value, 850 const char *name, Error **errp) 851 { 852 gchar *path = object_get_canonical_path(value); 853 object_property_set_str(obj, path, name, errp); 854 g_free(path); 855 } 856 857 Object *object_property_get_link(Object *obj, const char *name, 858 Error **errp) 859 { 860 char *str = object_property_get_str(obj, name, errp); 861 Object *target = NULL; 862 863 if (str && *str) { 864 target = object_resolve_path(str, NULL); 865 if (!target) { 866 error_set(errp, QERR_DEVICE_NOT_FOUND, str); 867 } 868 } 869 870 g_free(str); 871 return target; 872 } 873 874 void object_property_set_bool(Object *obj, bool value, 875 const char *name, Error **errp) 876 { 877 QBool *qbool = qbool_from_int(value); 878 object_property_set_qobject(obj, QOBJECT(qbool), name, errp); 879 880 QDECREF(qbool); 881 } 882 883 bool object_property_get_bool(Object *obj, const char *name, 884 Error **errp) 885 { 886 QObject *ret = object_property_get_qobject(obj, name, errp); 887 QBool *qbool; 888 bool retval; 889 890 if (!ret) { 891 return false; 892 } 893 qbool = qobject_to_qbool(ret); 894 if (!qbool) { 895 error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, "boolean"); 896 retval = false; 897 } else { 898 retval = qbool_get_int(qbool); 899 } 900 901 QDECREF(qbool); 902 return retval; 903 } 904 905 void object_property_set_int(Object *obj, int64_t value, 906 const char *name, Error **errp) 907 { 908 QInt *qint = qint_from_int(value); 909 object_property_set_qobject(obj, QOBJECT(qint), name, errp); 910 911 QDECREF(qint); 912 } 913 914 int64_t object_property_get_int(Object *obj, const char *name, 915 Error **errp) 916 { 917 QObject *ret = object_property_get_qobject(obj, name, errp); 918 QInt *qint; 919 int64_t retval; 920 921 if (!ret) { 922 return -1; 923 } 924 qint = qobject_to_qint(ret); 925 if (!qint) { 926 error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, "int"); 927 retval = -1; 928 } else { 929 retval = qint_get_int(qint); 930 } 931 932 QDECREF(qint); 933 return retval; 934 } 935 936 int object_property_get_enum(Object *obj, const char *name, 937 const char *strings[], Error **errp) 938 { 939 StringOutputVisitor *sov; 940 StringInputVisitor *siv; 941 int ret; 942 943 sov = string_output_visitor_new(false); 944 object_property_get(obj, string_output_get_visitor(sov), name, errp); 945 siv = string_input_visitor_new(string_output_get_string(sov)); 946 string_output_visitor_cleanup(sov); 947 visit_type_enum(string_input_get_visitor(siv), 948 &ret, strings, NULL, name, errp); 949 string_input_visitor_cleanup(siv); 950 951 return ret; 952 } 953 954 void object_property_get_uint16List(Object *obj, const char *name, 955 uint16List **list, Error **errp) 956 { 957 StringOutputVisitor *ov; 958 StringInputVisitor *iv; 959 960 ov = string_output_visitor_new(false); 961 object_property_get(obj, string_output_get_visitor(ov), 962 name, errp); 963 iv = string_input_visitor_new(string_output_get_string(ov)); 964 visit_type_uint16List(string_input_get_visitor(iv), 965 list, NULL, errp); 966 string_output_visitor_cleanup(ov); 967 string_input_visitor_cleanup(iv); 968 } 969 970 void object_property_parse(Object *obj, const char *string, 971 const char *name, Error **errp) 972 { 973 StringInputVisitor *mi; 974 mi = string_input_visitor_new(string); 975 object_property_set(obj, string_input_get_visitor(mi), name, errp); 976 977 string_input_visitor_cleanup(mi); 978 } 979 980 char *object_property_print(Object *obj, const char *name, bool human, 981 Error **errp) 982 { 983 StringOutputVisitor *mo; 984 char *string; 985 986 mo = string_output_visitor_new(human); 987 object_property_get(obj, string_output_get_visitor(mo), name, errp); 988 string = string_output_get_string(mo); 989 string_output_visitor_cleanup(mo); 990 return string; 991 } 992 993 const char *object_property_get_type(Object *obj, const char *name, Error **errp) 994 { 995 ObjectProperty *prop = object_property_find(obj, name, errp); 996 if (prop == NULL) { 997 return NULL; 998 } 999 1000 return prop->type; 1001 } 1002 1003 Object *object_get_root(void) 1004 { 1005 static Object *root; 1006 1007 if (!root) { 1008 root = object_new("container"); 1009 } 1010 1011 return root; 1012 } 1013 1014 static void object_get_child_property(Object *obj, Visitor *v, void *opaque, 1015 const char *name, Error **errp) 1016 { 1017 Object *child = opaque; 1018 gchar *path; 1019 1020 path = object_get_canonical_path(child); 1021 visit_type_str(v, &path, name, errp); 1022 g_free(path); 1023 } 1024 1025 static Object *object_resolve_child_property(Object *parent, void *opaque, const gchar *part) 1026 { 1027 return opaque; 1028 } 1029 1030 static void object_finalize_child_property(Object *obj, const char *name, 1031 void *opaque) 1032 { 1033 Object *child = opaque; 1034 1035 if (child->class->unparent) { 1036 (child->class->unparent)(child); 1037 } 1038 child->parent = NULL; 1039 object_unref(child); 1040 } 1041 1042 void object_property_add_child(Object *obj, const char *name, 1043 Object *child, Error **errp) 1044 { 1045 Error *local_err = NULL; 1046 gchar *type; 1047 ObjectProperty *op; 1048 1049 type = g_strdup_printf("child<%s>", object_get_typename(OBJECT(child))); 1050 1051 op = object_property_add(obj, name, type, object_get_child_property, NULL, 1052 object_finalize_child_property, child, &local_err); 1053 if (local_err) { 1054 error_propagate(errp, local_err); 1055 goto out; 1056 } 1057 1058 op->resolve = object_resolve_child_property; 1059 object_ref(child); 1060 g_assert(child->parent == NULL); 1061 child->parent = obj; 1062 1063 out: 1064 g_free(type); 1065 } 1066 1067 void object_property_allow_set_link(Object *obj, const char *name, 1068 Object *val, Error **errp) 1069 { 1070 /* Allow the link to be set, always */ 1071 } 1072 1073 typedef struct { 1074 Object **child; 1075 void (*check)(Object *, const char *, Object *, Error **); 1076 ObjectPropertyLinkFlags flags; 1077 } LinkProperty; 1078 1079 static void object_get_link_property(Object *obj, Visitor *v, void *opaque, 1080 const char *name, Error **errp) 1081 { 1082 LinkProperty *lprop = opaque; 1083 Object **child = lprop->child; 1084 gchar *path; 1085 1086 if (*child) { 1087 path = object_get_canonical_path(*child); 1088 visit_type_str(v, &path, name, errp); 1089 g_free(path); 1090 } else { 1091 path = (gchar *)""; 1092 visit_type_str(v, &path, name, errp); 1093 } 1094 } 1095 1096 /* 1097 * object_resolve_link: 1098 * 1099 * Lookup an object and ensure its type matches the link property type. This 1100 * is similar to object_resolve_path() except type verification against the 1101 * link property is performed. 1102 * 1103 * Returns: The matched object or NULL on path lookup failures. 1104 */ 1105 static Object *object_resolve_link(Object *obj, const char *name, 1106 const char *path, Error **errp) 1107 { 1108 const char *type; 1109 gchar *target_type; 1110 bool ambiguous = false; 1111 Object *target; 1112 1113 /* Go from link<FOO> to FOO. */ 1114 type = object_property_get_type(obj, name, NULL); 1115 target_type = g_strndup(&type[5], strlen(type) - 6); 1116 target = object_resolve_path_type(path, target_type, &ambiguous); 1117 1118 if (ambiguous) { 1119 error_set(errp, ERROR_CLASS_GENERIC_ERROR, 1120 "Path '%s' does not uniquely identify an object", path); 1121 } else if (!target) { 1122 target = object_resolve_path(path, &ambiguous); 1123 if (target || ambiguous) { 1124 error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, target_type); 1125 } else { 1126 error_set(errp, QERR_DEVICE_NOT_FOUND, path); 1127 } 1128 target = NULL; 1129 } 1130 g_free(target_type); 1131 1132 return target; 1133 } 1134 1135 static void object_set_link_property(Object *obj, Visitor *v, void *opaque, 1136 const char *name, Error **errp) 1137 { 1138 Error *local_err = NULL; 1139 LinkProperty *prop = opaque; 1140 Object **child = prop->child; 1141 Object *old_target = *child; 1142 Object *new_target = NULL; 1143 char *path = NULL; 1144 1145 visit_type_str(v, &path, name, &local_err); 1146 1147 if (!local_err && strcmp(path, "") != 0) { 1148 new_target = object_resolve_link(obj, name, path, &local_err); 1149 } 1150 1151 g_free(path); 1152 if (local_err) { 1153 error_propagate(errp, local_err); 1154 return; 1155 } 1156 1157 prop->check(obj, name, new_target, &local_err); 1158 if (local_err) { 1159 error_propagate(errp, local_err); 1160 return; 1161 } 1162 1163 object_ref(new_target); 1164 *child = new_target; 1165 object_unref(old_target); 1166 } 1167 1168 static Object *object_resolve_link_property(Object *parent, void *opaque, const gchar *part) 1169 { 1170 LinkProperty *lprop = opaque; 1171 1172 return *lprop->child; 1173 } 1174 1175 static void object_release_link_property(Object *obj, const char *name, 1176 void *opaque) 1177 { 1178 LinkProperty *prop = opaque; 1179 1180 if ((prop->flags & OBJ_PROP_LINK_UNREF_ON_RELEASE) && *prop->child) { 1181 object_unref(*prop->child); 1182 } 1183 g_free(prop); 1184 } 1185 1186 void object_property_add_link(Object *obj, const char *name, 1187 const char *type, Object **child, 1188 void (*check)(Object *, const char *, 1189 Object *, Error **), 1190 ObjectPropertyLinkFlags flags, 1191 Error **errp) 1192 { 1193 Error *local_err = NULL; 1194 LinkProperty *prop = g_malloc(sizeof(*prop)); 1195 gchar *full_type; 1196 ObjectProperty *op; 1197 1198 prop->child = child; 1199 prop->check = check; 1200 prop->flags = flags; 1201 1202 full_type = g_strdup_printf("link<%s>", type); 1203 1204 op = object_property_add(obj, name, full_type, 1205 object_get_link_property, 1206 check ? object_set_link_property : NULL, 1207 object_release_link_property, 1208 prop, 1209 &local_err); 1210 if (local_err) { 1211 error_propagate(errp, local_err); 1212 g_free(prop); 1213 goto out; 1214 } 1215 1216 op->resolve = object_resolve_link_property; 1217 1218 out: 1219 g_free(full_type); 1220 } 1221 1222 gchar *object_get_canonical_path_component(Object *obj) 1223 { 1224 ObjectProperty *prop = NULL; 1225 1226 g_assert(obj); 1227 g_assert(obj->parent != NULL); 1228 1229 QTAILQ_FOREACH(prop, &obj->parent->properties, node) { 1230 if (!object_property_is_child(prop)) { 1231 continue; 1232 } 1233 1234 if (prop->opaque == obj) { 1235 return g_strdup(prop->name); 1236 } 1237 } 1238 1239 /* obj had a parent but was not a child, should never happen */ 1240 g_assert_not_reached(); 1241 return NULL; 1242 } 1243 1244 gchar *object_get_canonical_path(Object *obj) 1245 { 1246 Object *root = object_get_root(); 1247 char *newpath, *path = NULL; 1248 1249 while (obj != root) { 1250 char *component = object_get_canonical_path_component(obj); 1251 1252 if (path) { 1253 newpath = g_strdup_printf("%s/%s", component, path); 1254 g_free(component); 1255 g_free(path); 1256 path = newpath; 1257 } else { 1258 path = component; 1259 } 1260 1261 obj = obj->parent; 1262 } 1263 1264 newpath = g_strdup_printf("/%s", path ? path : ""); 1265 g_free(path); 1266 1267 return newpath; 1268 } 1269 1270 Object *object_resolve_path_component(Object *parent, const gchar *part) 1271 { 1272 ObjectProperty *prop = object_property_find(parent, part, NULL); 1273 if (prop == NULL) { 1274 return NULL; 1275 } 1276 1277 if (prop->resolve) { 1278 return prop->resolve(parent, prop->opaque, part); 1279 } else { 1280 return NULL; 1281 } 1282 } 1283 1284 static Object *object_resolve_abs_path(Object *parent, 1285 gchar **parts, 1286 const char *typename, 1287 int index) 1288 { 1289 Object *child; 1290 1291 if (parts[index] == NULL) { 1292 return object_dynamic_cast(parent, typename); 1293 } 1294 1295 if (strcmp(parts[index], "") == 0) { 1296 return object_resolve_abs_path(parent, parts, typename, index + 1); 1297 } 1298 1299 child = object_resolve_path_component(parent, parts[index]); 1300 if (!child) { 1301 return NULL; 1302 } 1303 1304 return object_resolve_abs_path(child, parts, typename, index + 1); 1305 } 1306 1307 static Object *object_resolve_partial_path(Object *parent, 1308 gchar **parts, 1309 const char *typename, 1310 bool *ambiguous) 1311 { 1312 Object *obj; 1313 ObjectProperty *prop; 1314 1315 obj = object_resolve_abs_path(parent, parts, typename, 0); 1316 1317 QTAILQ_FOREACH(prop, &parent->properties, node) { 1318 Object *found; 1319 1320 if (!object_property_is_child(prop)) { 1321 continue; 1322 } 1323 1324 found = object_resolve_partial_path(prop->opaque, parts, 1325 typename, ambiguous); 1326 if (found) { 1327 if (obj) { 1328 if (ambiguous) { 1329 *ambiguous = true; 1330 } 1331 return NULL; 1332 } 1333 obj = found; 1334 } 1335 1336 if (ambiguous && *ambiguous) { 1337 return NULL; 1338 } 1339 } 1340 1341 return obj; 1342 } 1343 1344 Object *object_resolve_path_type(const char *path, const char *typename, 1345 bool *ambiguous) 1346 { 1347 Object *obj; 1348 gchar **parts; 1349 1350 parts = g_strsplit(path, "/", 0); 1351 assert(parts); 1352 1353 if (parts[0] == NULL || strcmp(parts[0], "") != 0) { 1354 if (ambiguous) { 1355 *ambiguous = false; 1356 } 1357 obj = object_resolve_partial_path(object_get_root(), parts, 1358 typename, ambiguous); 1359 } else { 1360 obj = object_resolve_abs_path(object_get_root(), parts, typename, 1); 1361 } 1362 1363 g_strfreev(parts); 1364 1365 return obj; 1366 } 1367 1368 Object *object_resolve_path(const char *path, bool *ambiguous) 1369 { 1370 return object_resolve_path_type(path, TYPE_OBJECT, ambiguous); 1371 } 1372 1373 typedef struct StringProperty 1374 { 1375 char *(*get)(Object *, Error **); 1376 void (*set)(Object *, const char *, Error **); 1377 } StringProperty; 1378 1379 static void property_get_str(Object *obj, Visitor *v, void *opaque, 1380 const char *name, Error **errp) 1381 { 1382 StringProperty *prop = opaque; 1383 char *value; 1384 1385 value = prop->get(obj, errp); 1386 if (value) { 1387 visit_type_str(v, &value, name, errp); 1388 g_free(value); 1389 } 1390 } 1391 1392 static void property_set_str(Object *obj, Visitor *v, void *opaque, 1393 const char *name, Error **errp) 1394 { 1395 StringProperty *prop = opaque; 1396 char *value; 1397 Error *local_err = NULL; 1398 1399 visit_type_str(v, &value, name, &local_err); 1400 if (local_err) { 1401 error_propagate(errp, local_err); 1402 return; 1403 } 1404 1405 prop->set(obj, value, errp); 1406 g_free(value); 1407 } 1408 1409 static void property_release_str(Object *obj, const char *name, 1410 void *opaque) 1411 { 1412 StringProperty *prop = opaque; 1413 g_free(prop); 1414 } 1415 1416 void object_property_add_str(Object *obj, const char *name, 1417 char *(*get)(Object *, Error **), 1418 void (*set)(Object *, const char *, Error **), 1419 Error **errp) 1420 { 1421 Error *local_err = NULL; 1422 StringProperty *prop = g_malloc0(sizeof(*prop)); 1423 1424 prop->get = get; 1425 prop->set = set; 1426 1427 object_property_add(obj, name, "string", 1428 get ? property_get_str : NULL, 1429 set ? property_set_str : NULL, 1430 property_release_str, 1431 prop, &local_err); 1432 if (local_err) { 1433 error_propagate(errp, local_err); 1434 g_free(prop); 1435 } 1436 } 1437 1438 typedef struct BoolProperty 1439 { 1440 bool (*get)(Object *, Error **); 1441 void (*set)(Object *, bool, Error **); 1442 } BoolProperty; 1443 1444 static void property_get_bool(Object *obj, Visitor *v, void *opaque, 1445 const char *name, Error **errp) 1446 { 1447 BoolProperty *prop = opaque; 1448 bool value; 1449 1450 value = prop->get(obj, errp); 1451 visit_type_bool(v, &value, name, errp); 1452 } 1453 1454 static void property_set_bool(Object *obj, Visitor *v, void *opaque, 1455 const char *name, Error **errp) 1456 { 1457 BoolProperty *prop = opaque; 1458 bool value; 1459 Error *local_err = NULL; 1460 1461 visit_type_bool(v, &value, name, &local_err); 1462 if (local_err) { 1463 error_propagate(errp, local_err); 1464 return; 1465 } 1466 1467 prop->set(obj, value, errp); 1468 } 1469 1470 static void property_release_bool(Object *obj, const char *name, 1471 void *opaque) 1472 { 1473 BoolProperty *prop = opaque; 1474 g_free(prop); 1475 } 1476 1477 void object_property_add_bool(Object *obj, const char *name, 1478 bool (*get)(Object *, Error **), 1479 void (*set)(Object *, bool, Error **), 1480 Error **errp) 1481 { 1482 Error *local_err = NULL; 1483 BoolProperty *prop = g_malloc0(sizeof(*prop)); 1484 1485 prop->get = get; 1486 prop->set = set; 1487 1488 object_property_add(obj, name, "bool", 1489 get ? property_get_bool : NULL, 1490 set ? property_set_bool : NULL, 1491 property_release_bool, 1492 prop, &local_err); 1493 if (local_err) { 1494 error_propagate(errp, local_err); 1495 g_free(prop); 1496 } 1497 } 1498 1499 static char *qdev_get_type(Object *obj, Error **errp) 1500 { 1501 return g_strdup(object_get_typename(obj)); 1502 } 1503 1504 static void property_get_uint8_ptr(Object *obj, Visitor *v, 1505 void *opaque, const char *name, 1506 Error **errp) 1507 { 1508 uint8_t value = *(uint8_t *)opaque; 1509 visit_type_uint8(v, &value, name, errp); 1510 } 1511 1512 static void property_get_uint16_ptr(Object *obj, Visitor *v, 1513 void *opaque, const char *name, 1514 Error **errp) 1515 { 1516 uint16_t value = *(uint16_t *)opaque; 1517 visit_type_uint16(v, &value, name, errp); 1518 } 1519 1520 static void property_get_uint32_ptr(Object *obj, Visitor *v, 1521 void *opaque, const char *name, 1522 Error **errp) 1523 { 1524 uint32_t value = *(uint32_t *)opaque; 1525 visit_type_uint32(v, &value, name, errp); 1526 } 1527 1528 static void property_get_uint64_ptr(Object *obj, Visitor *v, 1529 void *opaque, const char *name, 1530 Error **errp) 1531 { 1532 uint64_t value = *(uint64_t *)opaque; 1533 visit_type_uint64(v, &value, name, errp); 1534 } 1535 1536 void object_property_add_uint8_ptr(Object *obj, const char *name, 1537 const uint8_t *v, Error **errp) 1538 { 1539 object_property_add(obj, name, "uint8", property_get_uint8_ptr, 1540 NULL, NULL, (void *)v, errp); 1541 } 1542 1543 void object_property_add_uint16_ptr(Object *obj, const char *name, 1544 const uint16_t *v, Error **errp) 1545 { 1546 object_property_add(obj, name, "uint16", property_get_uint16_ptr, 1547 NULL, NULL, (void *)v, errp); 1548 } 1549 1550 void object_property_add_uint32_ptr(Object *obj, const char *name, 1551 const uint32_t *v, Error **errp) 1552 { 1553 object_property_add(obj, name, "uint32", property_get_uint32_ptr, 1554 NULL, NULL, (void *)v, errp); 1555 } 1556 1557 void object_property_add_uint64_ptr(Object *obj, const char *name, 1558 const uint64_t *v, Error **errp) 1559 { 1560 object_property_add(obj, name, "uint64", property_get_uint64_ptr, 1561 NULL, NULL, (void *)v, errp); 1562 } 1563 1564 typedef struct { 1565 Object *target_obj; 1566 const char *target_name; 1567 } AliasProperty; 1568 1569 static void property_get_alias(Object *obj, struct Visitor *v, void *opaque, 1570 const char *name, Error **errp) 1571 { 1572 AliasProperty *prop = opaque; 1573 1574 object_property_get(prop->target_obj, v, prop->target_name, errp); 1575 } 1576 1577 static void property_set_alias(Object *obj, struct Visitor *v, void *opaque, 1578 const char *name, Error **errp) 1579 { 1580 AliasProperty *prop = opaque; 1581 1582 object_property_set(prop->target_obj, v, prop->target_name, errp); 1583 } 1584 1585 static Object *property_resolve_alias(Object *obj, void *opaque, 1586 const gchar *part) 1587 { 1588 AliasProperty *prop = opaque; 1589 1590 return object_resolve_path_component(prop->target_obj, prop->target_name); 1591 } 1592 1593 static void property_release_alias(Object *obj, const char *name, void *opaque) 1594 { 1595 AliasProperty *prop = opaque; 1596 1597 g_free(prop); 1598 } 1599 1600 void object_property_add_alias(Object *obj, const char *name, 1601 Object *target_obj, const char *target_name, 1602 Error **errp) 1603 { 1604 AliasProperty *prop; 1605 ObjectProperty *op; 1606 ObjectProperty *target_prop; 1607 gchar *prop_type; 1608 1609 target_prop = object_property_find(target_obj, target_name, errp); 1610 if (!target_prop) { 1611 return; 1612 } 1613 1614 if (object_property_is_child(target_prop)) { 1615 prop_type = g_strdup_printf("link%s", 1616 target_prop->type + strlen("child")); 1617 } else { 1618 prop_type = g_strdup(target_prop->type); 1619 } 1620 1621 prop = g_malloc(sizeof(*prop)); 1622 prop->target_obj = target_obj; 1623 prop->target_name = target_name; 1624 1625 op = object_property_add(obj, name, prop_type, 1626 property_get_alias, 1627 property_set_alias, 1628 property_release_alias, 1629 prop, errp); 1630 op->resolve = property_resolve_alias; 1631 1632 g_free(prop_type); 1633 } 1634 1635 static void object_instance_init(Object *obj) 1636 { 1637 object_property_add_str(obj, "type", qdev_get_type, NULL, NULL); 1638 } 1639 1640 static void register_types(void) 1641 { 1642 static TypeInfo interface_info = { 1643 .name = TYPE_INTERFACE, 1644 .class_size = sizeof(InterfaceClass), 1645 .abstract = true, 1646 }; 1647 1648 static TypeInfo object_info = { 1649 .name = TYPE_OBJECT, 1650 .instance_size = sizeof(Object), 1651 .instance_init = object_instance_init, 1652 .abstract = true, 1653 }; 1654 1655 type_interface = type_register_internal(&interface_info); 1656 type_register_internal(&object_info); 1657 } 1658 1659 type_init(register_types) 1660