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