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 "hw/qdev.h"
  21#include "hw/sysbus.h"
  22#include "monitor/monitor.h"
  23#include "monitor/qdev.h"
  24#include "qmp-commands.h"
  25#include "sysemu/arch_init.h"
  26#include "qemu/config-file.h"
  27
  28/*
  29 * Aliases were a bad idea from the start.  Let's keep them
  30 * from spreading further.
  31 */
  32typedef struct QDevAlias
  33{
  34    const char *typename;
  35    const char *alias;
  36    uint32_t arch_mask;
  37} QDevAlias;
  38
  39static const QDevAlias qdev_alias_table[] = {
  40    { "virtio-blk-pci", "virtio-blk", QEMU_ARCH_ALL & ~QEMU_ARCH_S390X },
  41    { "virtio-net-pci", "virtio-net", QEMU_ARCH_ALL & ~QEMU_ARCH_S390X },
  42    { "virtio-serial-pci", "virtio-serial", QEMU_ARCH_ALL & ~QEMU_ARCH_S390X },
  43    { "virtio-balloon-pci", "virtio-balloon",
  44            QEMU_ARCH_ALL & ~QEMU_ARCH_S390X },
  45    { "virtio-blk-s390", "virtio-blk", QEMU_ARCH_S390X },
  46    { "virtio-net-s390", "virtio-net", QEMU_ARCH_S390X },
  47    { "virtio-serial-s390", "virtio-serial", QEMU_ARCH_S390X },
  48    { "lsi53c895a", "lsi" },
  49    { "ich9-ahci", "ahci" },
  50    { "kvm-pci-assign", "pci-assign" },
  51    { }
  52};
  53
  54static const char *qdev_class_get_alias(DeviceClass *dc)
  55{
  56    const char *typename = object_class_get_name(OBJECT_CLASS(dc));
  57    int i;
  58
  59    for (i = 0; qdev_alias_table[i].typename; i++) {
  60        if (qdev_alias_table[i].arch_mask &&
  61            !(qdev_alias_table[i].arch_mask & arch_type)) {
  62            continue;
  63        }
  64
  65        if (strcmp(qdev_alias_table[i].typename, typename) == 0) {
  66            return qdev_alias_table[i].alias;
  67        }
  68    }
  69
  70    return NULL;
  71}
  72
  73static bool qdev_class_has_alias(DeviceClass *dc)
  74{
  75    return (qdev_class_get_alias(dc) != NULL);
  76}
  77
  78static void qdev_print_class_devinfo(DeviceClass *dc)
  79{
  80    DeviceCategory category;
  81
  82    if (!dc) {
  83        return;
  84    }
  85
  86    error_printf("name \"%s\"", object_class_get_name(OBJECT_CLASS(dc)));
  87    if (dc->bus_type) {
  88        error_printf(", bus %s", dc->bus_type);
  89    }
  90    if (qdev_class_has_alias(dc)) {
  91        error_printf(", alias \"%s\"", qdev_class_get_alias(dc));
  92    }
  93    error_printf(", categories");
  94    for (category = 0; category < DEVICE_CATEGORY_MAX; ++category) {
  95        if (test_bit(category, dc->categories)) {
  96            error_printf(" \"%s\"", qdev_category_get_name(category));
  97        }
  98    }
  99    if (dc->desc) {
 100        error_printf(", desc \"%s\"", dc->desc);
 101    }
 102    if (dc->no_user) {
 103        error_printf(", no-user");
 104    }
 105    error_printf("\n");
 106}
 107
 108static void qdev_print_devinfo(ObjectClass *klass, void *opaque)
 109{
 110    DeviceClass *dc;
 111
 112    dc = (DeviceClass *)object_class_dynamic_cast(klass, TYPE_DEVICE);
 113
 114    qdev_print_class_devinfo(dc);
 115}
 116
 117static int set_property(const char *name, const char *value, void *opaque)
 118{
 119    DeviceState *dev = opaque;
 120    Error *err = NULL;
 121
 122    if (strcmp(name, "driver") == 0)
 123        return 0;
 124    if (strcmp(name, "bus") == 0)
 125        return 0;
 126
 127    qdev_prop_parse(dev, name, value, &err);
 128    if (err != NULL) {
 129        qerror_report_err(err);
 130        error_free(err);
 131        return -1;
 132    }
 133    return 0;
 134}
 135
 136static const char *find_typename_by_alias(const char *alias)
 137{
 138    int i;
 139
 140    for (i = 0; qdev_alias_table[i].alias; i++) {
 141        if (qdev_alias_table[i].arch_mask &&
 142            !(qdev_alias_table[i].arch_mask & arch_type)) {
 143            continue;
 144        }
 145
 146        if (strcmp(qdev_alias_table[i].alias, alias) == 0) {
 147            return qdev_alias_table[i].typename;
 148        }
 149    }
 150
 151    return NULL;
 152}
 153
 154static void qdev_print_category_devices(DeviceCategory category)
 155{
 156    DeviceClass *dc;
 157    GSList *list, *curr;
 158
 159    list = object_class_get_list(TYPE_DEVICE, false);
 160    for (curr = list; curr; curr = g_slist_next(curr)) {
 161        dc = (DeviceClass *)object_class_dynamic_cast(curr->data, TYPE_DEVICE);
 162        if (!dc->no_user && test_bit(category, dc->categories)) {
 163            qdev_print_class_devinfo(dc);
 164        }
 165    }
 166    g_slist_free(list);
 167}
 168
 169int qdev_device_help(QemuOpts *opts)
 170{
 171    const char *driver;
 172    Property *prop;
 173    ObjectClass *klass;
 174
 175    driver = qemu_opt_get(opts, "driver");
 176    if (driver && is_help_option(driver)) {
 177        DeviceCategory category;
 178        for (category = 0; category < DEVICE_CATEGORY_MAX; ++category) {
 179            qdev_print_category_devices(category);
 180        }
 181
 182        return 1;
 183    }
 184
 185    if (!driver || !qemu_opt_has_help_opt(opts)) {
 186        return 0;
 187    }
 188
 189    klass = object_class_by_name(driver);
 190    if (!klass) {
 191        const char *typename = find_typename_by_alias(driver);
 192
 193        if (typename) {
 194            driver = typename;
 195            klass = object_class_by_name(driver);
 196        }
 197    }
 198
 199    if (!klass) {
 200        return 0;
 201    }
 202    do {
 203        for (prop = DEVICE_CLASS(klass)->props; prop && prop->name; prop++) {
 204            /*
 205             * TODO Properties without a parser are just for dirty hacks.
 206             * qdev_prop_ptr is the only such PropertyInfo.  It's marked
 207             * for removal.  This conditional should be removed along with
 208             * it.
 209             */
 210            if (!prop->info->set) {
 211                continue;           /* no way to set it, don't show */
 212            }
 213            error_printf("%s.%s=%s\n", driver, prop->name,
 214                         prop->info->legacy_name ?: prop->info->name);
 215        }
 216        klass = object_class_get_parent(klass);
 217    } while (klass != object_class_by_name(TYPE_DEVICE));
 218    return 1;
 219}
 220
 221static Object *qdev_get_peripheral(void)
 222{
 223    static Object *dev;
 224
 225    if (dev == NULL) {
 226        dev = container_get(qdev_get_machine(), "/peripheral");
 227    }
 228
 229    return dev;
 230}
 231
 232static Object *qdev_get_peripheral_anon(void)
 233{
 234    static Object *dev;
 235
 236    if (dev == NULL) {
 237        dev = container_get(qdev_get_machine(), "/peripheral-anon");
 238    }
 239
 240    return dev;
 241}
 242
 243static void qbus_list_bus(DeviceState *dev)
 244{
 245    BusState *child;
 246    const char *sep = " ";
 247
 248    error_printf("child busses at \"%s\":",
 249                 dev->id ? dev->id : object_get_typename(OBJECT(dev)));
 250    QLIST_FOREACH(child, &dev->child_bus, sibling) {
 251        error_printf("%s\"%s\"", sep, child->name);
 252        sep = ", ";
 253    }
 254    error_printf("\n");
 255}
 256
 257static void qbus_list_dev(BusState *bus)
 258{
 259    BusChild *kid;
 260    const char *sep = " ";
 261
 262    error_printf("devices at \"%s\":", bus->name);
 263    QTAILQ_FOREACH(kid, &bus->children, sibling) {
 264        DeviceState *dev = kid->child;
 265        error_printf("%s\"%s\"", sep, object_get_typename(OBJECT(dev)));
 266        if (dev->id)
 267            error_printf("/\"%s\"", dev->id);
 268        sep = ", ";
 269    }
 270    error_printf("\n");
 271}
 272
 273static BusState *qbus_find_bus(DeviceState *dev, char *elem)
 274{
 275    BusState *child;
 276
 277    QLIST_FOREACH(child, &dev->child_bus, sibling) {
 278        if (strcmp(child->name, elem) == 0) {
 279            return child;
 280        }
 281    }
 282    return NULL;
 283}
 284
 285static DeviceState *qbus_find_dev(BusState *bus, char *elem)
 286{
 287    BusChild *kid;
 288
 289    /*
 290     * try to match in order:
 291     *   (1) instance id, if present
 292     *   (2) driver name
 293     *   (3) driver alias, if present
 294     */
 295    QTAILQ_FOREACH(kid, &bus->children, sibling) {
 296        DeviceState *dev = kid->child;
 297        if (dev->id  &&  strcmp(dev->id, elem) == 0) {
 298            return dev;
 299        }
 300    }
 301    QTAILQ_FOREACH(kid, &bus->children, sibling) {
 302        DeviceState *dev = kid->child;
 303        if (strcmp(object_get_typename(OBJECT(dev)), elem) == 0) {
 304            return dev;
 305        }
 306    }
 307    QTAILQ_FOREACH(kid, &bus->children, sibling) {
 308        DeviceState *dev = kid->child;
 309        DeviceClass *dc = DEVICE_GET_CLASS(dev);
 310
 311        if (qdev_class_has_alias(dc) &&
 312            strcmp(qdev_class_get_alias(dc), elem) == 0) {
 313            return dev;
 314        }
 315    }
 316    return NULL;
 317}
 318
 319static BusState *qbus_find_recursive(BusState *bus, const char *name,
 320                                     const char *bus_typename)
 321{
 322    BusClass *bus_class = BUS_GET_CLASS(bus);
 323    BusChild *kid;
 324    BusState *child, *ret;
 325    int match = 1;
 326
 327    if (name && (strcmp(bus->name, name) != 0)) {
 328        match = 0;
 329    } else if (bus_typename && !object_dynamic_cast(OBJECT(bus), bus_typename)) {
 330        match = 0;
 331    } else if ((bus_class->max_dev != 0) && (bus_class->max_dev <= bus->max_index)) {
 332        if (name != NULL) {
 333            /* bus was explicitly specified: return an error. */
 334            qerror_report(ERROR_CLASS_GENERIC_ERROR, "Bus '%s' is full",
 335                          bus->name);
 336            return NULL;
 337        } else {
 338            /* bus was not specified: try to find another one. */
 339            match = 0;
 340        }
 341    }
 342    if (match) {
 343        return bus;
 344    }
 345
 346    QTAILQ_FOREACH(kid, &bus->children, sibling) {
 347        DeviceState *dev = kid->child;
 348        QLIST_FOREACH(child, &dev->child_bus, sibling) {
 349            ret = qbus_find_recursive(child, name, bus_typename);
 350            if (ret) {
 351                return ret;
 352            }
 353        }
 354    }
 355    return NULL;
 356}
 357
 358static BusState *qbus_find(const char *path)
 359{
 360    DeviceState *dev;
 361    BusState *bus;
 362    char elem[128];
 363    int pos, len;
 364
 365    /* find start element */
 366    if (path[0] == '/') {
 367        bus = sysbus_get_default();
 368        pos = 0;
 369    } else {
 370        if (sscanf(path, "%127[^/]%n", elem, &len) != 1) {
 371            assert(!path[0]);
 372            elem[0] = len = 0;
 373        }
 374        bus = qbus_find_recursive(sysbus_get_default(), elem, NULL);
 375        if (!bus) {
 376            qerror_report(QERR_BUS_NOT_FOUND, elem);
 377            return NULL;
 378        }
 379        pos = len;
 380    }
 381
 382    for (;;) {
 383        assert(path[pos] == '/' || !path[pos]);
 384        while (path[pos] == '/') {
 385            pos++;
 386        }
 387        if (path[pos] == '\0') {
 388            return bus;
 389        }
 390
 391        /* find device */
 392        if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
 393            g_assert_not_reached();
 394            elem[0] = len = 0;
 395        }
 396        pos += len;
 397        dev = qbus_find_dev(bus, elem);
 398        if (!dev) {
 399            qerror_report(QERR_DEVICE_NOT_FOUND, elem);
 400            if (!monitor_cur_is_qmp()) {
 401                qbus_list_dev(bus);
 402            }
 403            return NULL;
 404        }
 405
 406        assert(path[pos] == '/' || !path[pos]);
 407        while (path[pos] == '/') {
 408            pos++;
 409        }
 410        if (path[pos] == '\0') {
 411            /* last specified element is a device.  If it has exactly
 412             * one child bus accept it nevertheless */
 413            switch (dev->num_child_bus) {
 414            case 0:
 415                qerror_report(QERR_DEVICE_NO_BUS, elem);
 416                return NULL;
 417            case 1:
 418                return QLIST_FIRST(&dev->child_bus);
 419            default:
 420                qerror_report(QERR_DEVICE_MULTIPLE_BUSSES, elem);
 421                if (!monitor_cur_is_qmp()) {
 422                    qbus_list_bus(dev);
 423                }
 424                return NULL;
 425            }
 426        }
 427
 428        /* find bus */
 429        if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
 430            g_assert_not_reached();
 431            elem[0] = len = 0;
 432        }
 433        pos += len;
 434        bus = qbus_find_bus(dev, elem);
 435        if (!bus) {
 436            qerror_report(QERR_BUS_NOT_FOUND, elem);
 437            if (!monitor_cur_is_qmp()) {
 438                qbus_list_bus(dev);
 439            }
 440            return NULL;
 441        }
 442    }
 443}
 444
 445DeviceState *qdev_device_add(QemuOpts *opts)
 446{
 447    ObjectClass *obj;
 448    DeviceClass *k;
 449    const char *driver, *path, *id;
 450    DeviceState *qdev;
 451    BusState *bus = NULL;
 452
 453    driver = qemu_opt_get(opts, "driver");
 454    if (!driver) {
 455        qerror_report(QERR_MISSING_PARAMETER, "driver");
 456        return NULL;
 457    }
 458
 459    /* find driver */
 460    obj = object_class_by_name(driver);
 461    if (!obj) {
 462        const char *typename = find_typename_by_alias(driver);
 463
 464        if (typename) {
 465            driver = typename;
 466            obj = object_class_by_name(driver);
 467        }
 468    }
 469
 470    if (!obj) {
 471        qerror_report(QERR_INVALID_PARAMETER_VALUE, "driver", "device type");
 472        return NULL;
 473    }
 474
 475    if (object_class_is_abstract(obj)) {
 476        qerror_report(QERR_INVALID_PARAMETER_VALUE, "driver",
 477                      "non-abstract device type");
 478        return NULL;
 479    }
 480
 481    k = DEVICE_CLASS(obj);
 482
 483    /* find bus */
 484    path = qemu_opt_get(opts, "bus");
 485    if (path != NULL) {
 486        bus = qbus_find(path);
 487        if (!bus) {
 488            return NULL;
 489        }
 490        if (!object_dynamic_cast(OBJECT(bus), k->bus_type)) {
 491            qerror_report(QERR_BAD_BUS_FOR_DEVICE,
 492                          driver, object_get_typename(OBJECT(bus)));
 493            return NULL;
 494        }
 495    } else if (k->bus_type != NULL) {
 496        bus = qbus_find_recursive(sysbus_get_default(), NULL, k->bus_type);
 497        if (!bus) {
 498            qerror_report(QERR_NO_BUS_FOR_DEVICE,
 499                          k->bus_type, driver);
 500            return NULL;
 501        }
 502    }
 503    if (qdev_hotplug && bus && !bus->allow_hotplug) {
 504        qerror_report(QERR_BUS_NO_HOTPLUG, bus->name);
 505        return NULL;
 506    }
 507
 508    /* create device, set properties */
 509    qdev = DEVICE(object_new(driver));
 510
 511    if (bus) {
 512        qdev_set_parent_bus(qdev, bus);
 513    }
 514
 515    id = qemu_opts_id(opts);
 516    if (id) {
 517        qdev->id = id;
 518    }
 519    if (qemu_opt_foreach(opts, set_property, qdev, 1) != 0) {
 520        qdev_free(qdev);
 521        object_unref(OBJECT(qdev));
 522        return NULL;
 523    }
 524    if (qdev->id) {
 525        object_property_add_child(qdev_get_peripheral(), qdev->id,
 526                                  OBJECT(qdev), NULL);
 527    } else {
 528        static int anon_count;
 529        gchar *name = g_strdup_printf("device[%d]", anon_count++);
 530        object_property_add_child(qdev_get_peripheral_anon(), name,
 531                                  OBJECT(qdev), NULL);
 532        g_free(name);
 533    }        
 534    if (qdev_init(qdev) < 0) {
 535        object_unref(OBJECT(qdev));
 536        qerror_report(QERR_DEVICE_INIT_FAILED, driver);
 537        return NULL;
 538    }
 539    qdev->opts = opts;
 540    return qdev;
 541}
 542
 543
 544#define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## __VA_ARGS__)
 545static void qbus_print(Monitor *mon, BusState *bus, int indent);
 546
 547static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
 548                             int indent)
 549{
 550    if (!props)
 551        return;
 552    for (; props->name; props++) {
 553        Error *err = NULL;
 554        char *value;
 555        char *legacy_name = g_strdup_printf("legacy-%s", props->name);
 556        if (object_property_get_type(OBJECT(dev), legacy_name, NULL)) {
 557            value = object_property_get_str(OBJECT(dev), legacy_name, &err);
 558        } else {
 559            value = object_property_print(OBJECT(dev), props->name, &err);
 560        }
 561        g_free(legacy_name);
 562
 563        if (err) {
 564            error_free(err);
 565            continue;
 566        }
 567        qdev_printf("%s = %s\n", props->name,
 568                    value && *value ? value : "<null>");
 569        g_free(value);
 570    }
 571}
 572
 573static void bus_print_dev(BusState *bus, Monitor *mon, DeviceState *dev, int indent)
 574{
 575    BusClass *bc = BUS_GET_CLASS(bus);
 576
 577    if (bc->print_dev) {
 578        bc->print_dev(mon, dev, indent);
 579    }
 580}
 581
 582static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
 583{
 584    ObjectClass *class;
 585    BusState *child;
 586    qdev_printf("dev: %s, id \"%s\"\n", object_get_typename(OBJECT(dev)),
 587                dev->id ? dev->id : "");
 588    indent += 2;
 589    if (dev->num_gpio_in) {
 590        qdev_printf("gpio-in %d\n", dev->num_gpio_in);
 591    }
 592    if (dev->num_gpio_out) {
 593        qdev_printf("gpio-out %d\n", dev->num_gpio_out);
 594    }
 595    class = object_get_class(OBJECT(dev));
 596    do {
 597        qdev_print_props(mon, dev, DEVICE_CLASS(class)->props, indent);
 598        class = object_class_get_parent(class);
 599    } while (class != object_class_by_name(TYPE_DEVICE));
 600    bus_print_dev(dev->parent_bus, mon, dev, indent);
 601    QLIST_FOREACH(child, &dev->child_bus, sibling) {
 602        qbus_print(mon, child, indent);
 603    }
 604}
 605
 606static void qbus_print(Monitor *mon, BusState *bus, int indent)
 607{
 608    BusChild *kid;
 609
 610    qdev_printf("bus: %s\n", bus->name);
 611    indent += 2;
 612    qdev_printf("type %s\n", object_get_typename(OBJECT(bus)));
 613    QTAILQ_FOREACH(kid, &bus->children, sibling) {
 614        DeviceState *dev = kid->child;
 615        qdev_print(mon, dev, indent);
 616    }
 617}
 618#undef qdev_printf
 619
 620void do_info_qtree(Monitor *mon, const QDict *qdict)
 621{
 622    if (sysbus_get_default())
 623        qbus_print(mon, sysbus_get_default(), 0);
 624}
 625
 626void do_info_qdm(Monitor *mon, const QDict *qdict)
 627{
 628    object_class_foreach(qdev_print_devinfo, TYPE_DEVICE, false, NULL);
 629}
 630
 631int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data)
 632{
 633    Error *local_err = NULL;
 634    QemuOpts *opts;
 635    DeviceState *dev;
 636
 637    opts = qemu_opts_from_qdict(qemu_find_opts("device"), qdict, &local_err);
 638    if (error_is_set(&local_err)) {
 639        qerror_report_err(local_err);
 640        error_free(local_err);
 641        return -1;
 642    }
 643    if (!monitor_cur_is_qmp() && qdev_device_help(opts)) {
 644        qemu_opts_del(opts);
 645        return 0;
 646    }
 647    dev = qdev_device_add(opts);
 648    if (!dev) {
 649        qemu_opts_del(opts);
 650        return -1;
 651    }
 652    object_unref(OBJECT(dev));
 653    return 0;
 654}
 655
 656void qmp_device_del(const char *id, Error **errp)
 657{
 658    DeviceState *dev;
 659
 660    dev = qdev_find_recursive(sysbus_get_default(), id);
 661    if (NULL == dev) {
 662        error_set(errp, QERR_DEVICE_NOT_FOUND, id);
 663        return;
 664    }
 665
 666    qdev_unplug(dev, errp);
 667}
 668
 669void qdev_machine_init(void)
 670{
 671    qdev_get_peripheral_anon();
 672    qdev_get_peripheral();
 673}
 674
 675QemuOptsList qemu_device_opts = {
 676    .name = "device",
 677    .implied_opt_name = "driver",
 678    .head = QTAILQ_HEAD_INITIALIZER(qemu_device_opts.head),
 679    .desc = {
 680        /*
 681         * no elements => accept any
 682         * sanity checking will happen later
 683         * when setting device properties
 684         */
 685        { /* end of list */ }
 686    },
 687};
 688
 689QemuOptsList qemu_global_opts = {
 690    .name = "global",
 691    .head = QTAILQ_HEAD_INITIALIZER(qemu_global_opts.head),
 692    .desc = {
 693        {
 694            .name = "driver",
 695            .type = QEMU_OPT_STRING,
 696        },{
 697            .name = "property",
 698            .type = QEMU_OPT_STRING,
 699        },{
 700            .name = "value",
 701            .type = QEMU_OPT_STRING,
 702        },
 703        { /* end of list */ }
 704    },
 705};
 706
 707int qemu_global_option(const char *str)
 708{
 709    char driver[64], property[64];
 710    QemuOpts *opts;
 711    int rc, offset;
 712
 713    rc = sscanf(str, "%63[^.].%63[^=]%n", driver, property, &offset);
 714    if (rc < 2 || str[offset] != '=') {
 715        error_report("can't parse: \"%s\"", str);
 716        return -1;
 717    }
 718
 719    opts = qemu_opts_create_nofail(&qemu_global_opts);
 720    qemu_opt_set(opts, "driver", driver);
 721    qemu_opt_set(opts, "property", property);
 722    qemu_opt_set(opts, "value", str+offset+1);
 723    return 0;
 724}
 725