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