1f1b3ccfaSKevin Wolf /* 2f1b3ccfaSKevin Wolf * QEMU Management Protocol commands 3f1b3ccfaSKevin Wolf * 4f1b3ccfaSKevin Wolf * Copyright IBM, Corp. 2011 5f1b3ccfaSKevin Wolf * 6f1b3ccfaSKevin Wolf * Authors: 7f1b3ccfaSKevin Wolf * Anthony Liguori <aliguori@us.ibm.com> 8f1b3ccfaSKevin Wolf * 9f1b3ccfaSKevin Wolf * This work is licensed under the terms of the GNU GPL, version 2. See 10f1b3ccfaSKevin Wolf * the COPYING file in the top-level directory. 11f1b3ccfaSKevin Wolf * 12f1b3ccfaSKevin Wolf * Contributions after 2012-01-13 are licensed under the terms of the 13f1b3ccfaSKevin Wolf * GNU GPL, version 2 or (at your option) any later version. 14f1b3ccfaSKevin Wolf */ 15f1b3ccfaSKevin Wolf 16f1b3ccfaSKevin Wolf #include "qemu/osdep.h" 17f1b3ccfaSKevin Wolf #include "qemu-common.h" 18f1b3ccfaSKevin Wolf #include "qemu/cutils.h" 19f1b3ccfaSKevin Wolf #include "qemu/option.h" 20f1b3ccfaSKevin Wolf #include "monitor/monitor.h" 21f1b3ccfaSKevin Wolf #include "sysemu/sysemu.h" 22f1b3ccfaSKevin Wolf #include "qemu/config-file.h" 23f1b3ccfaSKevin Wolf #include "qemu/uuid.h" 24f1b3ccfaSKevin Wolf #include "chardev/char.h" 25f1b3ccfaSKevin Wolf #include "ui/qemu-spice.h" 26fb246f05SPeter Maydell #include "ui/console.h" 2799997823SMarc-André Lureau #include "ui/dbus-display.h" 28f1b3ccfaSKevin Wolf #include "sysemu/kvm.h" 2954d31236SMarkus Armbruster #include "sysemu/runstate.h" 30e6dba048SAlejandro Jimenez #include "sysemu/runstate-action.h" 31f1b3ccfaSKevin Wolf #include "sysemu/blockdev.h" 32f1b3ccfaSKevin Wolf #include "sysemu/block-backend.h" 33f1b3ccfaSKevin Wolf #include "qapi/error.h" 3427c9188fSPhilippe Mathieu-Daudé #include "qapi/qapi-commands-acpi.h" 355a16818bSKevin Wolf #include "qapi/qapi-commands-block.h" 36fa4dcf57SKevin Wolf #include "qapi/qapi-commands-control.h" 378ac25c84SMarkus Armbruster #include "qapi/qapi-commands-machine.h" 38f1b3ccfaSKevin Wolf #include "qapi/qapi-commands-misc.h" 39f1b3ccfaSKevin Wolf #include "qapi/qapi-commands-ui.h" 4037087fdeSDaniel P. Berrangé #include "qapi/type-helpers.h" 41f1b3ccfaSKevin Wolf #include "qapi/qmp/qerror.h" 42ca411b7cSDaniel P. Berrangé #include "exec/ramlist.h" 43f1b3ccfaSKevin Wolf #include "hw/mem/memory-device.h" 44f1b3ccfaSKevin Wolf #include "hw/acpi/acpi_dev_interface.h" 4591f2fa70SDaniel P. Berrangé #include "hw/intc/intc.h" 468dbbca5cSDaniel P. Berrangé #include "hw/rdma/rdma.h" 47f1b3ccfaSKevin Wolf 48f1b3ccfaSKevin Wolf NameInfo *qmp_query_name(Error **errp) 49f1b3ccfaSKevin Wolf { 50f1b3ccfaSKevin Wolf NameInfo *info = g_malloc0(sizeof(*info)); 51f1b3ccfaSKevin Wolf 52f1b3ccfaSKevin Wolf if (qemu_name) { 53f1b3ccfaSKevin Wolf info->has_name = true; 54f1b3ccfaSKevin Wolf info->name = g_strdup(qemu_name); 55f1b3ccfaSKevin Wolf } 56f1b3ccfaSKevin Wolf 57f1b3ccfaSKevin Wolf return info; 58f1b3ccfaSKevin Wolf } 59f1b3ccfaSKevin Wolf 60f1b3ccfaSKevin Wolf KvmInfo *qmp_query_kvm(Error **errp) 61f1b3ccfaSKevin Wolf { 62f1b3ccfaSKevin Wolf KvmInfo *info = g_malloc0(sizeof(*info)); 63f1b3ccfaSKevin Wolf 64f1b3ccfaSKevin Wolf info->enabled = kvm_enabled(); 654f9205beSPeter Maydell info->present = accel_find("kvm"); 66f1b3ccfaSKevin Wolf 67f1b3ccfaSKevin Wolf return info; 68f1b3ccfaSKevin Wolf } 69f1b3ccfaSKevin Wolf 70f1b3ccfaSKevin Wolf UuidInfo *qmp_query_uuid(Error **errp) 71f1b3ccfaSKevin Wolf { 72f1b3ccfaSKevin Wolf UuidInfo *info = g_malloc0(sizeof(*info)); 73f1b3ccfaSKevin Wolf 74f1b3ccfaSKevin Wolf info->UUID = qemu_uuid_unparse_strdup(&qemu_uuid); 75f1b3ccfaSKevin Wolf return info; 76f1b3ccfaSKevin Wolf } 77f1b3ccfaSKevin Wolf 78f1b3ccfaSKevin Wolf void qmp_quit(Error **errp) 79f1b3ccfaSKevin Wolf { 80e6dba048SAlejandro Jimenez shutdown_action = SHUTDOWN_ACTION_POWEROFF; 81f1b3ccfaSKevin Wolf qemu_system_shutdown_request(SHUTDOWN_CAUSE_HOST_QMP_QUIT); 82f1b3ccfaSKevin Wolf } 83f1b3ccfaSKevin Wolf 84f1b3ccfaSKevin Wolf void qmp_stop(Error **errp) 85f1b3ccfaSKevin Wolf { 86f1b3ccfaSKevin Wolf /* if there is a dump in background, we should wait until the dump 87f1b3ccfaSKevin Wolf * finished */ 88f1b3ccfaSKevin Wolf if (dump_in_progress()) { 89f1b3ccfaSKevin Wolf error_setg(errp, "There is a dump in process, please wait."); 90f1b3ccfaSKevin Wolf return; 91f1b3ccfaSKevin Wolf } 92f1b3ccfaSKevin Wolf 93f1b3ccfaSKevin Wolf if (runstate_check(RUN_STATE_INMIGRATE)) { 94f1b3ccfaSKevin Wolf autostart = 0; 95f1b3ccfaSKevin Wolf } else { 96f1b3ccfaSKevin Wolf vm_stop(RUN_STATE_PAUSED); 97f1b3ccfaSKevin Wolf } 98f1b3ccfaSKevin Wolf } 99f1b3ccfaSKevin Wolf 100f1b3ccfaSKevin Wolf void qmp_system_reset(Error **errp) 101f1b3ccfaSKevin Wolf { 102f1b3ccfaSKevin Wolf qemu_system_reset_request(SHUTDOWN_CAUSE_HOST_QMP_SYSTEM_RESET); 103f1b3ccfaSKevin Wolf } 104f1b3ccfaSKevin Wolf 105ec48595eSVladimir Sementsov-Ogievskiy void qmp_system_powerdown(Error **errp) 106f1b3ccfaSKevin Wolf { 107f1b3ccfaSKevin Wolf qemu_system_powerdown_request(); 108f1b3ccfaSKevin Wolf } 109f1b3ccfaSKevin Wolf 110f1b3ccfaSKevin Wolf void qmp_cont(Error **errp) 111f1b3ccfaSKevin Wolf { 112f1b3ccfaSKevin Wolf BlockBackend *blk; 11368d00e42SVladimir Sementsov-Ogievskiy BlockJob *job; 114f1b3ccfaSKevin Wolf Error *local_err = NULL; 115f1b3ccfaSKevin Wolf 116f1b3ccfaSKevin Wolf /* if there is a dump in background, we should wait until the dump 117f1b3ccfaSKevin Wolf * finished */ 118f1b3ccfaSKevin Wolf if (dump_in_progress()) { 119f1b3ccfaSKevin Wolf error_setg(errp, "There is a dump in process, please wait."); 120f1b3ccfaSKevin Wolf return; 121f1b3ccfaSKevin Wolf } 122f1b3ccfaSKevin Wolf 123f1b3ccfaSKevin Wolf if (runstate_needs_reset()) { 124f1b3ccfaSKevin Wolf error_setg(errp, "Resetting the Virtual Machine is required"); 125f1b3ccfaSKevin Wolf return; 126f1b3ccfaSKevin Wolf } else if (runstate_check(RUN_STATE_SUSPENDED)) { 127f1b3ccfaSKevin Wolf return; 128f1b3ccfaSKevin Wolf } else if (runstate_check(RUN_STATE_FINISH_MIGRATE)) { 129f1b3ccfaSKevin Wolf error_setg(errp, "Migration is not finalized yet"); 130f1b3ccfaSKevin Wolf return; 131f1b3ccfaSKevin Wolf } 132f1b3ccfaSKevin Wolf 133f1b3ccfaSKevin Wolf for (blk = blk_next(NULL); blk; blk = blk_next(blk)) { 134f1b3ccfaSKevin Wolf blk_iostatus_reset(blk); 135f1b3ccfaSKevin Wolf } 136f1b3ccfaSKevin Wolf 13768d00e42SVladimir Sementsov-Ogievskiy for (job = block_job_next(NULL); job; job = block_job_next(job)) { 13868d00e42SVladimir Sementsov-Ogievskiy block_job_iostatus_reset(job); 13968d00e42SVladimir Sementsov-Ogievskiy } 14068d00e42SVladimir Sementsov-Ogievskiy 141f1b3ccfaSKevin Wolf /* Continuing after completed migration. Images have been inactivated to 142f1b3ccfaSKevin Wolf * allow the destination to take control. Need to get control back now. 143f1b3ccfaSKevin Wolf * 144f1b3ccfaSKevin Wolf * If there are no inactive block nodes (e.g. because the VM was just 145f1b3ccfaSKevin Wolf * paused rather than completing a migration), bdrv_inactivate_all() simply 146f1b3ccfaSKevin Wolf * doesn't do anything. */ 147*3b717194SEmanuele Giuseppe Esposito bdrv_activate_all(&local_err); 148f1b3ccfaSKevin Wolf if (local_err) { 149f1b3ccfaSKevin Wolf error_propagate(errp, local_err); 150f1b3ccfaSKevin Wolf return; 151f1b3ccfaSKevin Wolf } 152f1b3ccfaSKevin Wolf 153f1b3ccfaSKevin Wolf if (runstate_check(RUN_STATE_INMIGRATE)) { 154f1b3ccfaSKevin Wolf autostart = 1; 155f1b3ccfaSKevin Wolf } else { 156f1b3ccfaSKevin Wolf vm_start(); 157f1b3ccfaSKevin Wolf } 158f1b3ccfaSKevin Wolf } 159f1b3ccfaSKevin Wolf 160f1b3ccfaSKevin Wolf void qmp_system_wakeup(Error **errp) 161f1b3ccfaSKevin Wolf { 162f1b3ccfaSKevin Wolf if (!qemu_wakeup_suspend_enabled()) { 163f1b3ccfaSKevin Wolf error_setg(errp, 164f1b3ccfaSKevin Wolf "wake-up from suspend is not supported by this guest"); 165f1b3ccfaSKevin Wolf return; 166f1b3ccfaSKevin Wolf } 167f1b3ccfaSKevin Wolf 168f1b3ccfaSKevin Wolf qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER, errp); 169f1b3ccfaSKevin Wolf } 170f1b3ccfaSKevin Wolf 171675fd3c9SStefan Reiter void qmp_set_password(SetPasswordOptions *opts, Error **errp) 172f1b3ccfaSKevin Wolf { 173f1b3ccfaSKevin Wolf int rc; 174f1b3ccfaSKevin Wolf 175675fd3c9SStefan Reiter if (opts->protocol == DISPLAY_PROTOCOL_SPICE) { 176f1b3ccfaSKevin Wolf if (!qemu_using_spice(errp)) { 177f1b3ccfaSKevin Wolf return; 178f1b3ccfaSKevin Wolf } 179675fd3c9SStefan Reiter rc = qemu_spice.set_passwd(opts->password, 180675fd3c9SStefan Reiter opts->connected == SET_PASSWORD_ACTION_FAIL, 181675fd3c9SStefan Reiter opts->connected == SET_PASSWORD_ACTION_DISCONNECT); 1827277db91SStefan Reiter } else { 183675fd3c9SStefan Reiter assert(opts->protocol == DISPLAY_PROTOCOL_VNC); 184675fd3c9SStefan Reiter if (opts->connected != SET_PASSWORD_ACTION_KEEP) { 185f1b3ccfaSKevin Wolf /* vnc supports "connected=keep" only */ 186f1b3ccfaSKevin Wolf error_setg(errp, QERR_INVALID_PARAMETER, "connected"); 187f1b3ccfaSKevin Wolf return; 188f1b3ccfaSKevin Wolf } 189f1b3ccfaSKevin Wolf /* Note that setting an empty password will not disable login through 190f1b3ccfaSKevin Wolf * this interface. */ 191675fd3c9SStefan Reiter rc = vnc_display_password(opts->u.vnc.display, opts->password); 192f1b3ccfaSKevin Wolf } 193f1b3ccfaSKevin Wolf 1949272186dSMarkus Armbruster if (rc != 0) { 1959272186dSMarkus Armbruster error_setg(errp, "Could not set password"); 1969272186dSMarkus Armbruster } 197f1b3ccfaSKevin Wolf } 198f1b3ccfaSKevin Wolf 199675fd3c9SStefan Reiter void qmp_expire_password(ExpirePasswordOptions *opts, Error **errp) 200f1b3ccfaSKevin Wolf { 201f1b3ccfaSKevin Wolf time_t when; 202f1b3ccfaSKevin Wolf int rc; 203675fd3c9SStefan Reiter const char *whenstr = opts->time; 204f1b3ccfaSKevin Wolf 205f1b3ccfaSKevin Wolf if (strcmp(whenstr, "now") == 0) { 206f1b3ccfaSKevin Wolf when = 0; 207f1b3ccfaSKevin Wolf } else if (strcmp(whenstr, "never") == 0) { 208f1b3ccfaSKevin Wolf when = TIME_MAX; 209f1b3ccfaSKevin Wolf } else if (whenstr[0] == '+') { 210f1b3ccfaSKevin Wolf when = time(NULL) + strtoull(whenstr+1, NULL, 10); 211f1b3ccfaSKevin Wolf } else { 212f1b3ccfaSKevin Wolf when = strtoull(whenstr, NULL, 10); 213f1b3ccfaSKevin Wolf } 214f1b3ccfaSKevin Wolf 215675fd3c9SStefan Reiter if (opts->protocol == DISPLAY_PROTOCOL_SPICE) { 216f1b3ccfaSKevin Wolf if (!qemu_using_spice(errp)) { 217f1b3ccfaSKevin Wolf return; 218f1b3ccfaSKevin Wolf } 21908ad2626SGerd Hoffmann rc = qemu_spice.set_pw_expire(when); 2209272186dSMarkus Armbruster } else { 221675fd3c9SStefan Reiter assert(opts->protocol == DISPLAY_PROTOCOL_VNC); 222675fd3c9SStefan Reiter rc = vnc_display_pw_expire(opts->u.vnc.display, when); 223f1b3ccfaSKevin Wolf } 224f1b3ccfaSKevin Wolf 2259272186dSMarkus Armbruster if (rc != 0) { 2269272186dSMarkus Armbruster error_setg(errp, "Could not set password expire time"); 2279272186dSMarkus Armbruster } 228f1b3ccfaSKevin Wolf } 229f1b3ccfaSKevin Wolf 230f1b3ccfaSKevin Wolf #ifdef CONFIG_VNC 231f1b3ccfaSKevin Wolf void qmp_change_vnc_password(const char *password, Error **errp) 232f1b3ccfaSKevin Wolf { 233f1b3ccfaSKevin Wolf if (vnc_display_password(NULL, password) < 0) { 2349272186dSMarkus Armbruster error_setg(errp, "Could not set password"); 235f1b3ccfaSKevin Wolf } 236f1b3ccfaSKevin Wolf } 237f1b3ccfaSKevin Wolf #endif 238f1b3ccfaSKevin Wolf 239f1b3ccfaSKevin Wolf void qmp_add_client(const char *protocol, const char *fdname, 240f1b3ccfaSKevin Wolf bool has_skipauth, bool skipauth, bool has_tls, bool tls, 241f1b3ccfaSKevin Wolf Error **errp) 242f1b3ccfaSKevin Wolf { 243f1b3ccfaSKevin Wolf Chardev *s; 244f1b3ccfaSKevin Wolf int fd; 245f1b3ccfaSKevin Wolf 246947e4744SKevin Wolf fd = monitor_get_fd(monitor_cur(), fdname, errp); 247f1b3ccfaSKevin Wolf if (fd < 0) { 248f1b3ccfaSKevin Wolf return; 249f1b3ccfaSKevin Wolf } 250f1b3ccfaSKevin Wolf 251f1b3ccfaSKevin Wolf if (strcmp(protocol, "spice") == 0) { 252f1b3ccfaSKevin Wolf if (!qemu_using_spice(errp)) { 253f1b3ccfaSKevin Wolf close(fd); 254f1b3ccfaSKevin Wolf return; 255f1b3ccfaSKevin Wolf } 256f1b3ccfaSKevin Wolf skipauth = has_skipauth ? skipauth : false; 257f1b3ccfaSKevin Wolf tls = has_tls ? tls : false; 258864a024cSGerd Hoffmann if (qemu_spice.display_add_client(fd, skipauth, tls) < 0) { 259f1b3ccfaSKevin Wolf error_setg(errp, "spice failed to add client"); 260f1b3ccfaSKevin Wolf close(fd); 261f1b3ccfaSKevin Wolf } 262f1b3ccfaSKevin Wolf return; 263f1b3ccfaSKevin Wolf #ifdef CONFIG_VNC 264f1b3ccfaSKevin Wolf } else if (strcmp(protocol, "vnc") == 0) { 265f1b3ccfaSKevin Wolf skipauth = has_skipauth ? skipauth : false; 266f1b3ccfaSKevin Wolf vnc_display_add_client(NULL, fd, skipauth); 267f1b3ccfaSKevin Wolf return; 268f1b3ccfaSKevin Wolf #endif 26999997823SMarc-André Lureau #ifdef CONFIG_DBUS_DISPLAY 27099997823SMarc-André Lureau } else if (strcmp(protocol, "@dbus-display") == 0) { 27199997823SMarc-André Lureau if (!qemu_using_dbus_display(errp)) { 27299997823SMarc-André Lureau close(fd); 27399997823SMarc-André Lureau return; 27499997823SMarc-André Lureau } 27599997823SMarc-André Lureau if (!qemu_dbus_display.add_client(fd, errp)) { 27699997823SMarc-André Lureau close(fd); 27799997823SMarc-André Lureau return; 27899997823SMarc-André Lureau } 27999997823SMarc-André Lureau return; 28099997823SMarc-André Lureau #endif 281f1b3ccfaSKevin Wolf } else if ((s = qemu_chr_find(protocol)) != NULL) { 282f1b3ccfaSKevin Wolf if (qemu_chr_add_client(s, fd) < 0) { 283f1b3ccfaSKevin Wolf error_setg(errp, "failed to add client"); 284f1b3ccfaSKevin Wolf close(fd); 285f1b3ccfaSKevin Wolf return; 286f1b3ccfaSKevin Wolf } 287f1b3ccfaSKevin Wolf return; 288f1b3ccfaSKevin Wolf } 289f1b3ccfaSKevin Wolf 290f1b3ccfaSKevin Wolf error_setg(errp, "protocol '%s' is invalid", protocol); 291f1b3ccfaSKevin Wolf close(fd); 292f1b3ccfaSKevin Wolf } 293f1b3ccfaSKevin Wolf 294f1b3ccfaSKevin Wolf 295f1b3ccfaSKevin Wolf MemoryDeviceInfoList *qmp_query_memory_devices(Error **errp) 296f1b3ccfaSKevin Wolf { 297f1b3ccfaSKevin Wolf return qmp_memory_device_list(); 298f1b3ccfaSKevin Wolf } 299f1b3ccfaSKevin Wolf 300f1b3ccfaSKevin Wolf ACPIOSTInfoList *qmp_query_acpi_ospm_status(Error **errp) 301f1b3ccfaSKevin Wolf { 302f1b3ccfaSKevin Wolf bool ambig; 303f1b3ccfaSKevin Wolf ACPIOSTInfoList *head = NULL; 304f1b3ccfaSKevin Wolf ACPIOSTInfoList **prev = &head; 305f1b3ccfaSKevin Wolf Object *obj = object_resolve_path_type("", TYPE_ACPI_DEVICE_IF, &ambig); 306f1b3ccfaSKevin Wolf 307f1b3ccfaSKevin Wolf if (obj) { 308f1b3ccfaSKevin Wolf AcpiDeviceIfClass *adevc = ACPI_DEVICE_IF_GET_CLASS(obj); 309f1b3ccfaSKevin Wolf AcpiDeviceIf *adev = ACPI_DEVICE_IF(obj); 310f1b3ccfaSKevin Wolf 311f1b3ccfaSKevin Wolf adevc->ospm_status(adev, &prev); 312f1b3ccfaSKevin Wolf } else { 313f1b3ccfaSKevin Wolf error_setg(errp, "command is not supported, missing ACPI device"); 314f1b3ccfaSKevin Wolf } 315f1b3ccfaSKevin Wolf 316f1b3ccfaSKevin Wolf return head; 317f1b3ccfaSKevin Wolf } 318f1b3ccfaSKevin Wolf 319f1b3ccfaSKevin Wolf MemoryInfo *qmp_query_memory_size_summary(Error **errp) 320f1b3ccfaSKevin Wolf { 321f1b3ccfaSKevin Wolf MemoryInfo *mem_info = g_malloc0(sizeof(MemoryInfo)); 322b326b6eaSPaolo Bonzini MachineState *ms = MACHINE(qdev_get_machine()); 323f1b3ccfaSKevin Wolf 324b326b6eaSPaolo Bonzini mem_info->base_memory = ms->ram_size; 325f1b3ccfaSKevin Wolf 326f1b3ccfaSKevin Wolf mem_info->plugged_memory = get_plugged_memory_size(); 327f1b3ccfaSKevin Wolf mem_info->has_plugged_memory = 328f1b3ccfaSKevin Wolf mem_info->plugged_memory != (uint64_t)-1; 329f1b3ccfaSKevin Wolf 330f1b3ccfaSKevin Wolf return mem_info; 331f1b3ccfaSKevin Wolf } 3329cc07651SZihao Chang 3339cc07651SZihao Chang void qmp_display_reload(DisplayReloadOptions *arg, Error **errp) 3349cc07651SZihao Chang { 3359cc07651SZihao Chang switch (arg->type) { 3369cc07651SZihao Chang case DISPLAY_RELOAD_TYPE_VNC: 3379cc07651SZihao Chang #ifdef CONFIG_VNC 3389cc07651SZihao Chang if (arg->u.vnc.has_tls_certs && arg->u.vnc.tls_certs) { 3399cc07651SZihao Chang vnc_display_reload_certs(NULL, errp); 3409cc07651SZihao Chang } 3419cc07651SZihao Chang #else 3429cc07651SZihao Chang error_setg(errp, "vnc is invalid, missing 'CONFIG_VNC'"); 3439cc07651SZihao Chang #endif 3449cc07651SZihao Chang break; 3459cc07651SZihao Chang default: 3469cc07651SZihao Chang abort(); 3479cc07651SZihao Chang } 3489cc07651SZihao Chang } 34937087fdeSDaniel P. Berrangé 3508dbbca5cSDaniel P. Berrangé static int qmp_x_query_rdma_foreach(Object *obj, void *opaque) 3518dbbca5cSDaniel P. Berrangé { 3528dbbca5cSDaniel P. Berrangé RdmaProvider *rdma; 3538dbbca5cSDaniel P. Berrangé RdmaProviderClass *k; 3548dbbca5cSDaniel P. Berrangé GString *buf = opaque; 3558dbbca5cSDaniel P. Berrangé 3568dbbca5cSDaniel P. Berrangé if (object_dynamic_cast(obj, INTERFACE_RDMA_PROVIDER)) { 3578dbbca5cSDaniel P. Berrangé rdma = RDMA_PROVIDER(obj); 3588dbbca5cSDaniel P. Berrangé k = RDMA_PROVIDER_GET_CLASS(obj); 3598dbbca5cSDaniel P. Berrangé if (k->format_statistics) { 3608dbbca5cSDaniel P. Berrangé k->format_statistics(rdma, buf); 3618dbbca5cSDaniel P. Berrangé } else { 3628dbbca5cSDaniel P. Berrangé g_string_append_printf(buf, 3638dbbca5cSDaniel P. Berrangé "RDMA statistics not available for %s.\n", 3648dbbca5cSDaniel P. Berrangé object_get_typename(obj)); 3658dbbca5cSDaniel P. Berrangé } 3668dbbca5cSDaniel P. Berrangé } 3678dbbca5cSDaniel P. Berrangé 3688dbbca5cSDaniel P. Berrangé return 0; 3698dbbca5cSDaniel P. Berrangé } 3708dbbca5cSDaniel P. Berrangé 3718dbbca5cSDaniel P. Berrangé HumanReadableText *qmp_x_query_rdma(Error **errp) 3728dbbca5cSDaniel P. Berrangé { 3738dbbca5cSDaniel P. Berrangé g_autoptr(GString) buf = g_string_new(""); 3748dbbca5cSDaniel P. Berrangé 3758dbbca5cSDaniel P. Berrangé object_child_foreach_recursive(object_get_root(), 3768dbbca5cSDaniel P. Berrangé qmp_x_query_rdma_foreach, buf); 3778dbbca5cSDaniel P. Berrangé 3788dbbca5cSDaniel P. Berrangé return human_readable_text_from_str(buf); 3798dbbca5cSDaniel P. Berrangé } 380ca411b7cSDaniel P. Berrangé 381ca411b7cSDaniel P. Berrangé HumanReadableText *qmp_x_query_ramblock(Error **errp) 382ca411b7cSDaniel P. Berrangé { 383ca411b7cSDaniel P. Berrangé g_autoptr(GString) buf = ram_block_format(); 384ca411b7cSDaniel P. Berrangé 385ca411b7cSDaniel P. Berrangé return human_readable_text_from_str(buf); 386ca411b7cSDaniel P. Berrangé } 38791f2fa70SDaniel P. Berrangé 38891f2fa70SDaniel P. Berrangé static int qmp_x_query_irq_foreach(Object *obj, void *opaque) 38991f2fa70SDaniel P. Berrangé { 39091f2fa70SDaniel P. Berrangé InterruptStatsProvider *intc; 39191f2fa70SDaniel P. Berrangé InterruptStatsProviderClass *k; 39291f2fa70SDaniel P. Berrangé GString *buf = opaque; 39391f2fa70SDaniel P. Berrangé 39491f2fa70SDaniel P. Berrangé if (object_dynamic_cast(obj, TYPE_INTERRUPT_STATS_PROVIDER)) { 39591f2fa70SDaniel P. Berrangé intc = INTERRUPT_STATS_PROVIDER(obj); 39691f2fa70SDaniel P. Berrangé k = INTERRUPT_STATS_PROVIDER_GET_CLASS(obj); 39791f2fa70SDaniel P. Berrangé uint64_t *irq_counts; 39891f2fa70SDaniel P. Berrangé unsigned int nb_irqs, i; 39991f2fa70SDaniel P. Berrangé if (k->get_statistics && 40091f2fa70SDaniel P. Berrangé k->get_statistics(intc, &irq_counts, &nb_irqs)) { 40191f2fa70SDaniel P. Berrangé if (nb_irqs > 0) { 40291f2fa70SDaniel P. Berrangé g_string_append_printf(buf, "IRQ statistics for %s:\n", 40391f2fa70SDaniel P. Berrangé object_get_typename(obj)); 40491f2fa70SDaniel P. Berrangé for (i = 0; i < nb_irqs; i++) { 40591f2fa70SDaniel P. Berrangé if (irq_counts[i] > 0) { 40691f2fa70SDaniel P. Berrangé g_string_append_printf(buf, "%2d: %" PRId64 "\n", i, 40791f2fa70SDaniel P. Berrangé irq_counts[i]); 40891f2fa70SDaniel P. Berrangé } 40991f2fa70SDaniel P. Berrangé } 41091f2fa70SDaniel P. Berrangé } 41191f2fa70SDaniel P. Berrangé } else { 41291f2fa70SDaniel P. Berrangé g_string_append_printf(buf, 41391f2fa70SDaniel P. Berrangé "IRQ statistics not available for %s.\n", 41491f2fa70SDaniel P. Berrangé object_get_typename(obj)); 41591f2fa70SDaniel P. Berrangé } 41691f2fa70SDaniel P. Berrangé } 41791f2fa70SDaniel P. Berrangé 41891f2fa70SDaniel P. Berrangé return 0; 41991f2fa70SDaniel P. Berrangé } 42091f2fa70SDaniel P. Berrangé 42191f2fa70SDaniel P. Berrangé HumanReadableText *qmp_x_query_irq(Error **errp) 42291f2fa70SDaniel P. Berrangé { 42391f2fa70SDaniel P. Berrangé g_autoptr(GString) buf = g_string_new(""); 42491f2fa70SDaniel P. Berrangé 42591f2fa70SDaniel P. Berrangé object_child_foreach_recursive(object_get_root(), 42691f2fa70SDaniel P. Berrangé qmp_x_query_irq_foreach, buf); 42791f2fa70SDaniel P. Berrangé 42891f2fa70SDaniel P. Berrangé return human_readable_text_from_str(buf); 42991f2fa70SDaniel P. Berrangé } 430