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/object.h" 14 #include "qemu-common.h" 15 #include "qapi/qapi-visit-core.h" 16 #include "qapi/string-input-visitor.h" 17 #include "qapi/string-output-visitor.h" 18 19 /* TODO: replace QObject with a simpler visitor to avoid a dependency 20 * of the QOM core on QObject? */ 21 #include "qemu/qom-qobject.h" 22 #include "qobject.h" 23 #include "qbool.h" 24 #include "qint.h" 25 #include "qstring.h" 26 27 #define MAX_INTERFACES 32 28 29 typedef struct InterfaceImpl InterfaceImpl; 30 typedef struct TypeImpl TypeImpl; 31 32 struct InterfaceImpl 33 { 34 const char *parent; 35 void (*interface_initfn)(ObjectClass *class, void *data); 36 TypeImpl *type; 37 }; 38 39 struct TypeImpl 40 { 41 const char *name; 42 43 size_t class_size; 44 45 size_t instance_size; 46 47 void (*class_init)(ObjectClass *klass, void *data); 48 void (*class_finalize)(ObjectClass *klass, void *data); 49 50 void *class_data; 51 52 void (*instance_init)(Object *obj); 53 void (*instance_finalize)(Object *obj); 54 55 bool abstract; 56 57 const char *parent; 58 TypeImpl *parent_type; 59 60 ObjectClass *class; 61 62 int num_interfaces; 63 InterfaceImpl interfaces[MAX_INTERFACES]; 64 }; 65 66 typedef struct Interface 67 { 68 Object parent; 69 Object *obj; 70 } Interface; 71 72 #define INTERFACE(obj) OBJECT_CHECK(Interface, obj, TYPE_INTERFACE) 73 74 static Type type_interface; 75 76 static GHashTable *type_table_get(void) 77 { 78 static GHashTable *type_table; 79 80 if (type_table == NULL) { 81 type_table = g_hash_table_new(g_str_hash, g_str_equal); 82 } 83 84 return type_table; 85 } 86 87 static void type_table_add(TypeImpl *ti) 88 { 89 g_hash_table_insert(type_table_get(), (void *)ti->name, ti); 90 } 91 92 static TypeImpl *type_table_lookup(const char *name) 93 { 94 return g_hash_table_lookup(type_table_get(), name); 95 } 96 97 TypeImpl *type_register(const TypeInfo *info) 98 { 99 TypeImpl *ti = g_malloc0(sizeof(*ti)); 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_finalize = info->class_finalize; 116 ti->class_data = info->class_data; 117 118 ti->instance_init = info->instance_init; 119 ti->instance_finalize = info->instance_finalize; 120 121 ti->abstract = info->abstract; 122 123 if (info->interfaces) { 124 int i; 125 126 for (i = 0; info->interfaces[i].type; i++) { 127 ti->interfaces[i].parent = info->interfaces[i].type; 128 ti->interfaces[i].interface_initfn = info->interfaces[i].interface_initfn; 129 ti->num_interfaces++; 130 } 131 } 132 133 type_table_add(ti); 134 135 return ti; 136 } 137 138 TypeImpl *type_register_static(const TypeInfo *info) 139 { 140 return type_register(info); 141 } 142 143 static TypeImpl *type_get_by_name(const char *name) 144 { 145 if (name == NULL) { 146 return NULL; 147 } 148 149 return type_table_lookup(name); 150 } 151 152 static TypeImpl *type_get_parent(TypeImpl *type) 153 { 154 if (!type->parent_type && type->parent) { 155 type->parent_type = type_get_by_name(type->parent); 156 g_assert(type->parent_type != NULL); 157 } 158 159 return type->parent_type; 160 } 161 162 static bool type_has_parent(TypeImpl *type) 163 { 164 return (type->parent != NULL); 165 } 166 167 static size_t type_class_get_size(TypeImpl *ti) 168 { 169 if (ti->class_size) { 170 return ti->class_size; 171 } 172 173 if (type_has_parent(ti)) { 174 return type_class_get_size(type_get_parent(ti)); 175 } 176 177 return sizeof(ObjectClass); 178 } 179 180 static size_t type_object_get_size(TypeImpl *ti) 181 { 182 if (ti->instance_size) { 183 return ti->instance_size; 184 } 185 186 if (type_has_parent(ti)) { 187 return type_object_get_size(type_get_parent(ti)); 188 } 189 190 return 0; 191 } 192 193 static void type_class_interface_init(TypeImpl *ti, InterfaceImpl *iface) 194 { 195 TypeInfo info = { 196 .instance_size = sizeof(Interface), 197 .parent = iface->parent, 198 .class_size = sizeof(InterfaceClass), 199 .class_init = iface->interface_initfn, 200 .abstract = true, 201 }; 202 char *name = g_strdup_printf("<%s::%s>", ti->name, iface->parent); 203 204 info.name = name; 205 iface->type = type_register(&info); 206 g_free(name); 207 } 208 209 static void type_initialize(TypeImpl *ti) 210 { 211 size_t class_size = sizeof(ObjectClass); 212 int i; 213 214 if (ti->class) { 215 return; 216 } 217 218 ti->class_size = type_class_get_size(ti); 219 ti->instance_size = type_object_get_size(ti); 220 221 ti->class = g_malloc0(ti->class_size); 222 ti->class->type = ti; 223 224 if (type_has_parent(ti)) { 225 TypeImpl *parent = type_get_parent(ti); 226 227 type_initialize(parent); 228 229 class_size = parent->class_size; 230 g_assert(parent->class_size <= ti->class_size); 231 232 memcpy((void *)ti->class + sizeof(ObjectClass), 233 (void *)parent->class + sizeof(ObjectClass), 234 parent->class_size - sizeof(ObjectClass)); 235 } 236 237 memset((void *)ti->class + class_size, 0, ti->class_size - class_size); 238 239 for (i = 0; i < ti->num_interfaces; i++) { 240 type_class_interface_init(ti, &ti->interfaces[i]); 241 } 242 243 if (ti->class_init) { 244 ti->class_init(ti->class, ti->class_data); 245 } 246 } 247 248 static void object_interface_init(Object *obj, InterfaceImpl *iface) 249 { 250 TypeImpl *ti = iface->type; 251 Interface *iface_obj; 252 253 iface_obj = INTERFACE(object_new(ti->name)); 254 iface_obj->obj = obj; 255 256 obj->interfaces = g_slist_prepend(obj->interfaces, iface_obj); 257 } 258 259 static void object_init_with_type(Object *obj, TypeImpl *ti) 260 { 261 int i; 262 263 if (type_has_parent(ti)) { 264 object_init_with_type(obj, type_get_parent(ti)); 265 } 266 267 for (i = 0; i < ti->num_interfaces; i++) { 268 object_interface_init(obj, &ti->interfaces[i]); 269 } 270 271 if (ti->instance_init) { 272 ti->instance_init(obj); 273 } 274 } 275 276 void object_initialize_with_type(void *data, TypeImpl *type) 277 { 278 Object *obj = data; 279 280 g_assert(type != NULL); 281 type_initialize(type); 282 283 g_assert(type->instance_size >= sizeof(Object)); 284 g_assert(type->abstract == false); 285 286 memset(obj, 0, type->instance_size); 287 obj->class = type->class; 288 QTAILQ_INIT(&obj->properties); 289 object_init_with_type(obj, type); 290 } 291 292 void object_initialize(void *data, const char *typename) 293 { 294 TypeImpl *type = type_get_by_name(typename); 295 296 object_initialize_with_type(data, type); 297 } 298 299 static void object_property_del_all(Object *obj) 300 { 301 while (!QTAILQ_EMPTY(&obj->properties)) { 302 ObjectProperty *prop = QTAILQ_FIRST(&obj->properties); 303 304 QTAILQ_REMOVE(&obj->properties, prop, node); 305 306 if (prop->release) { 307 prop->release(obj, prop->name, prop->opaque); 308 } 309 310 g_free(prop->name); 311 g_free(prop->type); 312 g_free(prop); 313 } 314 } 315 316 static void object_property_del_child(Object *obj, Object *child, Error **errp) 317 { 318 ObjectProperty *prop; 319 320 QTAILQ_FOREACH(prop, &obj->properties, node) { 321 if (strstart(prop->type, "child<", NULL) && prop->opaque == child) { 322 object_property_del(obj, prop->name, errp); 323 break; 324 } 325 } 326 } 327 328 void object_unparent(Object *obj) 329 { 330 if (obj->parent) { 331 object_property_del_child(obj->parent, obj, NULL); 332 } 333 } 334 335 static void object_deinit(Object *obj, TypeImpl *type) 336 { 337 if (type->instance_finalize) { 338 type->instance_finalize(obj); 339 } 340 341 while (obj->interfaces) { 342 Interface *iface_obj = obj->interfaces->data; 343 obj->interfaces = g_slist_delete_link(obj->interfaces, obj->interfaces); 344 object_delete(OBJECT(iface_obj)); 345 } 346 347 if (type_has_parent(type)) { 348 object_deinit(obj, type_get_parent(type)); 349 } 350 351 object_unparent(obj); 352 } 353 354 void object_finalize(void *data) 355 { 356 Object *obj = data; 357 TypeImpl *ti = obj->class->type; 358 359 object_deinit(obj, ti); 360 object_property_del_all(obj); 361 362 g_assert(obj->ref == 0); 363 } 364 365 Object *object_new_with_type(Type type) 366 { 367 Object *obj; 368 369 g_assert(type != NULL); 370 type_initialize(type); 371 372 obj = g_malloc(type->instance_size); 373 object_initialize_with_type(obj, type); 374 object_ref(obj); 375 376 return obj; 377 } 378 379 Object *object_new(const char *typename) 380 { 381 TypeImpl *ti = type_get_by_name(typename); 382 383 return object_new_with_type(ti); 384 } 385 386 void object_delete(Object *obj) 387 { 388 object_unref(obj); 389 g_assert(obj->ref == 0); 390 g_free(obj); 391 } 392 393 static bool type_is_ancestor(TypeImpl *type, TypeImpl *target_type) 394 { 395 assert(target_type); 396 397 /* Check if typename is a direct ancestor of type */ 398 while (type) { 399 if (type == target_type) { 400 return true; 401 } 402 403 type = type_get_parent(type); 404 } 405 406 return false; 407 } 408 409 static bool object_is_type(Object *obj, TypeImpl *target_type) 410 { 411 return !target_type || type_is_ancestor(obj->class->type, target_type); 412 } 413 414 Object *object_dynamic_cast(Object *obj, const char *typename) 415 { 416 TypeImpl *target_type = type_get_by_name(typename); 417 GSList *i; 418 419 /* Check if typename is a direct ancestor. Special-case TYPE_OBJECT, 420 * we want to go back from interfaces to the parent. 421 */ 422 if (target_type && object_is_type(obj, target_type)) { 423 return obj; 424 } 425 426 /* Check if obj is an interface and its containing object is a direct 427 * ancestor of typename. In principle we could do this test at the very 428 * beginning of object_dynamic_cast, avoiding a second call to 429 * object_is_type. However, casting between interfaces is relatively 430 * rare, and object_is_type(obj, type_interface) would fail almost always. 431 * 432 * Perhaps we could add a magic value to the object header for increased 433 * (run-time) type safety and to speed up tests like this one. If we ever 434 * do that we can revisit the order here. 435 */ 436 if (object_is_type(obj, type_interface)) { 437 assert(!obj->interfaces); 438 obj = INTERFACE(obj)->obj; 439 if (object_is_type(obj, target_type)) { 440 return obj; 441 } 442 } 443 444 if (!target_type) { 445 return obj; 446 } 447 448 /* Check if obj has an interface of typename */ 449 for (i = obj->interfaces; i; i = i->next) { 450 Interface *iface = i->data; 451 452 if (object_is_type(OBJECT(iface), target_type)) { 453 return OBJECT(iface); 454 } 455 } 456 457 return NULL; 458 } 459 460 461 static void register_types(void) 462 { 463 static TypeInfo interface_info = { 464 .name = TYPE_INTERFACE, 465 .instance_size = sizeof(Interface), 466 .abstract = true, 467 }; 468 469 type_interface = type_register_static(&interface_info); 470 } 471 472 type_init(register_types) 473 474 Object *object_dynamic_cast_assert(Object *obj, const char *typename) 475 { 476 Object *inst; 477 478 inst = object_dynamic_cast(obj, typename); 479 480 if (!inst) { 481 fprintf(stderr, "Object %p is not an instance of type %s\n", 482 obj, typename); 483 abort(); 484 } 485 486 return inst; 487 } 488 489 ObjectClass *object_class_dynamic_cast(ObjectClass *class, 490 const char *typename) 491 { 492 TypeImpl *target_type = type_get_by_name(typename); 493 TypeImpl *type = class->type; 494 495 while (type) { 496 if (type == target_type) { 497 return class; 498 } 499 500 type = type_get_parent(type); 501 } 502 503 return NULL; 504 } 505 506 ObjectClass *object_class_dynamic_cast_assert(ObjectClass *class, 507 const char *typename) 508 { 509 ObjectClass *ret = object_class_dynamic_cast(class, typename); 510 511 if (!ret) { 512 fprintf(stderr, "Object %p is not an instance of type %s\n", 513 class, typename); 514 abort(); 515 } 516 517 return ret; 518 } 519 520 const char *object_get_typename(Object *obj) 521 { 522 return obj->class->type->name; 523 } 524 525 ObjectClass *object_get_class(Object *obj) 526 { 527 return obj->class; 528 } 529 530 const char *object_class_get_name(ObjectClass *klass) 531 { 532 return klass->type->name; 533 } 534 535 ObjectClass *object_class_by_name(const char *typename) 536 { 537 TypeImpl *type = type_get_by_name(typename); 538 539 if (!type) { 540 return NULL; 541 } 542 543 type_initialize(type); 544 545 return type->class; 546 } 547 548 typedef struct OCFData 549 { 550 void (*fn)(ObjectClass *klass, void *opaque); 551 const char *implements_type; 552 bool include_abstract; 553 void *opaque; 554 } OCFData; 555 556 static void object_class_foreach_tramp(gpointer key, gpointer value, 557 gpointer opaque) 558 { 559 OCFData *data = opaque; 560 TypeImpl *type = value; 561 ObjectClass *k; 562 563 type_initialize(type); 564 k = type->class; 565 566 if (!data->include_abstract && type->abstract) { 567 return; 568 } 569 570 if (data->implements_type && 571 !object_class_dynamic_cast(k, data->implements_type)) { 572 return; 573 } 574 575 data->fn(k, data->opaque); 576 } 577 578 void object_class_foreach(void (*fn)(ObjectClass *klass, void *opaque), 579 const char *implements_type, bool include_abstract, 580 void *opaque) 581 { 582 OCFData data = { fn, implements_type, include_abstract, opaque }; 583 584 g_hash_table_foreach(type_table_get(), object_class_foreach_tramp, &data); 585 } 586 587 void object_ref(Object *obj) 588 { 589 obj->ref++; 590 } 591 592 void object_unref(Object *obj) 593 { 594 g_assert(obj->ref > 0); 595 obj->ref--; 596 597 /* parent always holds a reference to its children */ 598 if (obj->ref == 0) { 599 object_finalize(obj); 600 } 601 } 602 603 void object_property_add(Object *obj, const char *name, const char *type, 604 ObjectPropertyAccessor *get, 605 ObjectPropertyAccessor *set, 606 ObjectPropertyRelease *release, 607 void *opaque, Error **errp) 608 { 609 ObjectProperty *prop = g_malloc0(sizeof(*prop)); 610 611 prop->name = g_strdup(name); 612 prop->type = g_strdup(type); 613 614 prop->get = get; 615 prop->set = set; 616 prop->release = release; 617 prop->opaque = opaque; 618 619 QTAILQ_INSERT_TAIL(&obj->properties, prop, node); 620 } 621 622 static ObjectProperty *object_property_find(Object *obj, const char *name) 623 { 624 ObjectProperty *prop; 625 626 QTAILQ_FOREACH(prop, &obj->properties, node) { 627 if (strcmp(prop->name, name) == 0) { 628 return prop; 629 } 630 } 631 632 return NULL; 633 } 634 635 void object_property_del(Object *obj, const char *name, Error **errp) 636 { 637 ObjectProperty *prop = object_property_find(obj, name); 638 639 QTAILQ_REMOVE(&obj->properties, prop, node); 640 641 prop->release(obj, prop->name, prop->opaque); 642 643 g_free(prop->name); 644 g_free(prop->type); 645 g_free(prop); 646 } 647 648 void object_property_get(Object *obj, Visitor *v, const char *name, 649 Error **errp) 650 { 651 ObjectProperty *prop = object_property_find(obj, name); 652 653 if (prop == NULL) { 654 error_set(errp, QERR_PROPERTY_NOT_FOUND, "", name); 655 return; 656 } 657 658 if (!prop->get) { 659 error_set(errp, QERR_PERMISSION_DENIED); 660 } else { 661 prop->get(obj, v, prop->opaque, name, errp); 662 } 663 } 664 665 void object_property_set(Object *obj, Visitor *v, const char *name, 666 Error **errp) 667 { 668 ObjectProperty *prop = object_property_find(obj, name); 669 670 if (prop == NULL) { 671 error_set(errp, QERR_PROPERTY_NOT_FOUND, "", name); 672 return; 673 } 674 675 if (!prop->set) { 676 error_set(errp, QERR_PERMISSION_DENIED); 677 } else { 678 prop->set(obj, v, prop->opaque, name, errp); 679 } 680 } 681 682 void object_property_set_str(Object *obj, const char *value, 683 const char *name, Error **errp) 684 { 685 QString *qstr = qstring_from_str(value); 686 object_property_set_qobject(obj, QOBJECT(qstr), name, errp); 687 688 QDECREF(qstr); 689 } 690 691 char *object_property_get_str(Object *obj, const char *name, 692 Error **errp) 693 { 694 QObject *ret = object_property_get_qobject(obj, name, errp); 695 QString *qstring; 696 char *retval; 697 698 if (!ret) { 699 return NULL; 700 } 701 qstring = qobject_to_qstring(ret); 702 if (!qstring) { 703 error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, "string"); 704 retval = NULL; 705 } else { 706 retval = g_strdup(qstring_get_str(qstring)); 707 } 708 709 QDECREF(qstring); 710 return retval; 711 } 712 713 void object_property_set_link(Object *obj, Object *value, 714 const char *name, Error **errp) 715 { 716 object_property_set_str(obj, object_get_canonical_path(value), 717 name, errp); 718 } 719 720 Object *object_property_get_link(Object *obj, const char *name, 721 Error **errp) 722 { 723 char *str = object_property_get_str(obj, name, errp); 724 Object *target = NULL; 725 726 if (str && *str) { 727 target = object_resolve_path(str, NULL); 728 if (!target) { 729 error_set(errp, QERR_DEVICE_NOT_FOUND, str); 730 } 731 } 732 733 g_free(str); 734 return target; 735 } 736 737 void object_property_set_bool(Object *obj, bool value, 738 const char *name, Error **errp) 739 { 740 QBool *qbool = qbool_from_int(value); 741 object_property_set_qobject(obj, QOBJECT(qbool), name, errp); 742 743 QDECREF(qbool); 744 } 745 746 bool object_property_get_bool(Object *obj, const char *name, 747 Error **errp) 748 { 749 QObject *ret = object_property_get_qobject(obj, name, errp); 750 QBool *qbool; 751 bool retval; 752 753 if (!ret) { 754 return false; 755 } 756 qbool = qobject_to_qbool(ret); 757 if (!qbool) { 758 error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, "boolean"); 759 retval = false; 760 } else { 761 retval = qbool_get_int(qbool); 762 } 763 764 QDECREF(qbool); 765 return retval; 766 } 767 768 void object_property_set_int(Object *obj, int64_t value, 769 const char *name, Error **errp) 770 { 771 QInt *qint = qint_from_int(value); 772 object_property_set_qobject(obj, QOBJECT(qint), name, errp); 773 774 QDECREF(qint); 775 } 776 777 int64_t object_property_get_int(Object *obj, const char *name, 778 Error **errp) 779 { 780 QObject *ret = object_property_get_qobject(obj, name, errp); 781 QInt *qint; 782 int64_t retval; 783 784 if (!ret) { 785 return -1; 786 } 787 qint = qobject_to_qint(ret); 788 if (!qint) { 789 error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, "int"); 790 retval = -1; 791 } else { 792 retval = qint_get_int(qint); 793 } 794 795 QDECREF(qint); 796 return retval; 797 } 798 799 void object_property_parse(Object *obj, const char *string, 800 const char *name, Error **errp) 801 { 802 StringInputVisitor *mi; 803 mi = string_input_visitor_new(string); 804 object_property_set(obj, string_input_get_visitor(mi), name, errp); 805 806 string_input_visitor_cleanup(mi); 807 } 808 809 char *object_property_print(Object *obj, const char *name, 810 Error **errp) 811 { 812 StringOutputVisitor *mo; 813 char *string; 814 815 mo = string_output_visitor_new(); 816 object_property_get(obj, string_output_get_visitor(mo), name, NULL); 817 string = string_output_get_string(mo); 818 string_output_visitor_cleanup(mo); 819 return string; 820 } 821 822 const char *object_property_get_type(Object *obj, const char *name, Error **errp) 823 { 824 ObjectProperty *prop = object_property_find(obj, name); 825 826 if (prop == NULL) { 827 error_set(errp, QERR_PROPERTY_NOT_FOUND, "", name); 828 return NULL; 829 } 830 831 return prop->type; 832 } 833 834 Object *object_get_root(void) 835 { 836 static Object *root; 837 838 if (!root) { 839 root = object_new("container"); 840 } 841 842 return root; 843 } 844 845 static void object_get_child_property(Object *obj, Visitor *v, void *opaque, 846 const char *name, Error **errp) 847 { 848 Object *child = opaque; 849 gchar *path; 850 851 path = object_get_canonical_path(child); 852 visit_type_str(v, &path, name, errp); 853 g_free(path); 854 } 855 856 static void object_finalize_child_property(Object *obj, const char *name, 857 void *opaque) 858 { 859 Object *child = opaque; 860 861 object_unref(child); 862 } 863 864 void object_property_add_child(Object *obj, const char *name, 865 Object *child, Error **errp) 866 { 867 gchar *type; 868 869 /* Registering an interface object in the composition tree will mightily 870 * confuse object_get_canonical_path (which, on the other hand, knows how 871 * to get the canonical path of an interface object). 872 */ 873 assert(!object_is_type(obj, type_interface)); 874 875 type = g_strdup_printf("child<%s>", object_get_typename(OBJECT(child))); 876 877 object_property_add(obj, name, type, object_get_child_property, 878 NULL, object_finalize_child_property, child, errp); 879 880 object_ref(child); 881 g_assert(child->parent == NULL); 882 child->parent = obj; 883 884 g_free(type); 885 } 886 887 static void object_get_link_property(Object *obj, Visitor *v, void *opaque, 888 const char *name, Error **errp) 889 { 890 Object **child = opaque; 891 gchar *path; 892 893 if (*child) { 894 path = object_get_canonical_path(*child); 895 visit_type_str(v, &path, name, errp); 896 g_free(path); 897 } else { 898 path = (gchar *)""; 899 visit_type_str(v, &path, name, errp); 900 } 901 } 902 903 static void object_set_link_property(Object *obj, Visitor *v, void *opaque, 904 const char *name, Error **errp) 905 { 906 Object **child = opaque; 907 Object *old_target; 908 bool ambiguous = false; 909 const char *type; 910 char *path; 911 gchar *target_type; 912 913 type = object_property_get_type(obj, name, NULL); 914 915 visit_type_str(v, &path, name, errp); 916 917 old_target = *child; 918 *child = NULL; 919 920 if (strcmp(path, "") != 0) { 921 Object *target; 922 923 /* Go from link<FOO> to FOO. */ 924 target_type = g_strndup(&type[5], strlen(type) - 6); 925 target = object_resolve_path_type(path, target_type, &ambiguous); 926 927 if (ambiguous) { 928 error_set(errp, QERR_AMBIGUOUS_PATH, path); 929 } else if (target) { 930 object_ref(target); 931 *child = target; 932 } else { 933 target = object_resolve_path(path, &ambiguous); 934 if (target || ambiguous) { 935 error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, target_type); 936 } else { 937 error_set(errp, QERR_DEVICE_NOT_FOUND, path); 938 } 939 } 940 g_free(target_type); 941 } 942 943 g_free(path); 944 945 if (old_target != NULL) { 946 object_unref(old_target); 947 } 948 } 949 950 void object_property_add_link(Object *obj, const char *name, 951 const char *type, Object **child, 952 Error **errp) 953 { 954 gchar *full_type; 955 956 full_type = g_strdup_printf("link<%s>", type); 957 958 object_property_add(obj, name, full_type, 959 object_get_link_property, 960 object_set_link_property, 961 NULL, child, errp); 962 963 g_free(full_type); 964 } 965 966 gchar *object_get_canonical_path(Object *obj) 967 { 968 Object *root = object_get_root(); 969 char *newpath = NULL, *path = NULL; 970 971 if (object_is_type(obj, type_interface)) { 972 obj = INTERFACE(obj)->obj; 973 } 974 975 while (obj != root) { 976 ObjectProperty *prop = NULL; 977 978 g_assert(obj->parent != NULL); 979 980 QTAILQ_FOREACH(prop, &obj->parent->properties, node) { 981 if (!strstart(prop->type, "child<", NULL)) { 982 continue; 983 } 984 985 if (prop->opaque == obj) { 986 if (path) { 987 newpath = g_strdup_printf("%s/%s", prop->name, path); 988 g_free(path); 989 path = newpath; 990 } else { 991 path = g_strdup(prop->name); 992 } 993 break; 994 } 995 } 996 997 g_assert(prop != NULL); 998 999 obj = obj->parent; 1000 } 1001 1002 newpath = g_strdup_printf("/%s", path); 1003 g_free(path); 1004 1005 return newpath; 1006 } 1007 1008 static Object *object_resolve_abs_path(Object *parent, 1009 gchar **parts, 1010 const char *typename, 1011 int index) 1012 { 1013 ObjectProperty *prop; 1014 Object *child; 1015 1016 if (parts[index] == NULL) { 1017 return object_dynamic_cast(parent, typename); 1018 } 1019 1020 if (strcmp(parts[index], "") == 0) { 1021 return object_resolve_abs_path(parent, parts, typename, index + 1); 1022 } 1023 1024 prop = object_property_find(parent, parts[index]); 1025 if (prop == NULL) { 1026 return NULL; 1027 } 1028 1029 child = NULL; 1030 if (strstart(prop->type, "link<", NULL)) { 1031 Object **pchild = prop->opaque; 1032 if (*pchild) { 1033 child = *pchild; 1034 } 1035 } else if (strstart(prop->type, "child<", NULL)) { 1036 child = prop->opaque; 1037 } 1038 1039 if (!child) { 1040 return NULL; 1041 } 1042 1043 return object_resolve_abs_path(child, parts, typename, index + 1); 1044 } 1045 1046 static Object *object_resolve_partial_path(Object *parent, 1047 gchar **parts, 1048 const char *typename, 1049 bool *ambiguous) 1050 { 1051 Object *obj; 1052 ObjectProperty *prop; 1053 1054 obj = object_resolve_abs_path(parent, parts, typename, 0); 1055 1056 QTAILQ_FOREACH(prop, &parent->properties, node) { 1057 Object *found; 1058 1059 if (!strstart(prop->type, "child<", NULL)) { 1060 continue; 1061 } 1062 1063 found = object_resolve_partial_path(prop->opaque, parts, 1064 typename, ambiguous); 1065 if (found) { 1066 if (obj) { 1067 if (ambiguous) { 1068 *ambiguous = true; 1069 } 1070 return NULL; 1071 } 1072 obj = found; 1073 } 1074 1075 if (ambiguous && *ambiguous) { 1076 return NULL; 1077 } 1078 } 1079 1080 return obj; 1081 } 1082 1083 Object *object_resolve_path_type(const char *path, const char *typename, 1084 bool *ambiguous) 1085 { 1086 bool partial_path = true; 1087 Object *obj; 1088 gchar **parts; 1089 1090 parts = g_strsplit(path, "/", 0); 1091 if (parts == NULL || parts[0] == NULL) { 1092 g_strfreev(parts); 1093 return object_get_root(); 1094 } 1095 1096 if (strcmp(parts[0], "") == 0) { 1097 partial_path = false; 1098 } 1099 1100 if (partial_path) { 1101 if (ambiguous) { 1102 *ambiguous = false; 1103 } 1104 obj = object_resolve_partial_path(object_get_root(), parts, 1105 typename, ambiguous); 1106 } else { 1107 obj = object_resolve_abs_path(object_get_root(), parts, typename, 1); 1108 } 1109 1110 g_strfreev(parts); 1111 1112 return obj; 1113 } 1114 1115 Object *object_resolve_path(const char *path, bool *ambiguous) 1116 { 1117 return object_resolve_path_type(path, TYPE_OBJECT, ambiguous); 1118 } 1119 1120 typedef struct StringProperty 1121 { 1122 char *(*get)(Object *, Error **); 1123 void (*set)(Object *, const char *, Error **); 1124 } StringProperty; 1125 1126 static void property_get_str(Object *obj, Visitor *v, void *opaque, 1127 const char *name, Error **errp) 1128 { 1129 StringProperty *prop = opaque; 1130 char *value; 1131 1132 value = prop->get(obj, errp); 1133 if (value) { 1134 visit_type_str(v, &value, name, errp); 1135 g_free(value); 1136 } 1137 } 1138 1139 static void property_set_str(Object *obj, Visitor *v, void *opaque, 1140 const char *name, Error **errp) 1141 { 1142 StringProperty *prop = opaque; 1143 char *value; 1144 Error *local_err = NULL; 1145 1146 visit_type_str(v, &value, name, &local_err); 1147 if (local_err) { 1148 error_propagate(errp, local_err); 1149 return; 1150 } 1151 1152 prop->set(obj, value, errp); 1153 g_free(value); 1154 } 1155 1156 static void property_release_str(Object *obj, const char *name, 1157 void *opaque) 1158 { 1159 StringProperty *prop = opaque; 1160 g_free(prop); 1161 } 1162 1163 void object_property_add_str(Object *obj, const char *name, 1164 char *(*get)(Object *, Error **), 1165 void (*set)(Object *, const char *, Error **), 1166 Error **errp) 1167 { 1168 StringProperty *prop = g_malloc0(sizeof(*prop)); 1169 1170 prop->get = get; 1171 prop->set = set; 1172 1173 object_property_add(obj, name, "string", 1174 get ? property_get_str : NULL, 1175 set ? property_set_str : NULL, 1176 property_release_str, 1177 prop, errp); 1178 } 1179