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