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