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_activate_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(SetPasswordOptions *opts, Error **errp) 172 { 173 int rc; 174 175 if (opts->protocol == DISPLAY_PROTOCOL_SPICE) { 176 if (!qemu_using_spice(errp)) { 177 return; 178 } 179 rc = qemu_spice.set_passwd(opts->password, 180 opts->connected == SET_PASSWORD_ACTION_FAIL, 181 opts->connected == SET_PASSWORD_ACTION_DISCONNECT); 182 } else { 183 assert(opts->protocol == DISPLAY_PROTOCOL_VNC); 184 if (opts->connected != SET_PASSWORD_ACTION_KEEP) { 185 /* vnc supports "connected=keep" only */ 186 error_setg(errp, QERR_INVALID_PARAMETER, "connected"); 187 return; 188 } 189 /* Note that setting an empty password will not disable login through 190 * this interface. */ 191 rc = vnc_display_password(opts->u.vnc.display, opts->password); 192 } 193 194 if (rc != 0) { 195 error_setg(errp, "Could not set password"); 196 } 197 } 198 199 void qmp_expire_password(ExpirePasswordOptions *opts, Error **errp) 200 { 201 time_t when; 202 int rc; 203 const char *whenstr = opts->time; 204 205 if (strcmp(whenstr, "now") == 0) { 206 when = 0; 207 } else if (strcmp(whenstr, "never") == 0) { 208 when = TIME_MAX; 209 } else if (whenstr[0] == '+') { 210 when = time(NULL) + strtoull(whenstr+1, NULL, 10); 211 } else { 212 when = strtoull(whenstr, NULL, 10); 213 } 214 215 if (opts->protocol == DISPLAY_PROTOCOL_SPICE) { 216 if (!qemu_using_spice(errp)) { 217 return; 218 } 219 rc = qemu_spice.set_pw_expire(when); 220 } else { 221 assert(opts->protocol == DISPLAY_PROTOCOL_VNC); 222 rc = vnc_display_pw_expire(opts->u.vnc.display, when); 223 } 224 225 if (rc != 0) { 226 error_setg(errp, "Could not set password expire time"); 227 } 228 } 229 230 #ifdef CONFIG_VNC 231 void qmp_change_vnc_password(const char *password, Error **errp) 232 { 233 if (vnc_display_password(NULL, password) < 0) { 234 error_setg(errp, "Could not set password"); 235 } 236 } 237 #endif 238 239 void qmp_add_client(const char *protocol, const char *fdname, 240 bool has_skipauth, bool skipauth, bool has_tls, bool tls, 241 Error **errp) 242 { 243 Chardev *s; 244 int fd; 245 246 fd = monitor_get_fd(monitor_cur(), fdname, errp); 247 if (fd < 0) { 248 return; 249 } 250 251 if (strcmp(protocol, "spice") == 0) { 252 if (!qemu_using_spice(errp)) { 253 close(fd); 254 return; 255 } 256 skipauth = has_skipauth ? skipauth : false; 257 tls = has_tls ? tls : false; 258 if (qemu_spice.display_add_client(fd, skipauth, tls) < 0) { 259 error_setg(errp, "spice failed to add client"); 260 close(fd); 261 } 262 return; 263 #ifdef CONFIG_VNC 264 } else if (strcmp(protocol, "vnc") == 0) { 265 skipauth = has_skipauth ? skipauth : false; 266 vnc_display_add_client(NULL, fd, skipauth); 267 return; 268 #endif 269 #ifdef CONFIG_DBUS_DISPLAY 270 } else if (strcmp(protocol, "@dbus-display") == 0) { 271 if (!qemu_using_dbus_display(errp)) { 272 close(fd); 273 return; 274 } 275 if (!qemu_dbus_display.add_client(fd, errp)) { 276 close(fd); 277 return; 278 } 279 return; 280 #endif 281 } else if ((s = qemu_chr_find(protocol)) != NULL) { 282 if (qemu_chr_add_client(s, fd) < 0) { 283 error_setg(errp, "failed to add client"); 284 close(fd); 285 return; 286 } 287 return; 288 } 289 290 error_setg(errp, "protocol '%s' is invalid", protocol); 291 close(fd); 292 } 293 294 295 MemoryDeviceInfoList *qmp_query_memory_devices(Error **errp) 296 { 297 return qmp_memory_device_list(); 298 } 299 300 ACPIOSTInfoList *qmp_query_acpi_ospm_status(Error **errp) 301 { 302 bool ambig; 303 ACPIOSTInfoList *head = NULL; 304 ACPIOSTInfoList **prev = &head; 305 Object *obj = object_resolve_path_type("", TYPE_ACPI_DEVICE_IF, &ambig); 306 307 if (obj) { 308 AcpiDeviceIfClass *adevc = ACPI_DEVICE_IF_GET_CLASS(obj); 309 AcpiDeviceIf *adev = ACPI_DEVICE_IF(obj); 310 311 adevc->ospm_status(adev, &prev); 312 } else { 313 error_setg(errp, "command is not supported, missing ACPI device"); 314 } 315 316 return head; 317 } 318 319 MemoryInfo *qmp_query_memory_size_summary(Error **errp) 320 { 321 MemoryInfo *mem_info = g_malloc0(sizeof(MemoryInfo)); 322 MachineState *ms = MACHINE(qdev_get_machine()); 323 324 mem_info->base_memory = ms->ram_size; 325 326 mem_info->plugged_memory = get_plugged_memory_size(); 327 mem_info->has_plugged_memory = 328 mem_info->plugged_memory != (uint64_t)-1; 329 330 return mem_info; 331 } 332 333 void qmp_display_reload(DisplayReloadOptions *arg, Error **errp) 334 { 335 switch (arg->type) { 336 case DISPLAY_RELOAD_TYPE_VNC: 337 #ifdef CONFIG_VNC 338 if (arg->u.vnc.has_tls_certs && arg->u.vnc.tls_certs) { 339 vnc_display_reload_certs(NULL, errp); 340 } 341 #else 342 error_setg(errp, "vnc is invalid, missing 'CONFIG_VNC'"); 343 #endif 344 break; 345 default: 346 abort(); 347 } 348 } 349 350 static int qmp_x_query_rdma_foreach(Object *obj, void *opaque) 351 { 352 RdmaProvider *rdma; 353 RdmaProviderClass *k; 354 GString *buf = opaque; 355 356 if (object_dynamic_cast(obj, INTERFACE_RDMA_PROVIDER)) { 357 rdma = RDMA_PROVIDER(obj); 358 k = RDMA_PROVIDER_GET_CLASS(obj); 359 if (k->format_statistics) { 360 k->format_statistics(rdma, buf); 361 } else { 362 g_string_append_printf(buf, 363 "RDMA statistics not available for %s.\n", 364 object_get_typename(obj)); 365 } 366 } 367 368 return 0; 369 } 370 371 HumanReadableText *qmp_x_query_rdma(Error **errp) 372 { 373 g_autoptr(GString) buf = g_string_new(""); 374 375 object_child_foreach_recursive(object_get_root(), 376 qmp_x_query_rdma_foreach, buf); 377 378 return human_readable_text_from_str(buf); 379 } 380 381 HumanReadableText *qmp_x_query_ramblock(Error **errp) 382 { 383 g_autoptr(GString) buf = ram_block_format(); 384 385 return human_readable_text_from_str(buf); 386 } 387 388 static int qmp_x_query_irq_foreach(Object *obj, void *opaque) 389 { 390 InterruptStatsProvider *intc; 391 InterruptStatsProviderClass *k; 392 GString *buf = opaque; 393 394 if (object_dynamic_cast(obj, TYPE_INTERRUPT_STATS_PROVIDER)) { 395 intc = INTERRUPT_STATS_PROVIDER(obj); 396 k = INTERRUPT_STATS_PROVIDER_GET_CLASS(obj); 397 uint64_t *irq_counts; 398 unsigned int nb_irqs, i; 399 if (k->get_statistics && 400 k->get_statistics(intc, &irq_counts, &nb_irqs)) { 401 if (nb_irqs > 0) { 402 g_string_append_printf(buf, "IRQ statistics for %s:\n", 403 object_get_typename(obj)); 404 for (i = 0; i < nb_irqs; i++) { 405 if (irq_counts[i] > 0) { 406 g_string_append_printf(buf, "%2d: %" PRId64 "\n", i, 407 irq_counts[i]); 408 } 409 } 410 } 411 } else { 412 g_string_append_printf(buf, 413 "IRQ statistics not available for %s.\n", 414 object_get_typename(obj)); 415 } 416 } 417 418 return 0; 419 } 420 421 HumanReadableText *qmp_x_query_irq(Error **errp) 422 { 423 g_autoptr(GString) buf = g_string_new(""); 424 425 object_child_foreach_recursive(object_get_root(), 426 qmp_x_query_irq_foreach, buf); 427 428 return human_readable_text_from_str(buf); 429 } 430