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-common.h" 18 #include "qemu-version.h" 19 #include "qemu/cutils.h" 20 #include "qemu/option.h" 21 #include "monitor/monitor.h" 22 #include "sysemu/sysemu.h" 23 #include "qemu/config-file.h" 24 #include "qemu/uuid.h" 25 #include "chardev/char.h" 26 #include "ui/qemu-spice.h" 27 #include "ui/vnc.h" 28 #include "sysemu/kvm.h" 29 #include "sysemu/arch_init.h" 30 #include "sysemu/blockdev.h" 31 #include "sysemu/block-backend.h" 32 #include "qapi/error.h" 33 #include "qapi/qapi-commands-block-core.h" 34 #include "qapi/qapi-commands-machine.h" 35 #include "qapi/qapi-commands-misc.h" 36 #include "qapi/qapi-commands-ui.h" 37 #include "qapi/qmp/qerror.h" 38 #include "hw/mem/memory-device.h" 39 #include "hw/acpi/acpi_dev_interface.h" 40 41 NameInfo *qmp_query_name(Error **errp) 42 { 43 NameInfo *info = g_malloc0(sizeof(*info)); 44 45 if (qemu_name) { 46 info->has_name = true; 47 info->name = g_strdup(qemu_name); 48 } 49 50 return info; 51 } 52 53 VersionInfo *qmp_query_version(Error **errp) 54 { 55 VersionInfo *info = g_new0(VersionInfo, 1); 56 57 info->qemu = g_new0(VersionTriple, 1); 58 info->qemu->major = QEMU_VERSION_MAJOR; 59 info->qemu->minor = QEMU_VERSION_MINOR; 60 info->qemu->micro = QEMU_VERSION_MICRO; 61 info->package = g_strdup(QEMU_PKGVERSION); 62 63 return info; 64 } 65 66 KvmInfo *qmp_query_kvm(Error **errp) 67 { 68 KvmInfo *info = g_malloc0(sizeof(*info)); 69 70 info->enabled = kvm_enabled(); 71 info->present = kvm_available(); 72 73 return info; 74 } 75 76 UuidInfo *qmp_query_uuid(Error **errp) 77 { 78 UuidInfo *info = g_malloc0(sizeof(*info)); 79 80 info->UUID = qemu_uuid_unparse_strdup(&qemu_uuid); 81 return info; 82 } 83 84 void qmp_quit(Error **errp) 85 { 86 no_shutdown = 0; 87 qemu_system_shutdown_request(SHUTDOWN_CAUSE_HOST_QMP_QUIT); 88 } 89 90 void qmp_stop(Error **errp) 91 { 92 /* if there is a dump in background, we should wait until the dump 93 * finished */ 94 if (dump_in_progress()) { 95 error_setg(errp, "There is a dump in process, please wait."); 96 return; 97 } 98 99 if (runstate_check(RUN_STATE_INMIGRATE)) { 100 autostart = 0; 101 } else { 102 vm_stop(RUN_STATE_PAUSED); 103 } 104 } 105 106 void qmp_system_reset(Error **errp) 107 { 108 qemu_system_reset_request(SHUTDOWN_CAUSE_HOST_QMP_SYSTEM_RESET); 109 } 110 111 void qmp_system_powerdown(Error **erp) 112 { 113 qemu_system_powerdown_request(); 114 } 115 116 void qmp_x_exit_preconfig(Error **errp) 117 { 118 if (!runstate_check(RUN_STATE_PRECONFIG)) { 119 error_setg(errp, "The command is permitted only in '%s' state", 120 RunState_str(RUN_STATE_PRECONFIG)); 121 return; 122 } 123 qemu_exit_preconfig_request(); 124 } 125 126 void qmp_cont(Error **errp) 127 { 128 BlockBackend *blk; 129 BlockJob *job; 130 Error *local_err = NULL; 131 132 /* if there is a dump in background, we should wait until the dump 133 * finished */ 134 if (dump_in_progress()) { 135 error_setg(errp, "There is a dump in process, please wait."); 136 return; 137 } 138 139 if (runstate_needs_reset()) { 140 error_setg(errp, "Resetting the Virtual Machine is required"); 141 return; 142 } else if (runstate_check(RUN_STATE_SUSPENDED)) { 143 return; 144 } else if (runstate_check(RUN_STATE_FINISH_MIGRATE)) { 145 error_setg(errp, "Migration is not finalized yet"); 146 return; 147 } 148 149 for (blk = blk_next(NULL); blk; blk = blk_next(blk)) { 150 blk_iostatus_reset(blk); 151 } 152 153 for (job = block_job_next(NULL); job; job = block_job_next(job)) { 154 block_job_iostatus_reset(job); 155 } 156 157 /* Continuing after completed migration. Images have been inactivated to 158 * allow the destination to take control. Need to get control back now. 159 * 160 * If there are no inactive block nodes (e.g. because the VM was just 161 * paused rather than completing a migration), bdrv_inactivate_all() simply 162 * doesn't do anything. */ 163 bdrv_invalidate_cache_all(&local_err); 164 if (local_err) { 165 error_propagate(errp, local_err); 166 return; 167 } 168 169 if (runstate_check(RUN_STATE_INMIGRATE)) { 170 autostart = 1; 171 } else { 172 vm_start(); 173 } 174 } 175 176 void qmp_system_wakeup(Error **errp) 177 { 178 if (!qemu_wakeup_suspend_enabled()) { 179 error_setg(errp, 180 "wake-up from suspend is not supported by this guest"); 181 return; 182 } 183 184 qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER, errp); 185 } 186 187 void qmp_set_password(const char *protocol, const char *password, 188 bool has_connected, const char *connected, Error **errp) 189 { 190 int disconnect_if_connected = 0; 191 int fail_if_connected = 0; 192 int rc; 193 194 if (has_connected) { 195 if (strcmp(connected, "fail") == 0) { 196 fail_if_connected = 1; 197 } else if (strcmp(connected, "disconnect") == 0) { 198 disconnect_if_connected = 1; 199 } else if (strcmp(connected, "keep") == 0) { 200 /* nothing */ 201 } else { 202 error_setg(errp, QERR_INVALID_PARAMETER, "connected"); 203 return; 204 } 205 } 206 207 if (strcmp(protocol, "spice") == 0) { 208 if (!qemu_using_spice(errp)) { 209 return; 210 } 211 rc = qemu_spice_set_passwd(password, fail_if_connected, 212 disconnect_if_connected); 213 if (rc != 0) { 214 error_setg(errp, QERR_SET_PASSWD_FAILED); 215 } 216 return; 217 } 218 219 if (strcmp(protocol, "vnc") == 0) { 220 if (fail_if_connected || disconnect_if_connected) { 221 /* vnc supports "connected=keep" only */ 222 error_setg(errp, QERR_INVALID_PARAMETER, "connected"); 223 return; 224 } 225 /* Note that setting an empty password will not disable login through 226 * this interface. */ 227 rc = vnc_display_password(NULL, password); 228 if (rc < 0) { 229 error_setg(errp, QERR_SET_PASSWD_FAILED); 230 } 231 return; 232 } 233 234 error_setg(errp, QERR_INVALID_PARAMETER, "protocol"); 235 } 236 237 void qmp_expire_password(const char *protocol, const char *whenstr, 238 Error **errp) 239 { 240 time_t when; 241 int rc; 242 243 if (strcmp(whenstr, "now") == 0) { 244 when = 0; 245 } else if (strcmp(whenstr, "never") == 0) { 246 when = TIME_MAX; 247 } else if (whenstr[0] == '+') { 248 when = time(NULL) + strtoull(whenstr+1, NULL, 10); 249 } else { 250 when = strtoull(whenstr, NULL, 10); 251 } 252 253 if (strcmp(protocol, "spice") == 0) { 254 if (!qemu_using_spice(errp)) { 255 return; 256 } 257 rc = qemu_spice_set_pw_expire(when); 258 if (rc != 0) { 259 error_setg(errp, QERR_SET_PASSWD_FAILED); 260 } 261 return; 262 } 263 264 if (strcmp(protocol, "vnc") == 0) { 265 rc = vnc_display_pw_expire(NULL, when); 266 if (rc != 0) { 267 error_setg(errp, QERR_SET_PASSWD_FAILED); 268 } 269 return; 270 } 271 272 error_setg(errp, QERR_INVALID_PARAMETER, "protocol"); 273 } 274 275 #ifdef CONFIG_VNC 276 void qmp_change_vnc_password(const char *password, Error **errp) 277 { 278 if (vnc_display_password(NULL, password) < 0) { 279 error_setg(errp, QERR_SET_PASSWD_FAILED); 280 } 281 } 282 283 static void qmp_change_vnc_listen(const char *target, Error **errp) 284 { 285 QemuOptsList *olist = qemu_find_opts("vnc"); 286 QemuOpts *opts; 287 288 if (strstr(target, "id=")) { 289 error_setg(errp, "id not supported"); 290 return; 291 } 292 293 opts = qemu_opts_find(olist, "default"); 294 if (opts) { 295 qemu_opts_del(opts); 296 } 297 opts = vnc_parse(target, errp); 298 if (!opts) { 299 return; 300 } 301 302 vnc_display_open("default", errp); 303 } 304 305 static void qmp_change_vnc(const char *target, bool has_arg, const char *arg, 306 Error **errp) 307 { 308 if (strcmp(target, "passwd") == 0 || strcmp(target, "password") == 0) { 309 if (!has_arg) { 310 error_setg(errp, QERR_MISSING_PARAMETER, "password"); 311 } else { 312 qmp_change_vnc_password(arg, errp); 313 } 314 } else { 315 qmp_change_vnc_listen(target, errp); 316 } 317 } 318 #endif /* !CONFIG_VNC */ 319 320 void qmp_change(const char *device, const char *target, 321 bool has_arg, const char *arg, Error **errp) 322 { 323 if (strcmp(device, "vnc") == 0) { 324 #ifdef CONFIG_VNC 325 qmp_change_vnc(target, has_arg, arg, errp); 326 #else 327 error_setg(errp, QERR_FEATURE_DISABLED, "vnc"); 328 #endif 329 } else { 330 qmp_blockdev_change_medium(true, device, false, NULL, target, 331 has_arg, arg, false, 0, errp); 332 } 333 } 334 335 void qmp_add_client(const char *protocol, const char *fdname, 336 bool has_skipauth, bool skipauth, bool has_tls, bool tls, 337 Error **errp) 338 { 339 Chardev *s; 340 int fd; 341 342 fd = monitor_get_fd(cur_mon, fdname, errp); 343 if (fd < 0) { 344 return; 345 } 346 347 if (strcmp(protocol, "spice") == 0) { 348 if (!qemu_using_spice(errp)) { 349 close(fd); 350 return; 351 } 352 skipauth = has_skipauth ? skipauth : false; 353 tls = has_tls ? tls : false; 354 if (qemu_spice_display_add_client(fd, skipauth, tls) < 0) { 355 error_setg(errp, "spice failed to add client"); 356 close(fd); 357 } 358 return; 359 #ifdef CONFIG_VNC 360 } else if (strcmp(protocol, "vnc") == 0) { 361 skipauth = has_skipauth ? skipauth : false; 362 vnc_display_add_client(NULL, fd, skipauth); 363 return; 364 #endif 365 } else if ((s = qemu_chr_find(protocol)) != NULL) { 366 if (qemu_chr_add_client(s, fd) < 0) { 367 error_setg(errp, "failed to add client"); 368 close(fd); 369 return; 370 } 371 return; 372 } 373 374 error_setg(errp, "protocol '%s' is invalid", protocol); 375 close(fd); 376 } 377 378 379 MemoryDeviceInfoList *qmp_query_memory_devices(Error **errp) 380 { 381 return qmp_memory_device_list(); 382 } 383 384 ACPIOSTInfoList *qmp_query_acpi_ospm_status(Error **errp) 385 { 386 bool ambig; 387 ACPIOSTInfoList *head = NULL; 388 ACPIOSTInfoList **prev = &head; 389 Object *obj = object_resolve_path_type("", TYPE_ACPI_DEVICE_IF, &ambig); 390 391 if (obj) { 392 AcpiDeviceIfClass *adevc = ACPI_DEVICE_IF_GET_CLASS(obj); 393 AcpiDeviceIf *adev = ACPI_DEVICE_IF(obj); 394 395 adevc->ospm_status(adev, &prev); 396 } else { 397 error_setg(errp, "command is not supported, missing ACPI device"); 398 } 399 400 return head; 401 } 402 403 MemoryInfo *qmp_query_memory_size_summary(Error **errp) 404 { 405 MemoryInfo *mem_info = g_malloc0(sizeof(MemoryInfo)); 406 407 mem_info->base_memory = ram_size; 408 409 mem_info->plugged_memory = get_plugged_memory_size(); 410 mem_info->has_plugged_memory = 411 mem_info->plugged_memory != (uint64_t)-1; 412 413 return mem_info; 414 } 415