qemu/qdev-monitor.c
<<
>>
Prefs
   1/*
   2 *  Dynamic device configuration and creation.
   3 *
   4 *  Copyright (c) 2009 CodeSourcery
   5 *
   6 * This library is free software; you can redistribute it and/or
   7 * modify it under the terms of the GNU Lesser General Public
   8 * License as published by the Free Software Foundation; either
   9 * version 2 of the License, or (at your option) any later version.
  10 *
  11 * This library is distributed in the hope that it will be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14 * Lesser General Public License for more details.
  15 *
  16 * You should have received a copy of the GNU Lesser General Public
  17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  18 */
  19
  20#include "qemu/osdep.h"
  21#include "hw/qdev.h"
  22#include "hw/sysbus.h"
  23#include "monitor/monitor.h"
  24#include "monitor/qdev.h"
  25#include "qmp-commands.h"
  26#include "sysemu/arch_init.h"
  27#include "qapi/qmp/qerror.h"
  28#include "qemu/config-file.h"
  29#include "qemu/error-report.h"
  30#include "qemu/help_option.h"
  31
  32#include "hw/remote-port.h"
  33#include "qemu/cutils.h"
  34
  35/*
  36 * Aliases were a bad idea from the start.  Let's keep them
  37 * from spreading further.
  38 */
  39typedef struct QDevAlias
  40{
  41    const char *typename;
  42    const char *alias;
  43    uint32_t arch_mask;
  44} QDevAlias;
  45
  46/* Please keep this table sorted by typename. */
  47static const QDevAlias qdev_alias_table[] = {
  48    { "e1000", "e1000-82540em" },
  49    { "ich9-ahci", "ahci" },
  50    { "kvm-pci-assign", "pci-assign" },
  51    { "lsi53c895a", "lsi" },
  52    { "virtio-9p-ccw", "virtio-9p", QEMU_ARCH_S390X },
  53    { "virtio-9p-pci", "virtio-9p", QEMU_ARCH_ALL & ~QEMU_ARCH_S390X },
  54    { "virtio-balloon-ccw", "virtio-balloon", QEMU_ARCH_S390X },
  55    { "virtio-balloon-pci", "virtio-balloon",
  56            QEMU_ARCH_ALL & ~QEMU_ARCH_S390X },
  57    { "virtio-blk-ccw", "virtio-blk", QEMU_ARCH_S390X },
  58    { "virtio-blk-pci", "virtio-blk", QEMU_ARCH_ALL & ~QEMU_ARCH_S390X },
  59    { "virtio-gpu-ccw", "virtio-gpu", QEMU_ARCH_S390X },
  60    { "virtio-gpu-pci", "virtio-gpu", QEMU_ARCH_ALL & ~QEMU_ARCH_S390X },
  61    { "virtio-input-host-ccw", "virtio-input-host", QEMU_ARCH_S390X },
  62    { "virtio-input-host-pci", "virtio-input-host",
  63            QEMU_ARCH_ALL & ~QEMU_ARCH_S390X },
  64    { "virtio-keyboard-ccw", "virtio-keyboard", QEMU_ARCH_S390X },
  65    { "virtio-keyboard-pci", "virtio-keyboard",
  66            QEMU_ARCH_ALL & ~QEMU_ARCH_S390X },
  67    { "virtio-mouse-ccw", "virtio-mouse", QEMU_ARCH_S390X },
  68    { "virtio-mouse-pci", "virtio-mouse", QEMU_ARCH_ALL & ~QEMU_ARCH_S390X },
  69    { "virtio-net-ccw", "virtio-net", QEMU_ARCH_S390X },
  70    { "virtio-net-pci", "virtio-net", QEMU_ARCH_ALL & ~QEMU_ARCH_S390X },
  71    { "virtio-rng-ccw", "virtio-rng", QEMU_ARCH_S390X },
  72    { "virtio-rng-pci", "virtio-rng", QEMU_ARCH_ALL & ~QEMU_ARCH_S390X },
  73    { "virtio-scsi-ccw", "virtio-scsi", QEMU_ARCH_S390X },
  74    { "virtio-scsi-pci", "virtio-scsi", QEMU_ARCH_ALL & ~QEMU_ARCH_S390X },
  75    { "virtio-serial-ccw", "virtio-serial", QEMU_ARCH_S390X },
  76    { "virtio-serial-pci", "virtio-serial", QEMU_ARCH_ALL & ~QEMU_ARCH_S390X },
  77    { "virtio-tablet-ccw", "virtio-tablet", QEMU_ARCH_S390X },
  78    { "virtio-tablet-pci", "virtio-tablet", QEMU_ARCH_ALL & ~QEMU_ARCH_S390X },
  79    { }
  80};
  81
  82static const char *qdev_class_get_alias(DeviceClass *dc)
  83{
  84    const char *typename = object_class_get_name(OBJECT_CLASS(dc));
  85    int i;
  86
  87    for (i = 0; qdev_alias_table[i].typename; i++) {
  88        if (qdev_alias_table[i].arch_mask &&
  89            !(qdev_alias_table[i].arch_mask & arch_type)) {
  90            continue;
  91        }
  92
  93        if (strcmp(qdev_alias_table[i].typename, typename) == 0) {
  94            return qdev_alias_table[i].alias;
  95        }
  96    }
  97
  98    return NULL;
  99}
 100
 101static bool qdev_class_has_alias(DeviceClass *dc)
 102{
 103    return (qdev_class_get_alias(dc) != NULL);
 104}
 105
 106static void qdev_print_devinfo(DeviceClass *dc)
 107{
 108    error_printf("name \"%s\"", object_class_get_name(OBJECT_CLASS(dc)));
 109    if (dc->bus_type) {
 110        error_printf(", bus %s", dc->bus_type);
 111    }
 112    if (qdev_class_has_alias(dc)) {
 113        error_printf(", alias \"%s\"", qdev_class_get_alias(dc));
 114    }
 115    if (dc->desc) {
 116        error_printf(", desc \"%s\"", dc->desc);
 117    }
 118    if (dc->cannot_instantiate_with_device_add_yet) {
 119        error_printf(", no-user");
 120    }
 121    error_printf("\n");
 122}
 123
 124static gint devinfo_cmp(gconstpointer a, gconstpointer b)
 125{
 126    return strcasecmp(object_class_get_name((ObjectClass *)a),
 127                      object_class_get_name((ObjectClass *)b));
 128}
 129
 130static void qdev_print_devinfos(bool show_no_user)
 131{
 132    static const char *cat_name[DEVICE_CATEGORY_MAX + 1] = {
 133        [DEVICE_CATEGORY_BRIDGE]  = "Controller/Bridge/Hub",
 134        [DEVICE_CATEGORY_USB]     = "USB",
 135        [DEVICE_CATEGORY_STORAGE] = "Storage",
 136        [DEVICE_CATEGORY_NETWORK] = "Network",
 137        [DEVICE_CATEGORY_INPUT]   = "Input",
 138        [DEVICE_CATEGORY_DISPLAY] = "Display",
 139        [DEVICE_CATEGORY_SOUND]   = "Sound",
 140        [DEVICE_CATEGORY_MISC]    = "Misc",
 141        [DEVICE_CATEGORY_MAX]     = "Uncategorized",
 142    };
 143    GSList *list, *elt;
 144    int i;
 145    bool cat_printed;
 146
 147    list = g_slist_sort(object_class_get_list(TYPE_DEVICE, false),
 148                        devinfo_cmp);
 149
 150    for (i = 0; i <= DEVICE_CATEGORY_MAX; i++) {
 151        cat_printed = false;
 152        for (elt = list; elt; elt = elt->next) {
 153            DeviceClass *dc = OBJECT_CLASS_CHECK(DeviceClass, elt->data,
 154                                                 TYPE_DEVICE);
 155            if ((i < DEVICE_CATEGORY_MAX
 156                 ? !test_bit(i, dc->categories)
 157                 : !bitmap_empty(dc->categories, DEVICE_CATEGORY_MAX))
 158                || (!show_no_user
 159                    && dc->cannot_instantiate_with_device_add_yet)) {
 160                continue;
 161            }
 162            if (!cat_printed) {
 163                error_printf("%s%s devices:\n", i ? "\n" : "",
 164                             cat_name[i]);
 165                cat_printed = true;
 166            }
 167            qdev_print_devinfo(dc);
 168        }
 169    }
 170
 171    g_slist_free(list);
 172}
 173
 174static int set_property(void *opaque, const char *name, const char *value,
 175                        Error **errp)
 176{
 177    Object *obj = opaque;
 178    Error *err = NULL;
 179
 180    if (strcmp(name, "driver") == 0)
 181        return 0;
 182    if (strcmp(name, "bus") == 0)
 183        return 0;
 184    if (strstr(name, "rp-adaptor") == name) {
 185        return 0;
 186    }
 187
 188    object_property_parse(obj, value, name, &err);
 189    if (err != NULL) {
 190        error_propagate(errp, err);
 191        return -1;
 192    }
 193    return 0;
 194}
 195
 196static const char *find_typename_by_alias(const char *alias)
 197{
 198    int i;
 199
 200    for (i = 0; qdev_alias_table[i].alias; i++) {
 201        if (qdev_alias_table[i].arch_mask &&
 202            !(qdev_alias_table[i].arch_mask & arch_type)) {
 203            continue;
 204        }
 205
 206        if (strcmp(qdev_alias_table[i].alias, alias) == 0) {
 207            return qdev_alias_table[i].typename;
 208        }
 209    }
 210
 211    return NULL;
 212}
 213
 214static DeviceClass *qdev_get_device_class(const char **driver, Error **errp)
 215{
 216    ObjectClass *oc;
 217    DeviceClass *dc;
 218    const char *original_name = *driver;
 219
 220    oc = object_class_by_name(*driver);
 221    if (!oc) {
 222        const char *typename = find_typename_by_alias(*driver);
 223
 224        if (typename) {
 225            *driver = typename;
 226            oc = object_class_by_name(*driver);
 227        }
 228    }
 229
 230    if (!object_class_dynamic_cast(oc, TYPE_DEVICE)) {
 231        if (*driver != original_name) {
 232            error_setg(errp, "'%s' (alias '%s') is not a valid device model"
 233                       " name", original_name, *driver);
 234        } else {
 235            error_setg(errp, "'%s' is not a valid device model name", *driver);
 236        }
 237        return NULL;
 238    }
 239
 240    if (object_class_is_abstract(oc)) {
 241        error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "driver",
 242                   "non-abstract device type");
 243        return NULL;
 244    }
 245
 246    dc = DEVICE_CLASS(oc);
 247    if (dc->cannot_instantiate_with_device_add_yet ||
 248        (qdev_hotplug && !dc->hotpluggable)) {
 249        error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "driver",
 250                   "pluggable device type");
 251        return NULL;
 252    }
 253
 254    return dc;
 255}
 256
 257
 258int qdev_device_help(QemuOpts *opts)
 259{
 260    Error *local_err = NULL;
 261    const char *driver;
 262    DevicePropertyInfoList *prop_list;
 263    DevicePropertyInfoList *prop;
 264
 265    driver = qemu_opt_get(opts, "driver");
 266    if (driver && is_help_option(driver)) {
 267        qdev_print_devinfos(false);
 268        return 1;
 269    }
 270
 271    if (!driver || !qemu_opt_has_help_opt(opts)) {
 272        return 0;
 273    }
 274
 275    if (!object_class_by_name(driver)) {
 276        const char *typename = find_typename_by_alias(driver);
 277
 278        if (typename) {
 279            driver = typename;
 280        }
 281    }
 282
 283    prop_list = qmp_device_list_properties(driver, &local_err);
 284    if (local_err) {
 285        goto error;
 286    }
 287
 288    for (prop = prop_list; prop; prop = prop->next) {
 289        error_printf("%s.%s=%s", driver,
 290                     prop->value->name,
 291                     prop->value->type);
 292        if (prop->value->has_description) {
 293            error_printf(" (%s)\n", prop->value->description);
 294        } else {
 295            error_printf("\n");
 296        }
 297    }
 298
 299    qapi_free_DevicePropertyInfoList(prop_list);
 300    return 1;
 301
 302error:
 303    error_report_err(local_err);
 304    return 1;
 305}
 306
 307static Object *qdev_get_peripheral(void)
 308{
 309    static Object *dev;
 310
 311    if (dev == NULL) {
 312        dev = container_get(qdev_get_machine(), "/peripheral");
 313    }
 314
 315    return dev;
 316}
 317
 318static Object *qdev_get_peripheral_anon(void)
 319{
 320    static Object *dev;
 321
 322    if (dev == NULL) {
 323        dev = container_get(qdev_get_machine(), "/peripheral-anon");
 324    }
 325
 326    return dev;
 327}
 328
 329static void qbus_list_bus(DeviceState *dev, Error **errp)
 330{
 331    BusState *child;
 332    const char *sep = " ";
 333
 334    error_append_hint(errp, "child buses at \"%s\":",
 335                      dev->id ? dev->id : object_get_typename(OBJECT(dev)));
 336    QLIST_FOREACH(child, &dev->child_bus, sibling) {
 337        error_append_hint(errp, "%s\"%s\"", sep, child->name);
 338        sep = ", ";
 339    }
 340    error_append_hint(errp, "\n");
 341}
 342
 343static void qbus_list_dev(BusState *bus, Error **errp)
 344{
 345    BusChild *kid;
 346    const char *sep = " ";
 347
 348    error_append_hint(errp, "devices at \"%s\":", bus->name);
 349    QTAILQ_FOREACH(kid, &bus->children, sibling) {
 350        DeviceState *dev = kid->child;
 351        error_append_hint(errp, "%s\"%s\"", sep,
 352                          object_get_typename(OBJECT(dev)));
 353        if (dev->id) {
 354            error_append_hint(errp, "/\"%s\"", dev->id);
 355        }
 356        sep = ", ";
 357    }
 358    error_append_hint(errp, "\n");
 359}
 360
 361static BusState *qbus_find_bus(DeviceState *dev, char *elem)
 362{
 363    BusState *child;
 364
 365    QLIST_FOREACH(child, &dev->child_bus, sibling) {
 366        if (strcmp(child->name, elem) == 0) {
 367            return child;
 368        }
 369    }
 370    return NULL;
 371}
 372
 373static DeviceState *qbus_find_dev(BusState *bus, char *elem)
 374{
 375    BusChild *kid;
 376
 377    /*
 378     * try to match in order:
 379     *   (1) instance id, if present
 380     *   (2) driver name
 381     *   (3) driver alias, if present
 382     */
 383    QTAILQ_FOREACH(kid, &bus->children, sibling) {
 384        DeviceState *dev = kid->child;
 385        if (dev->id  &&  strcmp(dev->id, elem) == 0) {
 386            return dev;
 387        }
 388    }
 389    QTAILQ_FOREACH(kid, &bus->children, sibling) {
 390        DeviceState *dev = kid->child;
 391        if (strcmp(object_get_typename(OBJECT(dev)), elem) == 0) {
 392            return dev;
 393        }
 394    }
 395    QTAILQ_FOREACH(kid, &bus->children, sibling) {
 396        DeviceState *dev = kid->child;
 397        DeviceClass *dc = DEVICE_GET_CLASS(dev);
 398
 399        if (qdev_class_has_alias(dc) &&
 400            strcmp(qdev_class_get_alias(dc), elem) == 0) {
 401            return dev;
 402        }
 403    }
 404    return NULL;
 405}
 406
 407static inline bool qbus_is_full(BusState *bus)
 408{
 409    BusClass *bus_class = BUS_GET_CLASS(bus);
 410    return bus_class->max_dev && bus->max_index >= bus_class->max_dev;
 411}
 412
 413/*
 414 * Search the tree rooted at @bus for a bus.
 415 * If @name, search for a bus with that name.  Note that bus names
 416 * need not be unique.  Yes, that's screwed up.
 417 * Else search for a bus that is a subtype of @bus_typename.
 418 * If more than one exists, prefer one that can take another device.
 419 * Return the bus if found, else %NULL.
 420 */
 421static BusState *qbus_find_recursive(BusState *bus, const char *name,
 422                                     const char *bus_typename)
 423{
 424    BusChild *kid;
 425    BusState *pick, *child, *ret;
 426    bool match;
 427
 428    assert(name || bus_typename);
 429    if (name) {
 430        match = !strcmp(bus->name, name);
 431    } else {
 432        match = !!object_dynamic_cast(OBJECT(bus), bus_typename);
 433    }
 434
 435    if (match && !qbus_is_full(bus)) {
 436        return bus;             /* root matches and isn't full */
 437    }
 438
 439    pick = match ? bus : NULL;
 440
 441    QTAILQ_FOREACH(kid, &bus->children, sibling) {
 442        DeviceState *dev = kid->child;
 443        QLIST_FOREACH(child, &dev->child_bus, sibling) {
 444            ret = qbus_find_recursive(child, name, bus_typename);
 445            if (ret && !qbus_is_full(ret)) {
 446                return ret;     /* a descendant matches and isn't full */
 447            }
 448            if (ret && !pick) {
 449                pick = ret;
 450            }
 451        }
 452    }
 453
 454    /* root or a descendant matches, but is full */
 455    return pick;
 456}
 457
 458static BusState *qbus_find(const char *path, Error **errp)
 459{
 460    DeviceState *dev;
 461    BusState *bus;
 462    char elem[128];
 463    int pos, len;
 464
 465    /* find start element */
 466    if (path[0] == '/') {
 467        bus = sysbus_get_default();
 468        pos = 0;
 469    } else {
 470        if (sscanf(path, "%127[^/]%n", elem, &len) != 1) {
 471            assert(!path[0]);
 472            elem[0] = len = 0;
 473        }
 474        bus = qbus_find_recursive(sysbus_get_default(), elem, NULL);
 475        if (!bus) {
 476            error_setg(errp, "Bus '%s' not found", elem);
 477            return NULL;
 478        }
 479        pos = len;
 480    }
 481
 482    for (;;) {
 483        assert(path[pos] == '/' || !path[pos]);
 484        while (path[pos] == '/') {
 485            pos++;
 486        }
 487        if (path[pos] == '\0') {
 488            break;
 489        }
 490
 491        /* find device */
 492        if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
 493            g_assert_not_reached();
 494            elem[0] = len = 0;
 495        }
 496        pos += len;
 497        dev = qbus_find_dev(bus, elem);
 498        if (!dev) {
 499            error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
 500                      "Device '%s' not found", elem);
 501            qbus_list_dev(bus, errp);
 502            return NULL;
 503        }
 504
 505        assert(path[pos] == '/' || !path[pos]);
 506        while (path[pos] == '/') {
 507            pos++;
 508        }
 509        if (path[pos] == '\0') {
 510            /* last specified element is a device.  If it has exactly
 511             * one child bus accept it nevertheless */
 512            if (dev->num_child_bus == 1) {
 513                bus = QLIST_FIRST(&dev->child_bus);
 514                break;
 515            }
 516            if (dev->num_child_bus) {
 517                error_setg(errp, "Device '%s' has multiple child buses",
 518                           elem);
 519                qbus_list_bus(dev, errp);
 520            } else {
 521                error_setg(errp, "Device '%s' has no child bus", elem);
 522            }
 523            return NULL;
 524        }
 525
 526        /* find bus */
 527        if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
 528            g_assert_not_reached();
 529            elem[0] = len = 0;
 530        }
 531        pos += len;
 532        bus = qbus_find_bus(dev, elem);
 533        if (!bus) {
 534            error_setg(errp, "Bus '%s' not found", elem);
 535            qbus_list_bus(dev, errp);
 536            return NULL;
 537        }
 538    }
 539
 540    if (qbus_is_full(bus)) {
 541        error_setg(errp, "Bus '%s' is full", path);
 542        return NULL;
 543    }
 544    return bus;
 545}
 546
 547DeviceState *qdev_device_add(QemuOpts *opts, Error **errp)
 548{
 549    DeviceClass *dc;
 550    const char *driver, *path, *id;
 551    DeviceState *dev;
 552    BusState *bus = NULL;
 553    Error *err = NULL;
 554
 555    driver = qemu_opt_get(opts, "driver");
 556    if (!driver) {
 557        error_setg(errp, QERR_MISSING_PARAMETER, "driver");
 558        return NULL;
 559    }
 560
 561    /* find driver */
 562    dc = qdev_get_device_class(&driver, errp);
 563    if (!dc) {
 564        return NULL;
 565    }
 566
 567    /* find bus */
 568    path = qemu_opt_get(opts, "bus");
 569    if (path != NULL) {
 570        bus = qbus_find(path, errp);
 571        if (!bus) {
 572            return NULL;
 573        }
 574        if (!object_dynamic_cast(OBJECT(bus), dc->bus_type)) {
 575            error_setg(errp, "Device '%s' can't go on %s bus",
 576                       driver, object_get_typename(OBJECT(bus)));
 577            return NULL;
 578        }
 579    } else if (dc->bus_type != NULL) {
 580        bus = qbus_find_recursive(sysbus_get_default(), NULL, dc->bus_type);
 581        if (!bus || qbus_is_full(bus)) {
 582            error_setg(errp, "No '%s' bus found for device '%s'",
 583                       dc->bus_type, driver);
 584            return NULL;
 585        }
 586    }
 587    if (qdev_hotplug && bus && !qbus_is_hotpluggable(bus)) {
 588        error_setg(errp, QERR_BUS_NO_HOTPLUG, bus->name);
 589        return NULL;
 590    }
 591
 592    /* create device */
 593    dev = DEVICE(object_new(driver));
 594
 595    if (bus) {
 596        qdev_set_parent_bus(dev, bus);
 597    } else {
 598        if (dc->reset) {
 599            qemu_register_reset((void (*)(void *))dc->reset, dev);
 600        }
 601    }
 602
 603    id = qemu_opts_id(opts);
 604    if (id) {
 605        dev->id = (char *) id;
 606    }
 607
 608    if (dev->id) {
 609        object_property_add_child(qdev_get_peripheral(), dev->id,
 610                                  OBJECT(dev), NULL);
 611    } else {
 612        static int anon_count;
 613        gchar *name = g_strdup_printf("device[%d]", anon_count++);
 614        object_property_add_child(qdev_get_peripheral_anon(), name,
 615                                  OBJECT(dev), NULL);
 616        g_free(name);
 617    }
 618
 619    rp_device_add(opts, dev, &err);
 620    if (err != NULL) {
 621        error_propagate(errp, err);
 622        object_unparent(OBJECT(dev));
 623        object_unref(OBJECT(dev));
 624        return NULL;
 625    }
 626
 627    /* set properties */
 628    if (qemu_opt_foreach(opts, set_property, dev, &err)) {
 629        error_propagate(errp, err);
 630        object_unparent(OBJECT(dev));
 631        object_unref(OBJECT(dev));
 632        return NULL;
 633    }
 634
 635    dev->opts = opts;
 636    object_property_set_bool(OBJECT(dev), true, "realized", &err);
 637    if (err != NULL) {
 638        error_propagate(errp, err);
 639        dev->opts = NULL;
 640        object_unparent(OBJECT(dev));
 641        object_unref(OBJECT(dev));
 642        return NULL;
 643    }
 644    return dev;
 645}
 646
 647
 648#define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## __VA_ARGS__)
 649static void qbus_print(Monitor *mon, BusState *bus, int indent);
 650
 651static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
 652                             int indent)
 653{
 654    if (!props)
 655        return;
 656    for (; props->name; props++) {
 657        Error *err = NULL;
 658        char *value;
 659        char *legacy_name = g_strdup_printf("legacy-%s", props->name);
 660        if (object_property_get_type(OBJECT(dev), legacy_name, NULL)) {
 661            value = object_property_get_str(OBJECT(dev), legacy_name, &err);
 662        } else {
 663            value = object_property_print(OBJECT(dev), props->name, true, &err);
 664        }
 665        g_free(legacy_name);
 666
 667        if (err) {
 668            error_free(err);
 669            continue;
 670        }
 671        qdev_printf("%s = %s\n", props->name,
 672                    value && *value ? value : "<null>");
 673        g_free(value);
 674    }
 675}
 676
 677static void bus_print_dev(BusState *bus, Monitor *mon, DeviceState *dev, int indent)
 678{
 679    BusClass *bc = BUS_GET_CLASS(bus);
 680
 681    if (bc->print_dev) {
 682        bc->print_dev(mon, dev, indent);
 683    }
 684}
 685
 686static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
 687{
 688    ObjectClass *class;
 689    BusState *child;
 690    NamedGPIOList *ngl;
 691
 692    qdev_printf("dev: %s, id \"%s\"\n", object_get_typename(OBJECT(dev)),
 693                dev->id ? dev->id : "");
 694    indent += 2;
 695    QLIST_FOREACH(ngl, &dev->gpios, node) {
 696        if (ngl->num_in) {
 697            qdev_printf("gpio-in \"%s\" %d\n", ngl->name ? ngl->name : "",
 698                        ngl->num_in);
 699        }
 700        if (ngl->num_out) {
 701            qdev_printf("gpio-out \"%s\" %d\n", ngl->name ? ngl->name : "",
 702                        ngl->num_out);
 703        }
 704    }
 705    class = object_get_class(OBJECT(dev));
 706    do {
 707        qdev_print_props(mon, dev, DEVICE_CLASS(class)->props, indent);
 708        class = object_class_get_parent(class);
 709    } while (class != object_class_by_name(TYPE_DEVICE));
 710    bus_print_dev(dev->parent_bus, mon, dev, indent);
 711    QLIST_FOREACH(child, &dev->child_bus, sibling) {
 712        qbus_print(mon, child, indent);
 713    }
 714}
 715
 716static void qbus_print(Monitor *mon, BusState *bus, int indent)
 717{
 718    BusChild *kid;
 719
 720    qdev_printf("bus: %s\n", bus->name);
 721    indent += 2;
 722    qdev_printf("type %s\n", object_get_typename(OBJECT(bus)));
 723    QTAILQ_FOREACH(kid, &bus->children, sibling) {
 724        DeviceState *dev = kid->child;
 725        qdev_print(mon, dev, indent);
 726    }
 727}
 728#undef qdev_printf
 729
 730void hmp_info_qtree(Monitor *mon, const QDict *qdict)
 731{
 732    if (sysbus_get_default())
 733        qbus_print(mon, sysbus_get_default(), 0);
 734}
 735
 736void hmp_info_qdm(Monitor *mon, const QDict *qdict)
 737{
 738    qdev_print_devinfos(true);
 739}
 740
 741typedef struct QOMCompositionState {
 742    Monitor *mon;
 743    int indent;
 744} QOMCompositionState;
 745
 746static void print_qom_composition(Monitor *mon, Object *obj, int indent);
 747
 748static int print_qom_composition_child(Object *obj, void *opaque)
 749{
 750    QOMCompositionState *s = opaque;
 751
 752    print_qom_composition(s->mon, obj, s->indent);
 753
 754    return 0;
 755}
 756
 757static void print_qom_composition(Monitor *mon, Object *obj, int indent)
 758{
 759    QOMCompositionState s = {
 760        .mon = mon,
 761        .indent = indent + 2,
 762    };
 763    char *name;
 764
 765    if (obj == object_get_root()) {
 766        name = g_strdup("");
 767    } else {
 768        name = object_get_canonical_path_component(obj);
 769    }
 770    monitor_printf(mon, "%*s/%s (%s)\n", indent, "", name,
 771                   object_get_typename(obj));
 772    g_free(name);
 773    object_child_foreach(obj, print_qom_composition_child, &s);
 774}
 775
 776void hmp_info_qom_tree(Monitor *mon, const QDict *dict)
 777{
 778    const char *path = qdict_get_try_str(dict, "path");
 779    Object *obj;
 780    bool ambiguous = false;
 781
 782    if (path) {
 783        obj = object_resolve_path(path, &ambiguous);
 784        if (!obj) {
 785            monitor_printf(mon, "Path '%s' could not be resolved.\n", path);
 786            return;
 787        }
 788        if (ambiguous) {
 789            monitor_printf(mon, "Warning: Path '%s' is ambiguous.\n", path);
 790            return;
 791        }
 792    } else {
 793        obj = qdev_get_machine();
 794    }
 795    print_qom_composition(mon, obj, 0);
 796}
 797
 798void qmp_device_add(QDict *qdict, QObject **ret_data, Error **errp)
 799{
 800    Error *local_err = NULL;
 801    QemuOpts *opts;
 802    DeviceState *dev;
 803
 804    opts = qemu_opts_from_qdict(qemu_find_opts("device"), qdict, &local_err);
 805    if (local_err) {
 806        error_propagate(errp, local_err);
 807        return;
 808    }
 809    if (!monitor_cur_is_qmp() && qdev_device_help(opts)) {
 810        qemu_opts_del(opts);
 811        return;
 812    }
 813    dev = qdev_device_add(opts, &local_err);
 814    if (!dev) {
 815        error_propagate(errp, local_err);
 816        qemu_opts_del(opts);
 817        return;
 818    }
 819    object_unref(OBJECT(dev));
 820}
 821
 822void qmp_device_del(const char *id, Error **errp)
 823{
 824    Object *obj;
 825
 826    if (id[0] == '/') {
 827        obj = object_resolve_path(id, NULL);
 828    } else {
 829        char *root_path = object_get_canonical_path(qdev_get_peripheral());
 830        char *path = g_strdup_printf("%s/%s", root_path, id);
 831
 832        g_free(root_path);
 833        obj = object_resolve_path_type(path, TYPE_DEVICE, NULL);
 834        g_free(path);
 835    }
 836
 837    if (!obj) {
 838        error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
 839                  "Device '%s' not found", id);
 840        return;
 841    }
 842
 843    if (!object_dynamic_cast(obj, TYPE_DEVICE)) {
 844        error_setg(errp, "%s is not a hotpluggable device", id);
 845        return;
 846    }
 847
 848    qdev_unplug(DEVICE(obj), errp);
 849}
 850
 851void qdev_machine_init(void)
 852{
 853    qdev_get_peripheral_anon();
 854    qdev_get_peripheral();
 855}
 856
 857QemuOptsList qemu_device_opts = {
 858    .name = "device",
 859    .implied_opt_name = "driver",
 860    .head = QTAILQ_HEAD_INITIALIZER(qemu_device_opts.head),
 861    .desc = {
 862        /*
 863         * no elements => accept any
 864         * sanity checking will happen later
 865         * when setting device properties
 866         */
 867        { /* end of list */ }
 868    },
 869};
 870
 871QemuOptsList qemu_global_opts = {
 872    .name = "global",
 873    .head = QTAILQ_HEAD_INITIALIZER(qemu_global_opts.head),
 874    .desc = {
 875        {
 876            .name = "driver",
 877            .type = QEMU_OPT_STRING,
 878        },{
 879            .name = "property",
 880            .type = QEMU_OPT_STRING,
 881        },{
 882            .name = "value",
 883            .type = QEMU_OPT_STRING,
 884        },
 885        { /* end of list */ }
 886    },
 887};
 888
 889int qemu_global_option(const char *str)
 890{
 891    char driver[64], property[64];
 892    QemuOpts *opts;
 893    int rc, offset;
 894
 895    rc = sscanf(str, "%63[^.=].%63[^=]%n", driver, property, &offset);
 896    if (rc == 2 && str[offset] == '=') {
 897        opts = qemu_opts_create(&qemu_global_opts, NULL, 0, &error_abort);
 898        qemu_opt_set(opts, "driver", driver, &error_abort);
 899        qemu_opt_set(opts, "property", property, &error_abort);
 900        qemu_opt_set(opts, "value", str + offset + 1, &error_abort);
 901        return 0;
 902    }
 903
 904    opts = qemu_opts_parse_noisily(&qemu_global_opts, str, false);
 905    if (!opts) {
 906        return -1;
 907    }
 908
 909    return 0;
 910}
 911