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