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