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