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