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