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