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    k = DEVICE_CLASS(obj);
 476
 477    /* find bus */
 478    path = qemu_opt_get(opts, "bus");
 479    if (path != NULL) {
 480        bus = qbus_find(path);
 481        if (!bus) {
 482            return NULL;
 483        }
 484        if (!object_dynamic_cast(OBJECT(bus), k->bus_type)) {
 485            qerror_report(QERR_BAD_BUS_FOR_DEVICE,
 486                          driver, object_get_typename(OBJECT(bus)));
 487            return NULL;
 488        }
 489    } else if (k->bus_type != NULL) {
 490        bus = qbus_find_recursive(sysbus_get_default(), NULL, k->bus_type);
 491        if (!bus) {
 492            qerror_report(QERR_NO_BUS_FOR_DEVICE,
 493                          k->bus_type, driver);
 494            return NULL;
 495        }
 496    }
 497    if (qdev_hotplug && bus && !bus->allow_hotplug) {
 498        qerror_report(QERR_BUS_NO_HOTPLUG, bus->name);
 499        return NULL;
 500    }
 501
 502    /* create device, set properties */
 503    qdev = DEVICE(object_new(driver));
 504
 505    if (bus) {
 506        qdev_set_parent_bus(qdev, bus);
 507    }
 508
 509    id = qemu_opts_id(opts);
 510    if (id) {
 511        qdev->id = id;
 512    }
 513    if (qemu_opt_foreach(opts, set_property, qdev, 1) != 0) {
 514        qdev_free(qdev);
 515        return NULL;
 516    }
 517    if (qdev->id) {
 518        object_property_add_child(qdev_get_peripheral(), qdev->id,
 519                                  OBJECT(qdev), NULL);
 520    } else {
 521        static int anon_count;
 522        gchar *name = g_strdup_printf("device[%d]", anon_count++);
 523        object_property_add_child(qdev_get_peripheral_anon(), name,
 524                                  OBJECT(qdev), NULL);
 525        g_free(name);
 526    }        
 527    if (qdev_init(qdev) < 0) {
 528        qerror_report(QERR_DEVICE_INIT_FAILED, driver);
 529        return NULL;
 530    }
 531    qdev->opts = opts;
 532    return qdev;
 533}
 534
 535
 536#define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## __VA_ARGS__)
 537static void qbus_print(Monitor *mon, BusState *bus, int indent);
 538
 539static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
 540                             int indent)
 541{
 542    if (!props)
 543        return;
 544    for (; props->name; props++) {
 545        Error *err = NULL;
 546        char *value;
 547        char *legacy_name = g_strdup_printf("legacy-%s", props->name);
 548        if (object_property_get_type(OBJECT(dev), legacy_name, NULL)) {
 549            value = object_property_get_str(OBJECT(dev), legacy_name, &err);
 550        } else {
 551            value = object_property_print(OBJECT(dev), props->name, &err);
 552        }
 553        g_free(legacy_name);
 554
 555        if (err) {
 556            error_free(err);
 557            continue;
 558        }
 559        qdev_printf("%s = %s\n", props->name,
 560                    value && *value ? value : "<null>");
 561        g_free(value);
 562    }
 563}
 564
 565static void bus_print_dev(BusState *bus, Monitor *mon, DeviceState *dev, int indent)
 566{
 567    BusClass *bc = BUS_GET_CLASS(bus);
 568
 569    if (bc->print_dev) {
 570        bc->print_dev(mon, dev, indent);
 571    }
 572}
 573
 574static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
 575{
 576    ObjectClass *class;
 577    BusState *child;
 578    qdev_printf("dev: %s, id \"%s\"\n", object_get_typename(OBJECT(dev)),
 579                dev->id ? dev->id : "");
 580    indent += 2;
 581    if (dev->num_gpio_in) {
 582        qdev_printf("gpio-in %d\n", dev->num_gpio_in);
 583    }
 584    if (dev->num_gpio_out) {
 585        qdev_printf("gpio-out %d\n", dev->num_gpio_out);
 586    }
 587    class = object_get_class(OBJECT(dev));
 588    do {
 589        qdev_print_props(mon, dev, DEVICE_CLASS(class)->props, indent);
 590        class = object_class_get_parent(class);
 591    } while (class != object_class_by_name(TYPE_DEVICE));
 592    bus_print_dev(dev->parent_bus, mon, dev, indent);
 593    QLIST_FOREACH(child, &dev->child_bus, sibling) {
 594        qbus_print(mon, child, indent);
 595    }
 596}
 597
 598static void qbus_print(Monitor *mon, BusState *bus, int indent)
 599{
 600    BusChild *kid;
 601
 602    qdev_printf("bus: %s\n", bus->name);
 603    indent += 2;
 604    qdev_printf("type %s\n", object_get_typename(OBJECT(bus)));
 605    QTAILQ_FOREACH(kid, &bus->children, sibling) {
 606        DeviceState *dev = kid->child;
 607        qdev_print(mon, dev, indent);
 608    }
 609}
 610#undef qdev_printf
 611
 612void do_info_qtree(Monitor *mon, const QDict *qdict)
 613{
 614    if (sysbus_get_default())
 615        qbus_print(mon, sysbus_get_default(), 0);
 616}
 617
 618void do_info_qdm(Monitor *mon, const QDict *qdict)
 619{
 620    object_class_foreach(qdev_print_devinfo, TYPE_DEVICE, false, NULL);
 621}
 622
 623int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data)
 624{
 625    Error *local_err = NULL;
 626    QemuOpts *opts;
 627    DeviceState *dev;
 628
 629    opts = qemu_opts_from_qdict(qemu_find_opts("device"), qdict, &local_err);
 630    if (error_is_set(&local_err)) {
 631        qerror_report_err(local_err);
 632        error_free(local_err);
 633        return -1;
 634    }
 635    if (!monitor_cur_is_qmp() && qdev_device_help(opts)) {
 636        qemu_opts_del(opts);
 637        return 0;
 638    }
 639    dev = qdev_device_add(opts);
 640    if (!dev) {
 641        qemu_opts_del(opts);
 642        return -1;
 643    }
 644    object_unref(OBJECT(dev));
 645    return 0;
 646}
 647
 648void qmp_device_del(const char *id, Error **errp)
 649{
 650    DeviceState *dev;
 651
 652    dev = qdev_find_recursive(sysbus_get_default(), id);
 653    if (NULL == dev) {
 654        error_set(errp, QERR_DEVICE_NOT_FOUND, id);
 655        return;
 656    }
 657
 658    qdev_unplug(dev, errp);
 659}
 660
 661void qdev_machine_init(void)
 662{
 663    qdev_get_peripheral_anon();
 664    qdev_get_peripheral();
 665}
 666
 667QemuOptsList qemu_device_opts = {
 668    .name = "device",
 669    .implied_opt_name = "driver",
 670    .head = QTAILQ_HEAD_INITIALIZER(qemu_device_opts.head),
 671    .desc = {
 672        /*
 673         * no elements => accept any
 674         * sanity checking will happen later
 675         * when setting device properties
 676         */
 677        { /* end of list */ }
 678    },
 679};
 680
 681QemuOptsList qemu_global_opts = {
 682    .name = "global",
 683    .head = QTAILQ_HEAD_INITIALIZER(qemu_global_opts.head),
 684    .desc = {
 685        {
 686            .name = "driver",
 687            .type = QEMU_OPT_STRING,
 688        },{
 689            .name = "property",
 690            .type = QEMU_OPT_STRING,
 691        },{
 692            .name = "value",
 693            .type = QEMU_OPT_STRING,
 694        },
 695        { /* end of list */ }
 696    },
 697};
 698
 699int qemu_global_option(const char *str)
 700{
 701    char driver[64], property[64];
 702    QemuOpts *opts;
 703    int rc, offset;
 704
 705    rc = sscanf(str, "%63[^.].%63[^=]%n", driver, property, &offset);
 706    if (rc < 2 || str[offset] != '=') {
 707        error_report("can't parse: \"%s\"", str);
 708        return -1;
 709    }
 710
 711    opts = qemu_opts_create_nofail(&qemu_global_opts);
 712    qemu_opt_set(opts, "driver", driver);
 713    qemu_opt_set(opts, "property", property);
 714    qemu_opt_set(opts, "value", str+offset+1);
 715    return 0;
 716}
 717