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/cutils.h" 19 #include "qemu/option.h" 20 #include "monitor/monitor.h" 21 #include "sysemu/sysemu.h" 22 #include "qemu/config-file.h" 23 #include "qemu/uuid.h" 24 #include "chardev/char.h" 25 #include "ui/qemu-spice.h" 26 #include "ui/console.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-ui.h" 39 #include "qapi/type-helpers.h" 40 #include "qapi/qmp/qerror.h" 41 #include "exec/ramlist.h" 42 #include "hw/mem/memory-device.h" 43 #include "hw/acpi/acpi_dev_interface.h" 44 #include "hw/intc/intc.h" 45 #include "hw/rdma/rdma.h" 46 47 NameInfo *qmp_query_name(Error **errp) 48 { 49 NameInfo *info = g_malloc0(sizeof(*info)); 50 51 if (qemu_name) { 52 info->has_name = true; 53 info->name = g_strdup(qemu_name); 54 } 55 56 return info; 57 } 58 59 KvmInfo *qmp_query_kvm(Error **errp) 60 { 61 KvmInfo *info = g_malloc0(sizeof(*info)); 62 63 info->enabled = kvm_enabled(); 64 info->present = accel_find("kvm"); 65 66 return info; 67 } 68 69 UuidInfo *qmp_query_uuid(Error **errp) 70 { 71 UuidInfo *info = g_malloc0(sizeof(*info)); 72 73 info->UUID = qemu_uuid_unparse_strdup(&qemu_uuid); 74 return info; 75 } 76 77 void qmp_quit(Error **errp) 78 { 79 shutdown_action = SHUTDOWN_ACTION_POWEROFF; 80 qemu_system_shutdown_request(SHUTDOWN_CAUSE_HOST_QMP_QUIT); 81 } 82 83 void qmp_stop(Error **errp) 84 { 85 /* if there is a dump in background, we should wait until the dump 86 * finished */ 87 if (dump_in_progress()) { 88 error_setg(errp, "There is a dump in process, please wait."); 89 return; 90 } 91 92 if (runstate_check(RUN_STATE_INMIGRATE)) { 93 autostart = 0; 94 } else { 95 vm_stop(RUN_STATE_PAUSED); 96 } 97 } 98 99 void qmp_system_reset(Error **errp) 100 { 101 qemu_system_reset_request(SHUTDOWN_CAUSE_HOST_QMP_SYSTEM_RESET); 102 } 103 104 void qmp_system_powerdown(Error **errp) 105 { 106 qemu_system_powerdown_request(); 107 } 108 109 void qmp_cont(Error **errp) 110 { 111 BlockBackend *blk; 112 BlockJob *job; 113 Error *local_err = NULL; 114 115 /* if there is a dump in background, we should wait until the dump 116 * finished */ 117 if (dump_in_progress()) { 118 error_setg(errp, "There is a dump in process, please wait."); 119 return; 120 } 121 122 if (runstate_needs_reset()) { 123 error_setg(errp, "Resetting the Virtual Machine is required"); 124 return; 125 } else if (runstate_check(RUN_STATE_SUSPENDED)) { 126 return; 127 } else if (runstate_check(RUN_STATE_FINISH_MIGRATE)) { 128 error_setg(errp, "Migration is not finalized yet"); 129 return; 130 } 131 132 for (blk = blk_next(NULL); blk; blk = blk_next(blk)) { 133 blk_iostatus_reset(blk); 134 } 135 136 for (job = block_job_next(NULL); job; job = block_job_next(job)) { 137 block_job_iostatus_reset(job); 138 } 139 140 /* Continuing after completed migration. Images have been inactivated to 141 * allow the destination to take control. Need to get control back now. 142 * 143 * If there are no inactive block nodes (e.g. because the VM was just 144 * paused rather than completing a migration), bdrv_inactivate_all() simply 145 * doesn't do anything. */ 146 bdrv_invalidate_cache_all(&local_err); 147 if (local_err) { 148 error_propagate(errp, local_err); 149 return; 150 } 151 152 if (runstate_check(RUN_STATE_INMIGRATE)) { 153 autostart = 1; 154 } else { 155 vm_start(); 156 } 157 } 158 159 void qmp_system_wakeup(Error **errp) 160 { 161 if (!qemu_wakeup_suspend_enabled()) { 162 error_setg(errp, 163 "wake-up from suspend is not supported by this guest"); 164 return; 165 } 166 167 qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER, errp); 168 } 169 170 void qmp_set_password(const char *protocol, const char *password, 171 bool has_connected, const char *connected, Error **errp) 172 { 173 int disconnect_if_connected = 0; 174 int fail_if_connected = 0; 175 int rc; 176 177 if (has_connected) { 178 if (strcmp(connected, "fail") == 0) { 179 fail_if_connected = 1; 180 } else if (strcmp(connected, "disconnect") == 0) { 181 disconnect_if_connected = 1; 182 } else if (strcmp(connected, "keep") == 0) { 183 /* nothing */ 184 } else { 185 error_setg(errp, QERR_INVALID_PARAMETER, "connected"); 186 return; 187 } 188 } 189 190 if (strcmp(protocol, "spice") == 0) { 191 if (!qemu_using_spice(errp)) { 192 return; 193 } 194 rc = qemu_spice.set_passwd(password, fail_if_connected, 195 disconnect_if_connected); 196 } else if (strcmp(protocol, "vnc") == 0) { 197 if (fail_if_connected || disconnect_if_connected) { 198 /* vnc supports "connected=keep" only */ 199 error_setg(errp, QERR_INVALID_PARAMETER, "connected"); 200 return; 201 } 202 /* Note that setting an empty password will not disable login through 203 * this interface. */ 204 rc = vnc_display_password(NULL, password); 205 } else { 206 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "protocol", 207 "'vnc' or 'spice'"); 208 return; 209 } 210 211 if (rc != 0) { 212 error_setg(errp, "Could not set password"); 213 } 214 } 215 216 void qmp_expire_password(const char *protocol, const char *whenstr, 217 Error **errp) 218 { 219 time_t when; 220 int rc; 221 222 if (strcmp(whenstr, "now") == 0) { 223 when = 0; 224 } else if (strcmp(whenstr, "never") == 0) { 225 when = TIME_MAX; 226 } else if (whenstr[0] == '+') { 227 when = time(NULL) + strtoull(whenstr+1, NULL, 10); 228 } else { 229 when = strtoull(whenstr, NULL, 10); 230 } 231 232 if (strcmp(protocol, "spice") == 0) { 233 if (!qemu_using_spice(errp)) { 234 return; 235 } 236 rc = qemu_spice.set_pw_expire(when); 237 } else if (strcmp(protocol, "vnc") == 0) { 238 rc = vnc_display_pw_expire(NULL, when); 239 } else { 240 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "protocol", 241 "'vnc' or 'spice'"); 242 return; 243 } 244 245 if (rc != 0) { 246 error_setg(errp, "Could not set password expire time"); 247 } 248 } 249 250 #ifdef CONFIG_VNC 251 void qmp_change_vnc_password(const char *password, Error **errp) 252 { 253 if (vnc_display_password(NULL, password) < 0) { 254 error_setg(errp, "Could not set password"); 255 } 256 } 257 #endif 258 259 void qmp_add_client(const char *protocol, const char *fdname, 260 bool has_skipauth, bool skipauth, bool has_tls, bool tls, 261 Error **errp) 262 { 263 Chardev *s; 264 int fd; 265 266 fd = monitor_get_fd(monitor_cur(), fdname, errp); 267 if (fd < 0) { 268 return; 269 } 270 271 if (strcmp(protocol, "spice") == 0) { 272 if (!qemu_using_spice(errp)) { 273 close(fd); 274 return; 275 } 276 skipauth = has_skipauth ? skipauth : false; 277 tls = has_tls ? tls : false; 278 if (qemu_spice.display_add_client(fd, skipauth, tls) < 0) { 279 error_setg(errp, "spice failed to add client"); 280 close(fd); 281 } 282 return; 283 #ifdef CONFIG_VNC 284 } else if (strcmp(protocol, "vnc") == 0) { 285 skipauth = has_skipauth ? skipauth : false; 286 vnc_display_add_client(NULL, fd, skipauth); 287 return; 288 #endif 289 } else if ((s = qemu_chr_find(protocol)) != NULL) { 290 if (qemu_chr_add_client(s, fd) < 0) { 291 error_setg(errp, "failed to add client"); 292 close(fd); 293 return; 294 } 295 return; 296 } 297 298 error_setg(errp, "protocol '%s' is invalid", protocol); 299 close(fd); 300 } 301 302 303 MemoryDeviceInfoList *qmp_query_memory_devices(Error **errp) 304 { 305 return qmp_memory_device_list(); 306 } 307 308 ACPIOSTInfoList *qmp_query_acpi_ospm_status(Error **errp) 309 { 310 bool ambig; 311 ACPIOSTInfoList *head = NULL; 312 ACPIOSTInfoList **prev = &head; 313 Object *obj = object_resolve_path_type("", TYPE_ACPI_DEVICE_IF, &ambig); 314 315 if (obj) { 316 AcpiDeviceIfClass *adevc = ACPI_DEVICE_IF_GET_CLASS(obj); 317 AcpiDeviceIf *adev = ACPI_DEVICE_IF(obj); 318 319 adevc->ospm_status(adev, &prev); 320 } else { 321 error_setg(errp, "command is not supported, missing ACPI device"); 322 } 323 324 return head; 325 } 326 327 MemoryInfo *qmp_query_memory_size_summary(Error **errp) 328 { 329 MemoryInfo *mem_info = g_malloc0(sizeof(MemoryInfo)); 330 MachineState *ms = MACHINE(qdev_get_machine()); 331 332 mem_info->base_memory = ms->ram_size; 333 334 mem_info->plugged_memory = get_plugged_memory_size(); 335 mem_info->has_plugged_memory = 336 mem_info->plugged_memory != (uint64_t)-1; 337 338 return mem_info; 339 } 340 341 void qmp_display_reload(DisplayReloadOptions *arg, Error **errp) 342 { 343 switch (arg->type) { 344 case DISPLAY_RELOAD_TYPE_VNC: 345 #ifdef CONFIG_VNC 346 if (arg->u.vnc.has_tls_certs && arg->u.vnc.tls_certs) { 347 vnc_display_reload_certs(NULL, errp); 348 } 349 #else 350 error_setg(errp, "vnc is invalid, missing 'CONFIG_VNC'"); 351 #endif 352 break; 353 default: 354 abort(); 355 } 356 } 357 358 #ifdef CONFIG_PROFILER 359 360 int64_t dev_time; 361 362 HumanReadableText *qmp_x_query_profile(Error **errp) 363 { 364 g_autoptr(GString) buf = g_string_new(""); 365 static int64_t last_cpu_exec_time; 366 int64_t cpu_exec_time; 367 int64_t delta; 368 369 cpu_exec_time = tcg_cpu_exec_time(); 370 delta = cpu_exec_time - last_cpu_exec_time; 371 372 g_string_append_printf(buf, "async time %" PRId64 " (%0.3f)\n", 373 dev_time, dev_time / (double)NANOSECONDS_PER_SECOND); 374 g_string_append_printf(buf, "qemu time %" PRId64 " (%0.3f)\n", 375 delta, delta / (double)NANOSECONDS_PER_SECOND); 376 last_cpu_exec_time = cpu_exec_time; 377 dev_time = 0; 378 379 return human_readable_text_from_str(buf); 380 } 381 #else 382 HumanReadableText *qmp_x_query_profile(Error **errp) 383 { 384 error_setg(errp, "Internal profiler not compiled"); 385 return NULL; 386 } 387 #endif 388 389 static int qmp_x_query_rdma_foreach(Object *obj, void *opaque) 390 { 391 RdmaProvider *rdma; 392 RdmaProviderClass *k; 393 GString *buf = opaque; 394 395 if (object_dynamic_cast(obj, INTERFACE_RDMA_PROVIDER)) { 396 rdma = RDMA_PROVIDER(obj); 397 k = RDMA_PROVIDER_GET_CLASS(obj); 398 if (k->format_statistics) { 399 k->format_statistics(rdma, buf); 400 } else { 401 g_string_append_printf(buf, 402 "RDMA statistics not available for %s.\n", 403 object_get_typename(obj)); 404 } 405 } 406 407 return 0; 408 } 409 410 HumanReadableText *qmp_x_query_rdma(Error **errp) 411 { 412 g_autoptr(GString) buf = g_string_new(""); 413 414 object_child_foreach_recursive(object_get_root(), 415 qmp_x_query_rdma_foreach, buf); 416 417 return human_readable_text_from_str(buf); 418 } 419 420 HumanReadableText *qmp_x_query_ramblock(Error **errp) 421 { 422 g_autoptr(GString) buf = ram_block_format(); 423 424 return human_readable_text_from_str(buf); 425 } 426 427 static int qmp_x_query_irq_foreach(Object *obj, void *opaque) 428 { 429 InterruptStatsProvider *intc; 430 InterruptStatsProviderClass *k; 431 GString *buf = opaque; 432 433 if (object_dynamic_cast(obj, TYPE_INTERRUPT_STATS_PROVIDER)) { 434 intc = INTERRUPT_STATS_PROVIDER(obj); 435 k = INTERRUPT_STATS_PROVIDER_GET_CLASS(obj); 436 uint64_t *irq_counts; 437 unsigned int nb_irqs, i; 438 if (k->get_statistics && 439 k->get_statistics(intc, &irq_counts, &nb_irqs)) { 440 if (nb_irqs > 0) { 441 g_string_append_printf(buf, "IRQ statistics for %s:\n", 442 object_get_typename(obj)); 443 for (i = 0; i < nb_irqs; i++) { 444 if (irq_counts[i] > 0) { 445 g_string_append_printf(buf, "%2d: %" PRId64 "\n", i, 446 irq_counts[i]); 447 } 448 } 449 } 450 } else { 451 g_string_append_printf(buf, 452 "IRQ statistics not available for %s.\n", 453 object_get_typename(obj)); 454 } 455 } 456 457 return 0; 458 } 459 460 HumanReadableText *qmp_x_query_irq(Error **errp) 461 { 462 g_autoptr(GString) buf = g_string_new(""); 463 464 object_child_foreach_recursive(object_get_root(), 465 qmp_x_query_irq_foreach, buf); 466 467 return human_readable_text_from_str(buf); 468 } 469