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