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 "system/system.h" 22 #include "system/kvm.h" 23 #include "system/runstate.h" 24 #include "system/runstate-action.h" 25 #include "system/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 "migration/misc.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 if (runstate_check(RUN_STATE_INMIGRATE)) { 101 autostart = 1; 102 } else { 103 /* 104 * Continuing after completed migration. Images have been 105 * inactivated to allow the destination to take control. Need to 106 * get control back now. 107 */ 108 if (!migration_block_activate(&local_err)) { 109 error_propagate(errp, local_err); 110 return; 111 } 112 vm_start(); 113 } 114 } 115 116 void qmp_add_client(const char *protocol, const char *fdname, 117 bool has_skipauth, bool skipauth, bool has_tls, bool tls, 118 Error **errp) 119 { 120 static const struct { 121 const char *name; 122 bool (*add_client)(int fd, bool has_skipauth, bool skipauth, 123 bool has_tls, bool tls, Error **errp); 124 } protocol_table[] = { 125 { "spice", qmp_add_client_spice }, 126 #ifdef CONFIG_VNC 127 { "vnc", qmp_add_client_vnc }, 128 #endif 129 #ifdef CONFIG_DBUS_DISPLAY 130 { "@dbus-display", qmp_add_client_dbus_display }, 131 #endif 132 }; 133 int fd, i; 134 135 fd = monitor_get_fd(monitor_cur(), fdname, errp); 136 if (fd < 0) { 137 return; 138 } 139 140 if (!fd_is_socket(fd)) { 141 error_setg(errp, "parameter @fdname must name a socket"); 142 close(fd); 143 return; 144 } 145 146 for (i = 0; i < ARRAY_SIZE(protocol_table); i++) { 147 if (!strcmp(protocol, protocol_table[i].name)) { 148 if (!protocol_table[i].add_client(fd, has_skipauth, skipauth, 149 has_tls, tls, errp)) { 150 close(fd); 151 } 152 return; 153 } 154 } 155 156 if (!qmp_add_client_char(fd, has_skipauth, skipauth, has_tls, tls, 157 protocol, errp)) { 158 close(fd); 159 } 160 } 161 162 char *qmp_human_monitor_command(const char *command_line, bool has_cpu_index, 163 int64_t cpu_index, Error **errp) 164 { 165 char *output = NULL; 166 MonitorHMP hmp = {}; 167 168 monitor_data_init(&hmp.common, false, true, false); 169 170 if (has_cpu_index) { 171 int ret = monitor_set_cpu(&hmp.common, cpu_index); 172 if (ret < 0) { 173 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "cpu-index", 174 "a CPU number"); 175 goto out; 176 } 177 } 178 179 handle_hmp_command(&hmp, command_line); 180 181 WITH_QEMU_LOCK_GUARD(&hmp.common.mon_lock) { 182 output = g_strdup(hmp.common.outbuf->str); 183 } 184 185 out: 186 monitor_data_destroy(&hmp.common); 187 return output; 188 } 189 190 static void __attribute__((__constructor__)) monitor_init_qmp_commands(void) 191 { 192 /* 193 * Two command lists: 194 * - qmp_commands contains all QMP commands 195 * - qmp_cap_negotiation_commands contains just 196 * "qmp_capabilities", to enforce capability negotiation 197 */ 198 199 qmp_init_marshal(&qmp_commands); 200 201 qmp_register_command(&qmp_commands, "device_add", 202 qmp_device_add, 0, 0); 203 204 QTAILQ_INIT(&qmp_cap_negotiation_commands); 205 qmp_register_command(&qmp_cap_negotiation_commands, "qmp_capabilities", 206 qmp_marshal_qmp_capabilities, 207 QCO_ALLOW_PRECONFIG, 0); 208 } 209