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