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