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