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