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" 17*e6e108d1SMarkus Armbruster #include "monitor-internal.h" 18*e6e108d1SMarkus Armbruster #include "monitor/qdev.h" 193125af29SMarkus Armbruster #include "monitor/qmp-helpers.h" 20f1b3ccfaSKevin Wolf #include "sysemu/sysemu.h" 21f1b3ccfaSKevin Wolf #include "sysemu/kvm.h" 2254d31236SMarkus Armbruster #include "sysemu/runstate.h" 23e6dba048SAlejandro Jimenez #include "sysemu/runstate-action.h" 24f1b3ccfaSKevin Wolf #include "sysemu/block-backend.h" 25f1b3ccfaSKevin Wolf #include "qapi/error.h" 26*e6e108d1SMarkus Armbruster #include "qapi/qapi-init-commands.h" 27fa4dcf57SKevin Wolf #include "qapi/qapi-commands-control.h" 28f1b3ccfaSKevin Wolf #include "qapi/qapi-commands-misc.h" 29*e6e108d1SMarkus Armbruster #include "qapi/qmp/qerror.h" 3037087fdeSDaniel P. Berrangé #include "qapi/type-helpers.h" 31f1b3ccfaSKevin Wolf #include "hw/mem/memory-device.h" 3291f2fa70SDaniel P. Berrangé #include "hw/intc/intc.h" 338dbbca5cSDaniel P. Berrangé #include "hw/rdma/rdma.h" 34f1b3ccfaSKevin Wolf 35f1b3ccfaSKevin Wolf NameInfo *qmp_query_name(Error **errp) 36f1b3ccfaSKevin Wolf { 37f1b3ccfaSKevin Wolf NameInfo *info = g_malloc0(sizeof(*info)); 38f1b3ccfaSKevin Wolf 39f1b3ccfaSKevin Wolf info->name = g_strdup(qemu_name); 40f1b3ccfaSKevin Wolf return info; 41f1b3ccfaSKevin Wolf } 42f1b3ccfaSKevin Wolf 43f1b3ccfaSKevin Wolf void qmp_quit(Error **errp) 44f1b3ccfaSKevin Wolf { 45e6dba048SAlejandro Jimenez shutdown_action = SHUTDOWN_ACTION_POWEROFF; 46f1b3ccfaSKevin Wolf qemu_system_shutdown_request(SHUTDOWN_CAUSE_HOST_QMP_QUIT); 47f1b3ccfaSKevin Wolf } 48f1b3ccfaSKevin Wolf 49f1b3ccfaSKevin Wolf void qmp_stop(Error **errp) 50f1b3ccfaSKevin Wolf { 51f1b3ccfaSKevin Wolf /* if there is a dump in background, we should wait until the dump 52f1b3ccfaSKevin Wolf * finished */ 53544803c7SMarc-André Lureau if (qemu_system_dump_in_progress()) { 54f1b3ccfaSKevin Wolf error_setg(errp, "There is a dump in process, please wait."); 55f1b3ccfaSKevin Wolf return; 56f1b3ccfaSKevin Wolf } 57f1b3ccfaSKevin Wolf 58f1b3ccfaSKevin Wolf if (runstate_check(RUN_STATE_INMIGRATE)) { 59f1b3ccfaSKevin Wolf autostart = 0; 60f1b3ccfaSKevin Wolf } else { 61f1b3ccfaSKevin Wolf vm_stop(RUN_STATE_PAUSED); 62f1b3ccfaSKevin Wolf } 63f1b3ccfaSKevin Wolf } 64f1b3ccfaSKevin Wolf 65f1b3ccfaSKevin Wolf void qmp_cont(Error **errp) 66f1b3ccfaSKevin Wolf { 67f1b3ccfaSKevin Wolf BlockBackend *blk; 6868d00e42SVladimir Sementsov-Ogievskiy BlockJob *job; 69f1b3ccfaSKevin Wolf Error *local_err = NULL; 70f1b3ccfaSKevin Wolf 71f1b3ccfaSKevin Wolf /* if there is a dump in background, we should wait until the dump 72f1b3ccfaSKevin Wolf * finished */ 73544803c7SMarc-André Lureau if (qemu_system_dump_in_progress()) { 74f1b3ccfaSKevin Wolf error_setg(errp, "There is a dump in process, please wait."); 75f1b3ccfaSKevin Wolf return; 76f1b3ccfaSKevin Wolf } 77f1b3ccfaSKevin Wolf 78f1b3ccfaSKevin Wolf if (runstate_needs_reset()) { 79f1b3ccfaSKevin Wolf error_setg(errp, "Resetting the Virtual Machine is required"); 80f1b3ccfaSKevin Wolf return; 81f1b3ccfaSKevin Wolf } else if (runstate_check(RUN_STATE_SUSPENDED)) { 82f1b3ccfaSKevin Wolf return; 83f1b3ccfaSKevin Wolf } else if (runstate_check(RUN_STATE_FINISH_MIGRATE)) { 84f1b3ccfaSKevin Wolf error_setg(errp, "Migration is not finalized yet"); 85f1b3ccfaSKevin Wolf return; 86f1b3ccfaSKevin Wolf } 87f1b3ccfaSKevin Wolf 88f1b3ccfaSKevin Wolf for (blk = blk_next(NULL); blk; blk = blk_next(blk)) { 89f1b3ccfaSKevin Wolf blk_iostatus_reset(blk); 90f1b3ccfaSKevin Wolf } 91f1b3ccfaSKevin Wolf 92880eeec6SEmanuele Giuseppe Esposito WITH_JOB_LOCK_GUARD() { 93880eeec6SEmanuele Giuseppe Esposito for (job = block_job_next_locked(NULL); job; 94880eeec6SEmanuele Giuseppe Esposito job = block_job_next_locked(job)) { 95880eeec6SEmanuele Giuseppe Esposito block_job_iostatus_reset_locked(job); 96880eeec6SEmanuele Giuseppe Esposito } 9768d00e42SVladimir Sementsov-Ogievskiy } 9868d00e42SVladimir Sementsov-Ogievskiy 99f1b3ccfaSKevin Wolf /* Continuing after completed migration. Images have been inactivated to 100f1b3ccfaSKevin Wolf * allow the destination to take control. Need to get control back now. 101f1b3ccfaSKevin Wolf * 102f1b3ccfaSKevin Wolf * If there are no inactive block nodes (e.g. because the VM was just 103f1b3ccfaSKevin Wolf * paused rather than completing a migration), bdrv_inactivate_all() simply 104f1b3ccfaSKevin Wolf * doesn't do anything. */ 1053b717194SEmanuele Giuseppe Esposito bdrv_activate_all(&local_err); 106f1b3ccfaSKevin Wolf if (local_err) { 107f1b3ccfaSKevin Wolf error_propagate(errp, local_err); 108f1b3ccfaSKevin Wolf return; 109f1b3ccfaSKevin Wolf } 110f1b3ccfaSKevin Wolf 111f1b3ccfaSKevin Wolf if (runstate_check(RUN_STATE_INMIGRATE)) { 112f1b3ccfaSKevin Wolf autostart = 1; 113f1b3ccfaSKevin Wolf } else { 114f1b3ccfaSKevin Wolf vm_start(); 115f1b3ccfaSKevin Wolf } 116f1b3ccfaSKevin Wolf } 117f1b3ccfaSKevin Wolf 118f1b3ccfaSKevin Wolf void qmp_add_client(const char *protocol, const char *fdname, 119f1b3ccfaSKevin Wolf bool has_skipauth, bool skipauth, bool has_tls, bool tls, 120f1b3ccfaSKevin Wolf Error **errp) 121f1b3ccfaSKevin Wolf { 122f916a175SMarkus Armbruster static const struct { 1233125af29SMarkus Armbruster const char *name; 1243125af29SMarkus Armbruster bool (*add_client)(int fd, bool has_skipauth, bool skipauth, 1253125af29SMarkus Armbruster bool has_tls, bool tls, Error **errp); 1263125af29SMarkus Armbruster } protocol_table[] = { 1273125af29SMarkus Armbruster { "spice", qmp_add_client_spice }, 1283125af29SMarkus Armbruster #ifdef CONFIG_VNC 1293125af29SMarkus Armbruster { "vnc", qmp_add_client_vnc }, 1303125af29SMarkus Armbruster #endif 1313125af29SMarkus Armbruster #ifdef CONFIG_DBUS_DISPLAY 1323125af29SMarkus Armbruster { "@dbus-display", qmp_add_client_dbus_display }, 1333125af29SMarkus Armbruster #endif 1343125af29SMarkus Armbruster }; 1353125af29SMarkus Armbruster int fd, i; 136f1b3ccfaSKevin Wolf 137947e4744SKevin Wolf fd = monitor_get_fd(monitor_cur(), fdname, errp); 138f1b3ccfaSKevin Wolf if (fd < 0) { 139f1b3ccfaSKevin Wolf return; 140f1b3ccfaSKevin Wolf } 141f1b3ccfaSKevin Wolf 1423125af29SMarkus Armbruster for (i = 0; i < ARRAY_SIZE(protocol_table); i++) { 1433125af29SMarkus Armbruster if (!strcmp(protocol, protocol_table[i].name)) { 1443125af29SMarkus Armbruster if (!protocol_table[i].add_client(fd, has_skipauth, skipauth, 1453125af29SMarkus Armbruster has_tls, tls, errp)) { 146f1b3ccfaSKevin Wolf close(fd); 1473125af29SMarkus Armbruster } 148f1b3ccfaSKevin Wolf return; 149f1b3ccfaSKevin Wolf } 150f1b3ccfaSKevin Wolf } 1513125af29SMarkus Armbruster 152c3054a6eSMarkus Armbruster if (!qmp_add_client_char(fd, has_skipauth, skipauth, has_tls, tls, 153c3054a6eSMarkus Armbruster protocol, errp)) { 15461d7f2a9SMarkus Armbruster close(fd); 155f1b3ccfaSKevin Wolf } 156f1b3ccfaSKevin Wolf } 157*e6e108d1SMarkus Armbruster 158*e6e108d1SMarkus Armbruster char *qmp_human_monitor_command(const char *command_line, bool has_cpu_index, 159*e6e108d1SMarkus Armbruster int64_t cpu_index, Error **errp) 160*e6e108d1SMarkus Armbruster { 161*e6e108d1SMarkus Armbruster char *output = NULL; 162*e6e108d1SMarkus Armbruster MonitorHMP hmp = {}; 163*e6e108d1SMarkus Armbruster 164*e6e108d1SMarkus Armbruster monitor_data_init(&hmp.common, false, true, false); 165*e6e108d1SMarkus Armbruster 166*e6e108d1SMarkus Armbruster if (has_cpu_index) { 167*e6e108d1SMarkus Armbruster int ret = monitor_set_cpu(&hmp.common, cpu_index); 168*e6e108d1SMarkus Armbruster if (ret < 0) { 169*e6e108d1SMarkus Armbruster error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "cpu-index", 170*e6e108d1SMarkus Armbruster "a CPU number"); 171*e6e108d1SMarkus Armbruster goto out; 172*e6e108d1SMarkus Armbruster } 173*e6e108d1SMarkus Armbruster } 174*e6e108d1SMarkus Armbruster 175*e6e108d1SMarkus Armbruster handle_hmp_command(&hmp, command_line); 176*e6e108d1SMarkus Armbruster 177*e6e108d1SMarkus Armbruster WITH_QEMU_LOCK_GUARD(&hmp.common.mon_lock) { 178*e6e108d1SMarkus Armbruster output = g_strdup(hmp.common.outbuf->str); 179*e6e108d1SMarkus Armbruster } 180*e6e108d1SMarkus Armbruster 181*e6e108d1SMarkus Armbruster out: 182*e6e108d1SMarkus Armbruster monitor_data_destroy(&hmp.common); 183*e6e108d1SMarkus Armbruster return output; 184*e6e108d1SMarkus Armbruster } 185*e6e108d1SMarkus Armbruster 186*e6e108d1SMarkus Armbruster static void __attribute__((__constructor__)) monitor_init_qmp_commands(void) 187*e6e108d1SMarkus Armbruster { 188*e6e108d1SMarkus Armbruster /* 189*e6e108d1SMarkus Armbruster * Two command lists: 190*e6e108d1SMarkus Armbruster * - qmp_commands contains all QMP commands 191*e6e108d1SMarkus Armbruster * - qmp_cap_negotiation_commands contains just 192*e6e108d1SMarkus Armbruster * "qmp_capabilities", to enforce capability negotiation 193*e6e108d1SMarkus Armbruster */ 194*e6e108d1SMarkus Armbruster 195*e6e108d1SMarkus Armbruster qmp_init_marshal(&qmp_commands); 196*e6e108d1SMarkus Armbruster 197*e6e108d1SMarkus Armbruster qmp_register_command(&qmp_commands, "device_add", 198*e6e108d1SMarkus Armbruster qmp_device_add, 0, 0); 199*e6e108d1SMarkus Armbruster 200*e6e108d1SMarkus Armbruster QTAILQ_INIT(&qmp_cap_negotiation_commands); 201*e6e108d1SMarkus Armbruster qmp_register_command(&qmp_cap_negotiation_commands, "qmp_capabilities", 202*e6e108d1SMarkus Armbruster qmp_marshal_qmp_capabilities, 203*e6e108d1SMarkus Armbruster QCO_ALLOW_PRECONFIG, 0); 204*e6e108d1SMarkus Armbruster } 205