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