qemu/qmp.c
<<
>>
Prefs
   1/*
   2 * QEMU Management Protocol
   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.  See
  10 * the COPYING file in the top-level directory.
  11 *
  12 * Contributions after 2012-01-13 are licensed under the terms of the
  13 * GNU GPL, version 2 or (at your option) any later version.
  14 */
  15
  16#include "qemu/osdep.h"
  17#include "qemu-version.h"
  18#include "qemu/cutils.h"
  19#include "monitor/monitor.h"
  20#include "sysemu/sysemu.h"
  21#include "qemu/config-file.h"
  22#include "qemu/uuid.h"
  23#include "qmp-commands.h"
  24#include "chardev/char.h"
  25#include "ui/qemu-spice.h"
  26#include "ui/vnc.h"
  27#include "sysemu/kvm.h"
  28#include "sysemu/arch_init.h"
  29#include "hw/qdev.h"
  30#include "sysemu/blockdev.h"
  31#include "sysemu/block-backend.h"
  32#include "qom/qom-qobject.h"
  33#include "qapi/qmp/qerror.h"
  34#include "qapi/qmp/qobject.h"
  35#include "qapi/qobject-input-visitor.h"
  36#include "hw/boards.h"
  37#include "qom/object_interfaces.h"
  38#include "hw/mem/pc-dimm.h"
  39#include "hw/acpi/acpi_dev_interface.h"
  40
  41NameInfo *qmp_query_name(Error **errp)
  42{
  43    NameInfo *info = g_malloc0(sizeof(*info));
  44
  45    if (qemu_name) {
  46        info->has_name = true;
  47        info->name = g_strdup(qemu_name);
  48    }
  49
  50    return info;
  51}
  52
  53VersionInfo *qmp_query_version(Error **errp)
  54{
  55    VersionInfo *info = g_new0(VersionInfo, 1);
  56
  57    info->qemu = g_new0(VersionTriple, 1);
  58    info->qemu->major = QEMU_VERSION_MAJOR;
  59    info->qemu->minor = QEMU_VERSION_MINOR;
  60    info->qemu->micro = QEMU_VERSION_MICRO;
  61    info->package = g_strdup(QEMU_PKGVERSION);
  62
  63    return info;
  64}
  65
  66KvmInfo *qmp_query_kvm(Error **errp)
  67{
  68    KvmInfo *info = g_malloc0(sizeof(*info));
  69
  70    info->enabled = kvm_enabled();
  71    info->present = kvm_available();
  72
  73    return info;
  74}
  75
  76UuidInfo *qmp_query_uuid(Error **errp)
  77{
  78    UuidInfo *info = g_malloc0(sizeof(*info));
  79
  80    info->UUID = qemu_uuid_unparse_strdup(&qemu_uuid);
  81    return info;
  82}
  83
  84void qmp_quit(Error **errp)
  85{
  86    no_shutdown = 0;
  87    qemu_system_shutdown_request(SHUTDOWN_CAUSE_HOST_QMP);
  88}
  89
  90void qmp_stop(Error **errp)
  91{
  92    /* if there is a dump in background, we should wait until the dump
  93     * finished */
  94    if (dump_in_progress()) {
  95        error_setg(errp, "There is a dump in process, please wait.");
  96        return;
  97    }
  98
  99    if (runstate_check(RUN_STATE_INMIGRATE)) {
 100        autostart = 0;
 101    } else {
 102        vm_stop(RUN_STATE_PAUSED);
 103    }
 104}
 105
 106void qmp_system_reset(Error **errp)
 107{
 108    qemu_system_reset_request(SHUTDOWN_CAUSE_HOST_QMP);
 109}
 110
 111void qmp_system_powerdown(Error **erp)
 112{
 113    qemu_system_powerdown_request();
 114}
 115
 116void qmp_cpu(int64_t index, Error **errp)
 117{
 118    /* Just do nothing */
 119}
 120
 121void qmp_cpu_add(int64_t id, Error **errp)
 122{
 123    MachineClass *mc;
 124
 125    mc = MACHINE_GET_CLASS(current_machine);
 126    if (mc->hot_add_cpu) {
 127        mc->hot_add_cpu(id, errp);
 128    } else {
 129        error_setg(errp, "Not supported");
 130    }
 131}
 132
 133#ifndef CONFIG_VNC
 134/* If VNC support is enabled, the "true" query-vnc command is
 135   defined in the VNC subsystem */
 136VncInfo *qmp_query_vnc(Error **errp)
 137{
 138    error_setg(errp, QERR_FEATURE_DISABLED, "vnc");
 139    return NULL;
 140};
 141
 142VncInfo2List *qmp_query_vnc_servers(Error **errp)
 143{
 144    error_setg(errp, QERR_FEATURE_DISABLED, "vnc");
 145    return NULL;
 146};
 147#endif
 148
 149#ifndef CONFIG_SPICE
 150/*
 151 * qmp-commands.hx ensures that QMP command query-spice exists only
 152 * #ifdef CONFIG_SPICE.  Necessary for an accurate query-commands
 153 * result.  However, the QAPI schema is blissfully unaware of that,
 154 * and the QAPI code generator happily generates a dead
 155 * qmp_marshal_query_spice() that calls qmp_query_spice().  Provide it
 156 * one, or else linking fails.  FIXME Educate the QAPI schema on
 157 * CONFIG_SPICE.
 158 */
 159SpiceInfo *qmp_query_spice(Error **errp)
 160{
 161    abort();
 162};
 163#endif
 164
 165void qmp_cont(Error **errp)
 166{
 167    BlockBackend *blk;
 168    Error *local_err = NULL;
 169
 170    /* if there is a dump in background, we should wait until the dump
 171     * finished */
 172    if (dump_in_progress()) {
 173        error_setg(errp, "There is a dump in process, please wait.");
 174        return;
 175    }
 176
 177    if (runstate_needs_reset()) {
 178        error_setg(errp, "Resetting the Virtual Machine is required");
 179        return;
 180    } else if (runstate_check(RUN_STATE_SUSPENDED)) {
 181        return;
 182    }
 183
 184    for (blk = blk_next(NULL); blk; blk = blk_next(blk)) {
 185        blk_iostatus_reset(blk);
 186    }
 187
 188    /* Continuing after completed migration. Images have been inactivated to
 189     * allow the destination to take control. Need to get control back now.
 190     *
 191     * If there are no inactive block nodes (e.g. because the VM was just
 192     * paused rather than completing a migration), bdrv_inactivate_all() simply
 193     * doesn't do anything. */
 194    bdrv_invalidate_cache_all(&local_err);
 195    if (local_err) {
 196        error_propagate(errp, local_err);
 197        return;
 198    }
 199
 200    if (runstate_check(RUN_STATE_INMIGRATE)) {
 201        autostart = 1;
 202    } else {
 203        vm_start();
 204    }
 205}
 206
 207void qmp_system_wakeup(Error **errp)
 208{
 209    qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
 210}
 211
 212ObjectPropertyInfoList *qmp_qom_list(const char *path, Error **errp)
 213{
 214    Object *obj;
 215    bool ambiguous = false;
 216    ObjectPropertyInfoList *props = NULL;
 217    ObjectProperty *prop;
 218    ObjectPropertyIterator iter;
 219
 220    obj = object_resolve_path(path, &ambiguous);
 221    if (obj == NULL) {
 222        if (ambiguous) {
 223            error_setg(errp, "Path '%s' is ambiguous", path);
 224        } else {
 225            error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
 226                      "Device '%s' not found", path);
 227        }
 228        return NULL;
 229    }
 230
 231    object_property_iter_init(&iter, obj);
 232    while ((prop = object_property_iter_next(&iter))) {
 233        ObjectPropertyInfoList *entry = g_malloc0(sizeof(*entry));
 234
 235        entry->value = g_malloc0(sizeof(ObjectPropertyInfo));
 236        entry->next = props;
 237        props = entry;
 238
 239        entry->value->name = g_strdup(prop->name);
 240        entry->value->type = g_strdup(prop->type);
 241    }
 242
 243    return props;
 244}
 245
 246void qmp_qom_set(const char *path, const char *property, QObject *value,
 247                 Error **errp)
 248{
 249    Object *obj;
 250
 251    obj = object_resolve_path(path, NULL);
 252    if (!obj) {
 253        error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
 254                  "Device '%s' not found", path);
 255        return;
 256    }
 257
 258    object_property_set_qobject(obj, value, property, errp);
 259}
 260
 261QObject *qmp_qom_get(const char *path, const char *property, Error **errp)
 262{
 263    Object *obj;
 264
 265    obj = object_resolve_path(path, NULL);
 266    if (!obj) {
 267        error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
 268                  "Device '%s' not found", path);
 269        return NULL;
 270    }
 271
 272    return object_property_get_qobject(obj, property, errp);
 273}
 274
 275void qmp_set_password(const char *protocol, const char *password,
 276                      bool has_connected, const char *connected, Error **errp)
 277{
 278    int disconnect_if_connected = 0;
 279    int fail_if_connected = 0;
 280    int rc;
 281
 282    if (has_connected) {
 283        if (strcmp(connected, "fail") == 0) {
 284            fail_if_connected = 1;
 285        } else if (strcmp(connected, "disconnect") == 0) {
 286            disconnect_if_connected = 1;
 287        } else if (strcmp(connected, "keep") == 0) {
 288            /* nothing */
 289        } else {
 290            error_setg(errp, QERR_INVALID_PARAMETER, "connected");
 291            return;
 292        }
 293    }
 294
 295    if (strcmp(protocol, "spice") == 0) {
 296        if (!qemu_using_spice(errp)) {
 297            return;
 298        }
 299        rc = qemu_spice_set_passwd(password, fail_if_connected,
 300                                   disconnect_if_connected);
 301        if (rc != 0) {
 302            error_setg(errp, QERR_SET_PASSWD_FAILED);
 303        }
 304        return;
 305    }
 306
 307    if (strcmp(protocol, "vnc") == 0) {
 308        if (fail_if_connected || disconnect_if_connected) {
 309            /* vnc supports "connected=keep" only */
 310            error_setg(errp, QERR_INVALID_PARAMETER, "connected");
 311            return;
 312        }
 313        /* Note that setting an empty password will not disable login through
 314         * this interface. */
 315        rc = vnc_display_password(NULL, password);
 316        if (rc < 0) {
 317            error_setg(errp, QERR_SET_PASSWD_FAILED);
 318        }
 319        return;
 320    }
 321
 322    error_setg(errp, QERR_INVALID_PARAMETER, "protocol");
 323}
 324
 325void qmp_expire_password(const char *protocol, const char *whenstr,
 326                         Error **errp)
 327{
 328    time_t when;
 329    int rc;
 330
 331    if (strcmp(whenstr, "now") == 0) {
 332        when = 0;
 333    } else if (strcmp(whenstr, "never") == 0) {
 334        when = TIME_MAX;
 335    } else if (whenstr[0] == '+') {
 336        when = time(NULL) + strtoull(whenstr+1, NULL, 10);
 337    } else {
 338        when = strtoull(whenstr, NULL, 10);
 339    }
 340
 341    if (strcmp(protocol, "spice") == 0) {
 342        if (!qemu_using_spice(errp)) {
 343            return;
 344        }
 345        rc = qemu_spice_set_pw_expire(when);
 346        if (rc != 0) {
 347            error_setg(errp, QERR_SET_PASSWD_FAILED);
 348        }
 349        return;
 350    }
 351
 352    if (strcmp(protocol, "vnc") == 0) {
 353        rc = vnc_display_pw_expire(NULL, when);
 354        if (rc != 0) {
 355            error_setg(errp, QERR_SET_PASSWD_FAILED);
 356        }
 357        return;
 358    }
 359
 360    error_setg(errp, QERR_INVALID_PARAMETER, "protocol");
 361}
 362
 363#ifdef CONFIG_VNC
 364void qmp_change_vnc_password(const char *password, Error **errp)
 365{
 366    if (vnc_display_password(NULL, password) < 0) {
 367        error_setg(errp, QERR_SET_PASSWD_FAILED);
 368    }
 369}
 370
 371static void qmp_change_vnc_listen(const char *target, Error **errp)
 372{
 373    QemuOptsList *olist = qemu_find_opts("vnc");
 374    QemuOpts *opts;
 375
 376    if (strstr(target, "id=")) {
 377        error_setg(errp, "id not supported");
 378        return;
 379    }
 380
 381    opts = qemu_opts_find(olist, "default");
 382    if (opts) {
 383        qemu_opts_del(opts);
 384    }
 385    opts = vnc_parse(target, errp);
 386    if (!opts) {
 387        return;
 388    }
 389
 390    vnc_display_open("default", errp);
 391}
 392
 393static void qmp_change_vnc(const char *target, bool has_arg, const char *arg,
 394                           Error **errp)
 395{
 396    if (strcmp(target, "passwd") == 0 || strcmp(target, "password") == 0) {
 397        if (!has_arg) {
 398            error_setg(errp, QERR_MISSING_PARAMETER, "password");
 399        } else {
 400            qmp_change_vnc_password(arg, errp);
 401        }
 402    } else {
 403        qmp_change_vnc_listen(target, errp);
 404    }
 405}
 406#else
 407void qmp_change_vnc_password(const char *password, Error **errp)
 408{
 409    error_setg(errp, QERR_FEATURE_DISABLED, "vnc");
 410}
 411static void qmp_change_vnc(const char *target, bool has_arg, const char *arg,
 412                           Error **errp)
 413{
 414    error_setg(errp, QERR_FEATURE_DISABLED, "vnc");
 415}
 416#endif /* !CONFIG_VNC */
 417
 418void qmp_change(const char *device, const char *target,
 419                bool has_arg, const char *arg, Error **errp)
 420{
 421    if (strcmp(device, "vnc") == 0) {
 422        qmp_change_vnc(target, has_arg, arg, errp);
 423    } else {
 424        qmp_blockdev_change_medium(true, device, false, NULL, target,
 425                                   has_arg, arg, false, 0, errp);
 426    }
 427}
 428
 429static void qom_list_types_tramp(ObjectClass *klass, void *data)
 430{
 431    ObjectTypeInfoList *e, **pret = data;
 432    ObjectTypeInfo *info;
 433    ObjectClass *parent = object_class_get_parent(klass);
 434
 435    info = g_malloc0(sizeof(*info));
 436    info->name = g_strdup(object_class_get_name(klass));
 437    info->has_abstract = info->abstract = object_class_is_abstract(klass);
 438    if (parent) {
 439        info->has_parent = true;
 440        info->parent = g_strdup(object_class_get_name(parent));
 441    }
 442
 443    e = g_malloc0(sizeof(*e));
 444    e->value = info;
 445    e->next = *pret;
 446    *pret = e;
 447}
 448
 449ObjectTypeInfoList *qmp_qom_list_types(bool has_implements,
 450                                       const char *implements,
 451                                       bool has_abstract,
 452                                       bool abstract,
 453                                       Error **errp)
 454{
 455    ObjectTypeInfoList *ret = NULL;
 456
 457    object_class_foreach(qom_list_types_tramp, implements, abstract, &ret);
 458
 459    return ret;
 460}
 461
 462/* Return a DevicePropertyInfo for a qdev property.
 463 *
 464 * If a qdev property with the given name does not exist, use the given default
 465 * type.  If the qdev property info should not be shown, return NULL.
 466 *
 467 * The caller must free the return value.
 468 */
 469static DevicePropertyInfo *make_device_property_info(ObjectClass *klass,
 470                                                     const char *name,
 471                                                     const char *default_type,
 472                                                     const char *description)
 473{
 474    DevicePropertyInfo *info;
 475    Property *prop;
 476
 477    do {
 478        for (prop = DEVICE_CLASS(klass)->props; prop && prop->name; prop++) {
 479            if (strcmp(name, prop->name) != 0) {
 480                continue;
 481            }
 482
 483            /*
 484             * TODO Properties without a parser are just for dirty hacks.
 485             * qdev_prop_ptr is the only such PropertyInfo.  It's marked
 486             * for removal.  This conditional should be removed along with
 487             * it.
 488             */
 489            if (!prop->info->set && !prop->info->create) {
 490                return NULL;           /* no way to set it, don't show */
 491            }
 492
 493            info = g_malloc0(sizeof(*info));
 494            info->name = g_strdup(prop->name);
 495            info->type = default_type ? g_strdup(default_type)
 496                                      : g_strdup(prop->info->name);
 497            info->has_description = !!prop->info->description;
 498            info->description = g_strdup(prop->info->description);
 499            return info;
 500        }
 501        klass = object_class_get_parent(klass);
 502    } while (klass != object_class_by_name(TYPE_DEVICE));
 503
 504    /* Not a qdev property, use the default type */
 505    info = g_malloc0(sizeof(*info));
 506    info->name = g_strdup(name);
 507    info->type = g_strdup(default_type);
 508    info->has_description = !!description;
 509    info->description = g_strdup(description);
 510
 511    return info;
 512}
 513
 514DevicePropertyInfoList *qmp_device_list_properties(const char *typename,
 515                                                   Error **errp)
 516{
 517    ObjectClass *klass;
 518    Object *obj;
 519    ObjectProperty *prop;
 520    ObjectPropertyIterator iter;
 521    DevicePropertyInfoList *prop_list = NULL;
 522
 523    klass = object_class_by_name(typename);
 524    if (klass == NULL) {
 525        error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
 526                  "Device '%s' not found", typename);
 527        return NULL;
 528    }
 529
 530    klass = object_class_dynamic_cast(klass, TYPE_DEVICE);
 531    if (klass == NULL) {
 532        error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "typename", TYPE_DEVICE);
 533        return NULL;
 534    }
 535
 536    if (object_class_is_abstract(klass)) {
 537        error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "typename",
 538                   "non-abstract device type");
 539        return NULL;
 540    }
 541
 542    obj = object_new(typename);
 543
 544    object_property_iter_init(&iter, obj);
 545    while ((prop = object_property_iter_next(&iter))) {
 546        DevicePropertyInfo *info;
 547        DevicePropertyInfoList *entry;
 548
 549        /* Skip Object and DeviceState properties */
 550        if (strcmp(prop->name, "type") == 0 ||
 551            strcmp(prop->name, "realized") == 0 ||
 552            strcmp(prop->name, "hotpluggable") == 0 ||
 553            strcmp(prop->name, "hotplugged") == 0 ||
 554            strcmp(prop->name, "parent_bus") == 0) {
 555            continue;
 556        }
 557
 558        /* Skip legacy properties since they are just string versions of
 559         * properties that we already list.
 560         */
 561        if (strstart(prop->name, "legacy-", NULL)) {
 562            continue;
 563        }
 564
 565        info = make_device_property_info(klass, prop->name, prop->type,
 566                                         prop->description);
 567        if (!info) {
 568            continue;
 569        }
 570
 571        entry = g_malloc0(sizeof(*entry));
 572        entry->value = info;
 573        entry->next = prop_list;
 574        prop_list = entry;
 575    }
 576
 577    object_unref(obj);
 578
 579    return prop_list;
 580}
 581
 582CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
 583{
 584    return arch_query_cpu_definitions(errp);
 585}
 586
 587CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
 588                                                     CpuModelInfo *model,
 589                                                     Error **errp)
 590{
 591    return arch_query_cpu_model_expansion(type, model, errp);
 592}
 593
 594CpuModelCompareInfo *qmp_query_cpu_model_comparison(CpuModelInfo *modela,
 595                                                    CpuModelInfo *modelb,
 596                                                    Error **errp)
 597{
 598    return arch_query_cpu_model_comparison(modela, modelb, errp);
 599}
 600
 601CpuModelBaselineInfo *qmp_query_cpu_model_baseline(CpuModelInfo *modela,
 602                                                   CpuModelInfo *modelb,
 603                                                   Error **errp)
 604{
 605    return arch_query_cpu_model_baseline(modela, modelb, errp);
 606}
 607
 608void qmp_add_client(const char *protocol, const char *fdname,
 609                    bool has_skipauth, bool skipauth, bool has_tls, bool tls,
 610                    Error **errp)
 611{
 612    Chardev *s;
 613    int fd;
 614
 615    fd = monitor_get_fd(cur_mon, fdname, errp);
 616    if (fd < 0) {
 617        return;
 618    }
 619
 620    if (strcmp(protocol, "spice") == 0) {
 621        if (!qemu_using_spice(errp)) {
 622            close(fd);
 623            return;
 624        }
 625        skipauth = has_skipauth ? skipauth : false;
 626        tls = has_tls ? tls : false;
 627        if (qemu_spice_display_add_client(fd, skipauth, tls) < 0) {
 628            error_setg(errp, "spice failed to add client");
 629            close(fd);
 630        }
 631        return;
 632#ifdef CONFIG_VNC
 633    } else if (strcmp(protocol, "vnc") == 0) {
 634        skipauth = has_skipauth ? skipauth : false;
 635        vnc_display_add_client(NULL, fd, skipauth);
 636        return;
 637#endif
 638    } else if ((s = qemu_chr_find(protocol)) != NULL) {
 639        if (qemu_chr_add_client(s, fd) < 0) {
 640            error_setg(errp, "failed to add client");
 641            close(fd);
 642            return;
 643        }
 644        return;
 645    }
 646
 647    error_setg(errp, "protocol '%s' is invalid", protocol);
 648    close(fd);
 649}
 650
 651
 652void qmp_object_add(const char *type, const char *id,
 653                    bool has_props, QObject *props, Error **errp)
 654{
 655    QDict *pdict;
 656    Visitor *v;
 657    Object *obj;
 658
 659    if (props) {
 660        pdict = qobject_to_qdict(props);
 661        if (!pdict) {
 662            error_setg(errp, QERR_INVALID_PARAMETER_TYPE, "props", "dict");
 663            return;
 664        }
 665        QINCREF(pdict);
 666    } else {
 667        pdict = qdict_new();
 668    }
 669
 670    v = qobject_input_visitor_new(QOBJECT(pdict));
 671    obj = user_creatable_add_type(type, id, pdict, v, errp);
 672    visit_free(v);
 673    if (obj) {
 674        object_unref(obj);
 675    }
 676    QDECREF(pdict);
 677}
 678
 679void qmp_object_del(const char *id, Error **errp)
 680{
 681    user_creatable_del(id, errp);
 682}
 683
 684MemoryDeviceInfoList *qmp_query_memory_devices(Error **errp)
 685{
 686    MemoryDeviceInfoList *head = NULL;
 687    MemoryDeviceInfoList **prev = &head;
 688
 689    qmp_pc_dimm_device_list(qdev_get_machine(), &prev);
 690
 691    return head;
 692}
 693
 694ACPIOSTInfoList *qmp_query_acpi_ospm_status(Error **errp)
 695{
 696    bool ambig;
 697    ACPIOSTInfoList *head = NULL;
 698    ACPIOSTInfoList **prev = &head;
 699    Object *obj = object_resolve_path_type("", TYPE_ACPI_DEVICE_IF, &ambig);
 700
 701    if (obj) {
 702        AcpiDeviceIfClass *adevc = ACPI_DEVICE_IF_GET_CLASS(obj);
 703        AcpiDeviceIf *adev = ACPI_DEVICE_IF(obj);
 704
 705        adevc->ospm_status(adev, &prev);
 706    } else {
 707        error_setg(errp, "command is not supported, missing ACPI device");
 708    }
 709
 710    return head;
 711}
 712
 713MemoryInfo *qmp_query_memory_size_summary(Error **errp)
 714{
 715    MemoryInfo *mem_info = g_malloc0(sizeof(MemoryInfo));
 716
 717    mem_info->base_memory = ram_size;
 718
 719    mem_info->plugged_memory = get_plugged_memory_size();
 720    mem_info->has_plugged_memory =
 721        mem_info->plugged_memory != (uint64_t)-1;
 722
 723    return mem_info;
 724}
 725