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/cutils.h" 18 #include "qemu/option.h" 19 #include "monitor/monitor.h" 20 #include "sysemu/sysemu.h" 21 #include "qemu/config-file.h" 22 #include "qemu/uuid.h" 23 #include "chardev/char.h" 24 #include "ui/qemu-spice.h" 25 #include "ui/console.h" 26 #include "ui/dbus-display.h" 27 #include "sysemu/kvm.h" 28 #include "sysemu/runstate.h" 29 #include "sysemu/runstate-action.h" 30 #include "sysemu/blockdev.h" 31 #include "sysemu/block-backend.h" 32 #include "qapi/error.h" 33 #include "qapi/qapi-commands-acpi.h" 34 #include "qapi/qapi-commands-block.h" 35 #include "qapi/qapi-commands-control.h" 36 #include "qapi/qapi-commands-machine.h" 37 #include "qapi/qapi-commands-misc.h" 38 #include "qapi/qapi-commands-stats.h" 39 #include "qapi/qapi-commands-ui.h" 40 #include "qapi/type-helpers.h" 41 #include "qapi/qmp/qerror.h" 42 #include "exec/ramlist.h" 43 #include "hw/mem/memory-device.h" 44 #include "hw/acpi/acpi_dev_interface.h" 45 #include "hw/intc/intc.h" 46 #include "hw/rdma/rdma.h" 47 #include "monitor/stats.h" 48 49 NameInfo *qmp_query_name(Error **errp) 50 { 51 NameInfo *info = g_malloc0(sizeof(*info)); 52 53 if (qemu_name) { 54 info->has_name = true; 55 info->name = g_strdup(qemu_name); 56 } 57 58 return info; 59 } 60 61 KvmInfo *qmp_query_kvm(Error **errp) 62 { 63 KvmInfo *info = g_malloc0(sizeof(*info)); 64 65 info->enabled = kvm_enabled(); 66 info->present = accel_find("kvm"); 67 68 return info; 69 } 70 71 UuidInfo *qmp_query_uuid(Error **errp) 72 { 73 UuidInfo *info = g_malloc0(sizeof(*info)); 74 75 info->UUID = qemu_uuid_unparse_strdup(&qemu_uuid); 76 return info; 77 } 78 79 void qmp_quit(Error **errp) 80 { 81 shutdown_action = SHUTDOWN_ACTION_POWEROFF; 82 qemu_system_shutdown_request(SHUTDOWN_CAUSE_HOST_QMP_QUIT); 83 } 84 85 void qmp_stop(Error **errp) 86 { 87 /* if there is a dump in background, we should wait until the dump 88 * finished */ 89 if (qemu_system_dump_in_progress()) { 90 error_setg(errp, "There is a dump in process, please wait."); 91 return; 92 } 93 94 if (runstate_check(RUN_STATE_INMIGRATE)) { 95 autostart = 0; 96 } else { 97 vm_stop(RUN_STATE_PAUSED); 98 } 99 } 100 101 void qmp_system_reset(Error **errp) 102 { 103 qemu_system_reset_request(SHUTDOWN_CAUSE_HOST_QMP_SYSTEM_RESET); 104 } 105 106 void qmp_system_powerdown(Error **errp) 107 { 108 qemu_system_powerdown_request(); 109 } 110 111 void qmp_cont(Error **errp) 112 { 113 BlockBackend *blk; 114 BlockJob *job; 115 Error *local_err = NULL; 116 117 /* if there is a dump in background, we should wait until the dump 118 * finished */ 119 if (qemu_system_dump_in_progress()) { 120 error_setg(errp, "There is a dump in process, please wait."); 121 return; 122 } 123 124 if (runstate_needs_reset()) { 125 error_setg(errp, "Resetting the Virtual Machine is required"); 126 return; 127 } else if (runstate_check(RUN_STATE_SUSPENDED)) { 128 return; 129 } else if (runstate_check(RUN_STATE_FINISH_MIGRATE)) { 130 error_setg(errp, "Migration is not finalized yet"); 131 return; 132 } 133 134 for (blk = blk_next(NULL); blk; blk = blk_next(blk)) { 135 blk_iostatus_reset(blk); 136 } 137 138 for (job = block_job_next(NULL); job; job = block_job_next(job)) { 139 block_job_iostatus_reset(job); 140 } 141 142 /* Continuing after completed migration. Images have been inactivated to 143 * allow the destination to take control. Need to get control back now. 144 * 145 * If there are no inactive block nodes (e.g. because the VM was just 146 * paused rather than completing a migration), bdrv_inactivate_all() simply 147 * doesn't do anything. */ 148 bdrv_activate_all(&local_err); 149 if (local_err) { 150 error_propagate(errp, local_err); 151 return; 152 } 153 154 if (runstate_check(RUN_STATE_INMIGRATE)) { 155 autostart = 1; 156 } else { 157 vm_start(); 158 } 159 } 160 161 void qmp_system_wakeup(Error **errp) 162 { 163 if (!qemu_wakeup_suspend_enabled()) { 164 error_setg(errp, 165 "wake-up from suspend is not supported by this guest"); 166 return; 167 } 168 169 qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER, errp); 170 } 171 172 void qmp_set_password(SetPasswordOptions *opts, Error **errp) 173 { 174 int rc; 175 176 if (opts->protocol == DISPLAY_PROTOCOL_SPICE) { 177 if (!qemu_using_spice(errp)) { 178 return; 179 } 180 rc = qemu_spice.set_passwd(opts->password, 181 opts->connected == SET_PASSWORD_ACTION_FAIL, 182 opts->connected == SET_PASSWORD_ACTION_DISCONNECT); 183 } else { 184 assert(opts->protocol == DISPLAY_PROTOCOL_VNC); 185 if (opts->connected != SET_PASSWORD_ACTION_KEEP) { 186 /* vnc supports "connected=keep" only */ 187 error_setg(errp, QERR_INVALID_PARAMETER, "connected"); 188 return; 189 } 190 /* Note that setting an empty password will not disable login through 191 * this interface. */ 192 rc = vnc_display_password(opts->u.vnc.display, opts->password); 193 } 194 195 if (rc != 0) { 196 error_setg(errp, "Could not set password"); 197 } 198 } 199 200 void qmp_expire_password(ExpirePasswordOptions *opts, Error **errp) 201 { 202 time_t when; 203 int rc; 204 const char *whenstr = opts->time; 205 206 if (strcmp(whenstr, "now") == 0) { 207 when = 0; 208 } else if (strcmp(whenstr, "never") == 0) { 209 when = TIME_MAX; 210 } else if (whenstr[0] == '+') { 211 when = time(NULL) + strtoull(whenstr+1, NULL, 10); 212 } else { 213 when = strtoull(whenstr, NULL, 10); 214 } 215 216 if (opts->protocol == DISPLAY_PROTOCOL_SPICE) { 217 if (!qemu_using_spice(errp)) { 218 return; 219 } 220 rc = qemu_spice.set_pw_expire(when); 221 } else { 222 assert(opts->protocol == DISPLAY_PROTOCOL_VNC); 223 rc = vnc_display_pw_expire(opts->u.vnc.display, when); 224 } 225 226 if (rc != 0) { 227 error_setg(errp, "Could not set password expire time"); 228 } 229 } 230 231 #ifdef CONFIG_VNC 232 void qmp_change_vnc_password(const char *password, Error **errp) 233 { 234 if (vnc_display_password(NULL, password) < 0) { 235 error_setg(errp, "Could not set password"); 236 } 237 } 238 #endif 239 240 void qmp_add_client(const char *protocol, const char *fdname, 241 bool has_skipauth, bool skipauth, bool has_tls, bool tls, 242 Error **errp) 243 { 244 Chardev *s; 245 int fd; 246 247 fd = monitor_get_fd(monitor_cur(), fdname, errp); 248 if (fd < 0) { 249 return; 250 } 251 252 if (strcmp(protocol, "spice") == 0) { 253 if (!qemu_using_spice(errp)) { 254 close(fd); 255 return; 256 } 257 skipauth = has_skipauth ? skipauth : false; 258 tls = has_tls ? tls : false; 259 if (qemu_spice.display_add_client(fd, skipauth, tls) < 0) { 260 error_setg(errp, "spice failed to add client"); 261 close(fd); 262 } 263 return; 264 #ifdef CONFIG_VNC 265 } else if (strcmp(protocol, "vnc") == 0) { 266 skipauth = has_skipauth ? skipauth : false; 267 vnc_display_add_client(NULL, fd, skipauth); 268 return; 269 #endif 270 #ifdef CONFIG_DBUS_DISPLAY 271 } else if (strcmp(protocol, "@dbus-display") == 0) { 272 if (!qemu_using_dbus_display(errp)) { 273 close(fd); 274 return; 275 } 276 if (!qemu_dbus_display.add_client(fd, errp)) { 277 close(fd); 278 return; 279 } 280 return; 281 #endif 282 } else if ((s = qemu_chr_find(protocol)) != NULL) { 283 if (qemu_chr_add_client(s, fd) < 0) { 284 error_setg(errp, "failed to add client"); 285 close(fd); 286 return; 287 } 288 return; 289 } 290 291 error_setg(errp, "protocol '%s' is invalid", protocol); 292 close(fd); 293 } 294 295 296 MemoryDeviceInfoList *qmp_query_memory_devices(Error **errp) 297 { 298 return qmp_memory_device_list(); 299 } 300 301 ACPIOSTInfoList *qmp_query_acpi_ospm_status(Error **errp) 302 { 303 bool ambig; 304 ACPIOSTInfoList *head = NULL; 305 ACPIOSTInfoList **prev = &head; 306 Object *obj = object_resolve_path_type("", TYPE_ACPI_DEVICE_IF, &ambig); 307 308 if (obj) { 309 AcpiDeviceIfClass *adevc = ACPI_DEVICE_IF_GET_CLASS(obj); 310 AcpiDeviceIf *adev = ACPI_DEVICE_IF(obj); 311 312 adevc->ospm_status(adev, &prev); 313 } else { 314 error_setg(errp, "command is not supported, missing ACPI device"); 315 } 316 317 return head; 318 } 319 320 MemoryInfo *qmp_query_memory_size_summary(Error **errp) 321 { 322 MemoryInfo *mem_info = g_new0(MemoryInfo, 1); 323 MachineState *ms = MACHINE(qdev_get_machine()); 324 325 mem_info->base_memory = ms->ram_size; 326 327 mem_info->plugged_memory = get_plugged_memory_size(); 328 mem_info->has_plugged_memory = 329 mem_info->plugged_memory != (uint64_t)-1; 330 331 return mem_info; 332 } 333 334 void qmp_display_reload(DisplayReloadOptions *arg, Error **errp) 335 { 336 switch (arg->type) { 337 case DISPLAY_RELOAD_TYPE_VNC: 338 #ifdef CONFIG_VNC 339 if (arg->u.vnc.has_tls_certs && arg->u.vnc.tls_certs) { 340 vnc_display_reload_certs(NULL, errp); 341 } 342 #else 343 error_setg(errp, "vnc is invalid, missing 'CONFIG_VNC'"); 344 #endif 345 break; 346 default: 347 abort(); 348 } 349 } 350 351 void qmp_display_update(DisplayUpdateOptions *arg, Error **errp) 352 { 353 switch (arg->type) { 354 case DISPLAY_UPDATE_TYPE_VNC: 355 #ifdef CONFIG_VNC 356 vnc_display_update(&arg->u.vnc, errp); 357 #else 358 error_setg(errp, "vnc is invalid, missing 'CONFIG_VNC'"); 359 #endif 360 break; 361 default: 362 abort(); 363 } 364 } 365 366 static int qmp_x_query_rdma_foreach(Object *obj, void *opaque) 367 { 368 RdmaProvider *rdma; 369 RdmaProviderClass *k; 370 GString *buf = opaque; 371 372 if (object_dynamic_cast(obj, INTERFACE_RDMA_PROVIDER)) { 373 rdma = RDMA_PROVIDER(obj); 374 k = RDMA_PROVIDER_GET_CLASS(obj); 375 if (k->format_statistics) { 376 k->format_statistics(rdma, buf); 377 } else { 378 g_string_append_printf(buf, 379 "RDMA statistics not available for %s.\n", 380 object_get_typename(obj)); 381 } 382 } 383 384 return 0; 385 } 386 387 HumanReadableText *qmp_x_query_rdma(Error **errp) 388 { 389 g_autoptr(GString) buf = g_string_new(""); 390 391 object_child_foreach_recursive(object_get_root(), 392 qmp_x_query_rdma_foreach, buf); 393 394 return human_readable_text_from_str(buf); 395 } 396 397 HumanReadableText *qmp_x_query_ramblock(Error **errp) 398 { 399 g_autoptr(GString) buf = ram_block_format(); 400 401 return human_readable_text_from_str(buf); 402 } 403 404 static int qmp_x_query_irq_foreach(Object *obj, void *opaque) 405 { 406 InterruptStatsProvider *intc; 407 InterruptStatsProviderClass *k; 408 GString *buf = opaque; 409 410 if (object_dynamic_cast(obj, TYPE_INTERRUPT_STATS_PROVIDER)) { 411 intc = INTERRUPT_STATS_PROVIDER(obj); 412 k = INTERRUPT_STATS_PROVIDER_GET_CLASS(obj); 413 uint64_t *irq_counts; 414 unsigned int nb_irqs, i; 415 if (k->get_statistics && 416 k->get_statistics(intc, &irq_counts, &nb_irqs)) { 417 if (nb_irqs > 0) { 418 g_string_append_printf(buf, "IRQ statistics for %s:\n", 419 object_get_typename(obj)); 420 for (i = 0; i < nb_irqs; i++) { 421 if (irq_counts[i] > 0) { 422 g_string_append_printf(buf, "%2d: %" PRId64 "\n", i, 423 irq_counts[i]); 424 } 425 } 426 } 427 } else { 428 g_string_append_printf(buf, 429 "IRQ statistics not available for %s.\n", 430 object_get_typename(obj)); 431 } 432 } 433 434 return 0; 435 } 436 437 HumanReadableText *qmp_x_query_irq(Error **errp) 438 { 439 g_autoptr(GString) buf = g_string_new(""); 440 441 object_child_foreach_recursive(object_get_root(), 442 qmp_x_query_irq_foreach, buf); 443 444 return human_readable_text_from_str(buf); 445 } 446 447 typedef struct StatsCallbacks { 448 StatsProvider provider; 449 StatRetrieveFunc *stats_cb; 450 SchemaRetrieveFunc *schemas_cb; 451 QTAILQ_ENTRY(StatsCallbacks) next; 452 } StatsCallbacks; 453 454 static QTAILQ_HEAD(, StatsCallbacks) stats_callbacks = 455 QTAILQ_HEAD_INITIALIZER(stats_callbacks); 456 457 void add_stats_callbacks(StatsProvider provider, 458 StatRetrieveFunc *stats_fn, 459 SchemaRetrieveFunc *schemas_fn) 460 { 461 StatsCallbacks *entry = g_new(StatsCallbacks, 1); 462 entry->provider = provider; 463 entry->stats_cb = stats_fn; 464 entry->schemas_cb = schemas_fn; 465 466 QTAILQ_INSERT_TAIL(&stats_callbacks, entry, next); 467 } 468 469 static bool invoke_stats_cb(StatsCallbacks *entry, 470 StatsResultList **stats_results, 471 StatsFilter *filter, StatsRequest *request, 472 Error **errp) 473 { 474 strList *targets = NULL; 475 strList *names = NULL; 476 ERRP_GUARD(); 477 478 if (request) { 479 if (request->provider != entry->provider) { 480 return true; 481 } 482 if (request->has_names && !request->names) { 483 return true; 484 } 485 names = request->has_names ? request->names : NULL; 486 } 487 488 switch (filter->target) { 489 case STATS_TARGET_VM: 490 break; 491 case STATS_TARGET_VCPU: 492 if (filter->u.vcpu.has_vcpus) { 493 if (!filter->u.vcpu.vcpus) { 494 /* No targets allowed? Return no statistics. */ 495 return true; 496 } 497 targets = filter->u.vcpu.vcpus; 498 } 499 break; 500 default: 501 abort(); 502 } 503 504 entry->stats_cb(stats_results, filter->target, names, targets, errp); 505 if (*errp) { 506 qapi_free_StatsResultList(*stats_results); 507 *stats_results = NULL; 508 return false; 509 } 510 return true; 511 } 512 513 StatsResultList *qmp_query_stats(StatsFilter *filter, Error **errp) 514 { 515 StatsResultList *stats_results = NULL; 516 StatsCallbacks *entry; 517 StatsRequestList *request; 518 519 QTAILQ_FOREACH(entry, &stats_callbacks, next) { 520 if (filter->has_providers) { 521 for (request = filter->providers; request; request = request->next) { 522 if (!invoke_stats_cb(entry, &stats_results, filter, 523 request->value, errp)) { 524 break; 525 } 526 } 527 } else { 528 if (!invoke_stats_cb(entry, &stats_results, filter, NULL, errp)) { 529 break; 530 } 531 } 532 } 533 534 return stats_results; 535 } 536 537 StatsSchemaList *qmp_query_stats_schemas(bool has_provider, 538 StatsProvider provider, 539 Error **errp) 540 { 541 StatsSchemaList *stats_results = NULL; 542 StatsCallbacks *entry; 543 ERRP_GUARD(); 544 545 QTAILQ_FOREACH(entry, &stats_callbacks, next) { 546 if (!has_provider || provider == entry->provider) { 547 entry->schemas_cb(&stats_results, errp); 548 if (*errp) { 549 qapi_free_StatsSchemaList(stats_results); 550 return NULL; 551 } 552 } 553 } 554 555 return stats_results; 556 } 557 558 void add_stats_entry(StatsResultList **stats_results, StatsProvider provider, 559 const char *qom_path, StatsList *stats_list) 560 { 561 StatsResult *entry = g_new0(StatsResult, 1); 562 563 entry->provider = provider; 564 if (qom_path) { 565 entry->has_qom_path = true; 566 entry->qom_path = g_strdup(qom_path); 567 } 568 entry->stats = stats_list; 569 570 QAPI_LIST_PREPEND(*stats_results, entry); 571 } 572 573 void add_stats_schema(StatsSchemaList **schema_results, 574 StatsProvider provider, StatsTarget target, 575 StatsSchemaValueList *stats_list) 576 { 577 StatsSchema *entry = g_new0(StatsSchema, 1); 578 579 entry->provider = provider; 580 entry->target = target; 581 entry->stats = stats_list; 582 QAPI_LIST_PREPEND(*schema_results, entry); 583 } 584 585 bool apply_str_list_filter(const char *string, strList *list) 586 { 587 strList *str_list = NULL; 588 589 if (!list) { 590 return true; 591 } 592 for (str_list = list; str_list; str_list = str_list->next) { 593 if (g_str_equal(string, str_list->value)) { 594 return true; 595 } 596 } 597 return false; 598 } 599