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-internal.h" 18 #include "monitor/qdev.h" 19 #include "monitor/qmp-helpers.h" 20 #include "sysemu/sysemu.h" 21 #include "sysemu/kvm.h" 22 #include "sysemu/runstate.h" 23 #include "sysemu/runstate-action.h" 24 #include "sysemu/block-backend.h" 25 #include "qapi/error.h" 26 #include "qapi/qapi-init-commands.h" 27 #include "qapi/qapi-commands-control.h" 28 #include "qapi/qapi-commands-misc.h" 29 #include "qapi/qmp/qerror.h" 30 #include "qapi/type-helpers.h" 31 #include "hw/mem/memory-device.h" 32 #include "hw/intc/intc.h" 33 #include "hw/rdma/rdma.h" 34 35 NameInfo *qmp_query_name(Error **errp) 36 { 37 NameInfo *info = g_malloc0(sizeof(*info)); 38 39 info->name = g_strdup(qemu_name); 40 return info; 41 } 42 43 void qmp_quit(Error **errp) 44 { 45 shutdown_action = SHUTDOWN_ACTION_POWEROFF; 46 qemu_system_shutdown_request(SHUTDOWN_CAUSE_HOST_QMP_QUIT); 47 } 48 49 void qmp_stop(Error **errp) 50 { 51 /* if there is a dump in background, we should wait until the dump 52 * finished */ 53 if (qemu_system_dump_in_progress()) { 54 error_setg(errp, "There is a dump in process, please wait."); 55 return; 56 } 57 58 if (runstate_check(RUN_STATE_INMIGRATE)) { 59 autostart = 0; 60 } else { 61 vm_stop(RUN_STATE_PAUSED); 62 } 63 } 64 65 void qmp_cont(Error **errp) 66 { 67 BlockBackend *blk; 68 BlockJob *job; 69 Error *local_err = NULL; 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_needs_reset()) { 79 error_setg(errp, "Resetting the Virtual Machine is required"); 80 return; 81 } else if (runstate_check(RUN_STATE_SUSPENDED)) { 82 return; 83 } else if (runstate_check(RUN_STATE_FINISH_MIGRATE)) { 84 error_setg(errp, "Migration is not finalized yet"); 85 return; 86 } 87 88 for (blk = blk_next(NULL); blk; blk = blk_next(blk)) { 89 blk_iostatus_reset(blk); 90 } 91 92 WITH_JOB_LOCK_GUARD() { 93 for (job = block_job_next_locked(NULL); job; 94 job = block_job_next_locked(job)) { 95 block_job_iostatus_reset_locked(job); 96 } 97 } 98 99 /* Continuing after completed migration. Images have been inactivated to 100 * allow the destination to take control. Need to get control back now. 101 * 102 * If there are no inactive block nodes (e.g. because the VM was just 103 * paused rather than completing a migration), bdrv_inactivate_all() simply 104 * doesn't do anything. */ 105 bdrv_activate_all(&local_err); 106 if (local_err) { 107 error_propagate(errp, local_err); 108 return; 109 } 110 111 if (runstate_check(RUN_STATE_INMIGRATE)) { 112 autostart = 1; 113 } else { 114 vm_start(); 115 } 116 } 117 118 void qmp_add_client(const char *protocol, const char *fdname, 119 bool has_skipauth, bool skipauth, bool has_tls, bool tls, 120 Error **errp) 121 { 122 static const struct { 123 const char *name; 124 bool (*add_client)(int fd, bool has_skipauth, bool skipauth, 125 bool has_tls, bool tls, Error **errp); 126 } protocol_table[] = { 127 { "spice", qmp_add_client_spice }, 128 #ifdef CONFIG_VNC 129 { "vnc", qmp_add_client_vnc }, 130 #endif 131 #ifdef CONFIG_DBUS_DISPLAY 132 { "@dbus-display", qmp_add_client_dbus_display }, 133 #endif 134 }; 135 int fd, i; 136 137 fd = monitor_get_fd(monitor_cur(), fdname, errp); 138 if (fd < 0) { 139 return; 140 } 141 142 for (i = 0; i < ARRAY_SIZE(protocol_table); i++) { 143 if (!strcmp(protocol, protocol_table[i].name)) { 144 if (!protocol_table[i].add_client(fd, has_skipauth, skipauth, 145 has_tls, tls, errp)) { 146 close(fd); 147 } 148 return; 149 } 150 } 151 152 if (!qmp_add_client_char(fd, has_skipauth, skipauth, has_tls, tls, 153 protocol, errp)) { 154 close(fd); 155 } 156 } 157 158 char *qmp_human_monitor_command(const char *command_line, bool has_cpu_index, 159 int64_t cpu_index, Error **errp) 160 { 161 char *output = NULL; 162 MonitorHMP hmp = {}; 163 164 monitor_data_init(&hmp.common, false, true, false); 165 166 if (has_cpu_index) { 167 int ret = monitor_set_cpu(&hmp.common, cpu_index); 168 if (ret < 0) { 169 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "cpu-index", 170 "a CPU number"); 171 goto out; 172 } 173 } 174 175 handle_hmp_command(&hmp, command_line); 176 177 WITH_QEMU_LOCK_GUARD(&hmp.common.mon_lock) { 178 output = g_strdup(hmp.common.outbuf->str); 179 } 180 181 out: 182 monitor_data_destroy(&hmp.common); 183 return output; 184 } 185 186 static void __attribute__((__constructor__)) monitor_init_qmp_commands(void) 187 { 188 /* 189 * Two command lists: 190 * - qmp_commands contains all QMP commands 191 * - qmp_cap_negotiation_commands contains just 192 * "qmp_capabilities", to enforce capability negotiation 193 */ 194 195 qmp_init_marshal(&qmp_commands); 196 197 qmp_register_command(&qmp_commands, "device_add", 198 qmp_device_add, 0, 0); 199 200 QTAILQ_INIT(&qmp_cap_negotiation_commands); 201 qmp_register_command(&qmp_cap_negotiation_commands, "qmp_capabilities", 202 qmp_marshal_qmp_capabilities, 203 QCO_ALLOW_PRECONFIG, 0); 204 } 205