X-Git-Url: https://repo.jachan.dev/qemu.git/blobdiff_plain/0bb8cacd958631655441ec1c2f7cd9644076b1ac..c9ceb3ec8a7e6dc4f74183ca7493895445b57845:/hmp.c diff --git a/hmp.c b/hmp.c index 20f5daba5e..056bf70cf1 100644 --- a/hmp.c +++ b/hmp.c @@ -17,7 +17,7 @@ #include "hmp.h" #include "net/net.h" #include "net/eth.h" -#include "sysemu/char.h" +#include "chardev/char.h" #include "sysemu/block-backend.h" #include "sysemu/sysemu.h" #include "qemu/config-file.h" @@ -31,7 +31,6 @@ #include "qapi/qmp/qerror.h" #include "qapi/string-input-visitor.h" #include "qapi/string-output-visitor.h" -#include "qapi/util.h" #include "qapi-visit.h" #include "qom/object_interfaces.h" #include "ui/console.h" @@ -42,6 +41,8 @@ #include "qemu/error-report.h" #include "exec/ramlist.h" #include "hw/intc/intc.h" +#include "migration/snapshot.h" +#include "migration/misc.h" #ifdef CONFIG_SPICE #include @@ -105,7 +106,7 @@ void hmp_info_status(Monitor *mon, const QDict *qdict) info->singlestep ? " (single step mode)" : ""); if (!info->running && info->status != RUN_STATE_PAUSED) { - monitor_printf(mon, " (%s)", RunState_lookup[info->status]); + monitor_printf(mon, " (%s)", RunState_str(info->status)); } monitor_printf(mon, "\n"); @@ -163,12 +164,14 @@ void hmp_info_migrate(Monitor *mon, const QDict *qdict) info = qmp_query_migrate(NULL); caps = qmp_query_migrate_capabilities(NULL); + migration_global_dump(mon); + /* do not display parameters during setup */ if (info->has_status && caps) { monitor_printf(mon, "capabilities: "); for (cap = caps; cap; cap = cap->next) { monitor_printf(mon, "%s: %s ", - MigrationCapability_lookup[cap->value->capability], + MigrationCapability_str(cap->value->capability), cap->value->state ? "on" : "off"); } monitor_printf(mon, "\n"); @@ -176,7 +179,7 @@ void hmp_info_migrate(Monitor *mon, const QDict *qdict) if (info->has_status) { monitor_printf(mon, "Migration status: %s", - MigrationStatus_lookup[info->status]); + MigrationStatus_str(info->status)); if (info->status == MIGRATION_STATUS_FAILED && info->has_error_desc) { monitor_printf(mon, " (%s)\n", info->error_desc); @@ -274,7 +277,7 @@ void hmp_info_migrate_capabilities(Monitor *mon, const QDict *qdict) if (caps) { for (cap = caps; cap; cap = cap->next) { monitor_printf(mon, "%s: %s\n", - MigrationCapability_lookup[cap->value->capability], + MigrationCapability_str(cap->value->capability), cap->value->state ? "on" : "off"); } } @@ -290,47 +293,58 @@ void hmp_info_migrate_parameters(Monitor *mon, const QDict *qdict) if (params) { assert(params->has_compress_level); - monitor_printf(mon, "%s: %" PRId64 "\n", - MigrationParameter_lookup[MIGRATION_PARAMETER_COMPRESS_LEVEL], + monitor_printf(mon, "%s: %u\n", + MigrationParameter_str(MIGRATION_PARAMETER_COMPRESS_LEVEL), params->compress_level); assert(params->has_compress_threads); - monitor_printf(mon, "%s: %" PRId64 "\n", - MigrationParameter_lookup[MIGRATION_PARAMETER_COMPRESS_THREADS], + monitor_printf(mon, "%s: %u\n", + MigrationParameter_str(MIGRATION_PARAMETER_COMPRESS_THREADS), params->compress_threads); assert(params->has_decompress_threads); - monitor_printf(mon, "%s: %" PRId64 "\n", - MigrationParameter_lookup[MIGRATION_PARAMETER_DECOMPRESS_THREADS], + monitor_printf(mon, "%s: %u\n", + MigrationParameter_str(MIGRATION_PARAMETER_DECOMPRESS_THREADS), params->decompress_threads); assert(params->has_cpu_throttle_initial); - monitor_printf(mon, "%s: %" PRId64 "\n", - MigrationParameter_lookup[MIGRATION_PARAMETER_CPU_THROTTLE_INITIAL], + monitor_printf(mon, "%s: %u\n", + MigrationParameter_str(MIGRATION_PARAMETER_CPU_THROTTLE_INITIAL), params->cpu_throttle_initial); assert(params->has_cpu_throttle_increment); - monitor_printf(mon, "%s: %" PRId64 "\n", - MigrationParameter_lookup[MIGRATION_PARAMETER_CPU_THROTTLE_INCREMENT], + monitor_printf(mon, "%s: %u\n", + MigrationParameter_str(MIGRATION_PARAMETER_CPU_THROTTLE_INCREMENT), params->cpu_throttle_increment); + assert(params->has_tls_creds); monitor_printf(mon, "%s: '%s'\n", - MigrationParameter_lookup[MIGRATION_PARAMETER_TLS_CREDS], - params->has_tls_creds ? params->tls_creds : ""); + MigrationParameter_str(MIGRATION_PARAMETER_TLS_CREDS), + params->tls_creds); + assert(params->has_tls_hostname); monitor_printf(mon, "%s: '%s'\n", - MigrationParameter_lookup[MIGRATION_PARAMETER_TLS_HOSTNAME], - params->has_tls_hostname ? params->tls_hostname : ""); + MigrationParameter_str(MIGRATION_PARAMETER_TLS_HOSTNAME), + params->tls_hostname); assert(params->has_max_bandwidth); - monitor_printf(mon, "%s: %" PRId64 " bytes/second\n", - MigrationParameter_lookup[MIGRATION_PARAMETER_MAX_BANDWIDTH], + monitor_printf(mon, "%s: %" PRIu64 " bytes/second\n", + MigrationParameter_str(MIGRATION_PARAMETER_MAX_BANDWIDTH), params->max_bandwidth); assert(params->has_downtime_limit); - monitor_printf(mon, "%s: %" PRId64 " milliseconds\n", - MigrationParameter_lookup[MIGRATION_PARAMETER_DOWNTIME_LIMIT], + monitor_printf(mon, "%s: %" PRIu64 " milliseconds\n", + MigrationParameter_str(MIGRATION_PARAMETER_DOWNTIME_LIMIT), params->downtime_limit); assert(params->has_x_checkpoint_delay); - monitor_printf(mon, "%s: %" PRId64 "\n", - MigrationParameter_lookup[MIGRATION_PARAMETER_X_CHECKPOINT_DELAY], + monitor_printf(mon, "%s: %u\n", + MigrationParameter_str(MIGRATION_PARAMETER_X_CHECKPOINT_DELAY), params->x_checkpoint_delay); assert(params->has_block_incremental); monitor_printf(mon, "%s: %s\n", - MigrationParameter_lookup[MIGRATION_PARAMETER_BLOCK_INCREMENTAL], - params->block_incremental ? "on" : "off"); + MigrationParameter_str(MIGRATION_PARAMETER_BLOCK_INCREMENTAL), + params->block_incremental ? "on" : "off"); + monitor_printf(mon, "%s: %u\n", + MigrationParameter_str(MIGRATION_PARAMETER_X_MULTIFD_CHANNELS), + params->x_multifd_channels); + monitor_printf(mon, "%s: %u\n", + MigrationParameter_str(MIGRATION_PARAMETER_X_MULTIFD_PAGE_COUNT), + params->x_multifd_page_count); + monitor_printf(mon, "%s: %" PRIu64 "\n", + MigrationParameter_str(MIGRATION_PARAMETER_XBZRLE_CACHE_SIZE), + params->xbzrle_cache_size); } qapi_free_MigrationParameters(params); @@ -397,16 +411,16 @@ static void print_block_info(Monitor *mon, BlockInfo *info, assert(!info || !info->has_inserted || info->inserted == inserted); - if (info) { + if (info && *info->device) { monitor_printf(mon, "%s", info->device); if (inserted && inserted->has_node_name) { monitor_printf(mon, " (%s)", inserted->node_name); } } else { - assert(inserted); + assert(info || inserted); monitor_printf(mon, "%s", - inserted->has_node_name - ? inserted->node_name + inserted && inserted->has_node_name ? inserted->node_name + : info && info->has_qdev ? info->qdev : ""); } @@ -421,9 +435,12 @@ static void print_block_info(Monitor *mon, BlockInfo *info, } if (info) { + if (info->has_qdev) { + monitor_printf(mon, " Attached to: %s\n", info->qdev); + } if (info->has_io_status && info->io_status != BLOCK_DEVICE_IO_STATUS_OK) { monitor_printf(mon, " I/O status: %s\n", - BlockDeviceIoStatus_lookup[info->io_status]); + BlockDeviceIoStatus_str(info->io_status)); } if (info->removable) { @@ -453,7 +470,7 @@ static void print_block_info(Monitor *mon, BlockInfo *info, if (inserted->detect_zeroes != BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF) { monitor_printf(mon, " Detect zeroes: %s\n", - BlockdevDetectZeroesOptions_lookup[inserted->detect_zeroes]); + BlockdevDetectZeroesOptions_str(inserted->detect_zeroes)); } if (inserted->bps || inserted->bps_rd || inserted->bps_wr || @@ -596,50 +613,92 @@ void hmp_info_blockstats(Monitor *mon, const QDict *qdict) qapi_free_BlockStatsList(stats_list); } -void hmp_info_vnc(Monitor *mon, const QDict *qdict) +/* Helper for hmp_info_vnc_clients, _servers */ +static void hmp_info_VncBasicInfo(Monitor *mon, VncBasicInfo *info, + const char *name) { - VncInfo *info; - Error *err = NULL; - VncClientInfoList *client; + monitor_printf(mon, " %s: %s:%s (%s%s)\n", + name, + info->host, + info->service, + NetworkAddressFamily_str(info->family), + info->websocket ? " (Websocket)" : ""); +} - info = qmp_query_vnc(&err); - if (err) { - error_report_err(err); - return; +/* Helper displaying and auth and crypt info */ +static void hmp_info_vnc_authcrypt(Monitor *mon, const char *indent, + VncPrimaryAuth auth, + VncVencryptSubAuth *vencrypt) +{ + monitor_printf(mon, "%sAuth: %s (Sub: %s)\n", indent, + VncPrimaryAuth_str(auth), + vencrypt ? VncVencryptSubAuth_str(*vencrypt) : "none"); +} + +static void hmp_info_vnc_clients(Monitor *mon, VncClientInfoList *client) +{ + while (client) { + VncClientInfo *cinfo = client->value; + + hmp_info_VncBasicInfo(mon, qapi_VncClientInfo_base(cinfo), "Client"); + monitor_printf(mon, " x509_dname: %s\n", + cinfo->has_x509_dname ? + cinfo->x509_dname : "none"); + monitor_printf(mon, " sasl_username: %s\n", + cinfo->has_sasl_username ? + cinfo->sasl_username : "none"); + + client = client->next; } +} - if (!info->enabled) { - monitor_printf(mon, "Server: disabled\n"); - goto out; +static void hmp_info_vnc_servers(Monitor *mon, VncServerInfo2List *server) +{ + while (server) { + VncServerInfo2 *sinfo = server->value; + hmp_info_VncBasicInfo(mon, qapi_VncServerInfo2_base(sinfo), "Server"); + hmp_info_vnc_authcrypt(mon, " ", sinfo->auth, + sinfo->has_vencrypt ? &sinfo->vencrypt : NULL); + server = server->next; } +} - monitor_printf(mon, "Server:\n"); - if (info->has_host && info->has_service) { - monitor_printf(mon, " address: %s:%s\n", info->host, info->service); +void hmp_info_vnc(Monitor *mon, const QDict *qdict) +{ + VncInfo2List *info2l; + Error *err = NULL; + + info2l = qmp_query_vnc_servers(&err); + if (err) { + hmp_handle_error(mon, &err); + return; } - if (info->has_auth) { - monitor_printf(mon, " auth: %s\n", info->auth); + if (!info2l) { + monitor_printf(mon, "None\n"); + return; } - if (!info->has_clients || info->clients == NULL) { - monitor_printf(mon, "Client: none\n"); - } else { - for (client = info->clients; client; client = client->next) { - monitor_printf(mon, "Client:\n"); - monitor_printf(mon, " address: %s:%s\n", - client->value->host, - client->value->service); - monitor_printf(mon, " x509_dname: %s\n", - client->value->x509_dname ? - client->value->x509_dname : "none"); - monitor_printf(mon, " username: %s\n", - client->value->has_sasl_username ? - client->value->sasl_username : "none"); + while (info2l) { + VncInfo2 *info = info2l->value; + monitor_printf(mon, "%s:\n", info->id); + hmp_info_vnc_servers(mon, info->server); + hmp_info_vnc_clients(mon, info->clients); + if (!info->server) { + /* The server entry displays its auth, we only + * need to display in the case of 'reverse' connections + * where there's no server. + */ + hmp_info_vnc_authcrypt(mon, " ", info->auth, + info->has_vencrypt ? &info->vencrypt : NULL); + } + if (info->has_display) { + monitor_printf(mon, " Display: %s\n", info->display); } + info2l = info2l->next; } -out: - qapi_free_VncInfo(info); + qapi_free_VncInfo2List(info2l); + } #ifdef CONFIG_SPICE @@ -688,7 +747,7 @@ void hmp_info_spice(Monitor *mon, const QDict *qdict) monitor_printf(mon, " auth: %s\n", info->auth); monitor_printf(mon, " compiled: %s\n", info->compiled_version); monitor_printf(mon, " mouse-mode: %s\n", - SpiceQueryMouseMode_lookup[info->mouse_mode]); + SpiceQueryMouseMode_str(info->mouse_mode)); if (!info->has_channels || info->channels == NULL) { monitor_printf(mon, "Channels: none\n"); @@ -726,7 +785,7 @@ void hmp_info_balloon(Monitor *mon, const QDict *qdict) info = qmp_query_balloon(&err); if (err) { - error_report_err(err); + hmp_handle_error(mon, &err); return; } @@ -944,6 +1003,7 @@ void hmp_info_tpm(Monitor *mon, const QDict *qdict) Error *err = NULL; unsigned int c = 0; TPMPassthroughOptions *tpo; + TPMEmulatorOptions *teo; info_list = qmp_query_tpm(&err); if (err) { @@ -959,10 +1019,10 @@ void hmp_info_tpm(Monitor *mon, const QDict *qdict) for (info = info_list; info; info = info->next) { TPMInfo *ti = info->value; monitor_printf(mon, " tpm%d: model=%s\n", - c, TpmModel_lookup[ti->model]); + c, TpmModel_str(ti->model)); monitor_printf(mon, " \\ %s: type=%s", - ti->id, TpmTypeOptionsKind_lookup[ti->options->type]); + ti->id, TpmTypeOptionsKind_str(ti->options->type)); switch (ti->options->type) { case TPM_TYPE_OPTIONS_KIND_PASSTHROUGH: @@ -973,6 +1033,10 @@ void hmp_info_tpm(Monitor *mon, const QDict *qdict) tpo->has_cancel_path ? ",cancel-path=" : "", tpo->has_cancel_path ? tpo->cancel_path : ""); break; + case TPM_TYPE_OPTIONS_KIND_EMULATOR: + teo = ti->options->u.emulator.data; + monitor_printf(mon, ",chardev=%s", teo->chardev); + break; case TPM_TYPE_OPTIONS_KIND__MAX: break; } @@ -1064,7 +1128,7 @@ void hmp_ringbuf_read(Monitor *mon, const QDict *qdict) data = qmp_ringbuf_read(chardev, size, false, 0, &err); if (err) { - error_report_err(err); + hmp_handle_error(mon, &err); return; } @@ -1084,37 +1148,12 @@ void hmp_ringbuf_read(Monitor *mon, const QDict *qdict) g_free(data); } -static void hmp_cont_cb(void *opaque, int err) -{ - if (!err) { - qmp_cont(NULL); - } -} - -static bool key_is_missing(const BlockInfo *bdev) -{ - return (bdev->inserted && bdev->inserted->encryption_key_missing); -} - void hmp_cont(Monitor *mon, const QDict *qdict) { - BlockInfoList *bdev_list, *bdev; Error *err = NULL; - bdev_list = qmp_query_block(NULL); - for (bdev = bdev_list; bdev; bdev = bdev->next) { - if (key_is_missing(bdev->value)) { - monitor_read_block_device_key(mon, bdev->value->device, - hmp_cont_cb, NULL); - goto out; - } - } - qmp_cont(&err); hmp_handle_error(mon, &err); - -out: - qapi_free_BlockInfoList(bdev_list); } void hmp_system_wakeup(Monitor *mon, const QDict *qdict) @@ -1156,9 +1195,7 @@ void hmp_balloon(Monitor *mon, const QDict *qdict) Error *err = NULL; qmp_balloon(value, &err); - if (err) { - error_report_err(err); - } + hmp_handle_error(mon, &err); } void hmp_block_resize(Monitor *mon, const QDict *qdict) @@ -1284,7 +1321,7 @@ void hmp_loadvm(Monitor *mon, const QDict *qdict) vm_stop(RUN_STATE_RESTORE_VM); - if (load_vmstate(name, &err) == 0 && saved_vm_running) { + if (load_snapshot(name, &err) == 0 && saved_vm_running) { vm_start(); } hmp_handle_error(mon, &err); @@ -1294,7 +1331,7 @@ void hmp_savevm(Monitor *mon, const QDict *qdict) { Error *err = NULL; - save_vmstate(qdict_get_try_str(qdict, "name"), &err); + save_snapshot(qdict_get_try_str(qdict, "name"), &err); hmp_handle_error(mon, &err); } @@ -1459,6 +1496,19 @@ void hmp_migrate_cancel(Monitor *mon, const QDict *qdict) qmp_migrate_cancel(NULL); } +void hmp_migrate_continue(Monitor *mon, const QDict *qdict) +{ + Error *err = NULL; + const char *state = qdict_get_str(qdict, "state"); + int val = qapi_enum_parse(&MigrationStatus_lookup, state, -1, &err); + + if (val >= 0) { + qmp_migrate_continue(val, &err); + } + + hmp_handle_error(mon, &err); +} + void hmp_migrate_incoming(Monitor *mon, const QDict *qdict) { Error *err = NULL; @@ -1482,10 +1532,7 @@ void hmp_migrate_set_cache_size(Monitor *mon, const QDict *qdict) Error *err = NULL; qmp_migrate_set_cache_size(value, &err); - if (err) { - error_report_err(err); - return; - } + hmp_handle_error(mon, &err); } /* Kept for backwards compatibility */ @@ -1501,28 +1548,22 @@ void hmp_migrate_set_capability(Monitor *mon, const QDict *qdict) bool state = qdict_get_bool(qdict, "state"); Error *err = NULL; MigrationCapabilityStatusList *caps = g_malloc0(sizeof(*caps)); - int i; + int val; - for (i = 0; i < MIGRATION_CAPABILITY__MAX; i++) { - if (strcmp(cap, MigrationCapability_lookup[i]) == 0) { - caps->value = g_malloc0(sizeof(*caps->value)); - caps->value->capability = i; - caps->value->state = state; - caps->next = NULL; - qmp_migrate_set_capabilities(caps, &err); - break; - } + val = qapi_enum_parse(&MigrationCapability_lookup, cap, -1, &err); + if (val < 0) { + goto end; } - if (i == MIGRATION_CAPABILITY__MAX) { - error_setg(&err, QERR_INVALID_PARAMETER, cap); - } + caps->value = g_malloc0(sizeof(*caps->value)); + caps->value->capability = val; + caps->value->state = state; + caps->next = NULL; + qmp_migrate_set_capabilities(caps, &err); +end: qapi_free_MigrationCapabilityStatusList(caps); - - if (err) { - error_report_err(err); - } + hmp_handle_error(mon, &err); } void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict) @@ -1530,103 +1571,108 @@ void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict) const char *param = qdict_get_str(qdict, "parameter"); const char *valuestr = qdict_get_str(qdict, "value"); Visitor *v = string_input_visitor_new(valuestr); + MigrateSetParameters *p = g_new0(MigrateSetParameters, 1); uint64_t valuebw = 0; - int64_t valueint = 0; - bool valuebool = false; + uint64_t cache_size; Error *err = NULL; - bool use_int_value = false; - int i, ret; - - for (i = 0; i < MIGRATION_PARAMETER__MAX; i++) { - if (strcmp(param, MigrationParameter_lookup[i]) == 0) { - MigrationParameters p = { 0 }; - switch (i) { - case MIGRATION_PARAMETER_COMPRESS_LEVEL: - p.has_compress_level = true; - use_int_value = true; - break; - case MIGRATION_PARAMETER_COMPRESS_THREADS: - p.has_compress_threads = true; - use_int_value = true; - break; - case MIGRATION_PARAMETER_DECOMPRESS_THREADS: - p.has_decompress_threads = true; - use_int_value = true; - break; - case MIGRATION_PARAMETER_CPU_THROTTLE_INITIAL: - p.has_cpu_throttle_initial = true; - use_int_value = true; - break; - case MIGRATION_PARAMETER_CPU_THROTTLE_INCREMENT: - p.has_cpu_throttle_increment = true; - use_int_value = true; - break; - case MIGRATION_PARAMETER_TLS_CREDS: - p.has_tls_creds = true; - p.tls_creds = (char *) valuestr; - break; - case MIGRATION_PARAMETER_TLS_HOSTNAME: - p.has_tls_hostname = true; - p.tls_hostname = (char *) valuestr; - break; - case MIGRATION_PARAMETER_MAX_BANDWIDTH: - p.has_max_bandwidth = true; - ret = qemu_strtosz_MiB(valuestr, NULL, &valuebw); - if (ret < 0 || valuebw > INT64_MAX - || (size_t)valuebw != valuebw) { - error_setg(&err, "Invalid size %s", valuestr); - goto cleanup; - } - p.max_bandwidth = valuebw; - break; - case MIGRATION_PARAMETER_DOWNTIME_LIMIT: - p.has_downtime_limit = true; - use_int_value = true; - break; - case MIGRATION_PARAMETER_X_CHECKPOINT_DELAY: - p.has_x_checkpoint_delay = true; - use_int_value = true; - break; - case MIGRATION_PARAMETER_BLOCK_INCREMENTAL: - p.has_block_incremental = true; - visit_type_bool(v, param, &valuebool, &err); - if (err) { - goto cleanup; - } - p.block_incremental = valuebool; - break; - } - - if (use_int_value) { - visit_type_int(v, param, &valueint, &err); - if (err) { - goto cleanup; - } - /* Set all integers; only one has_FOO will be set, and - * the code ignores the remaining values */ - p.compress_level = valueint; - p.compress_threads = valueint; - p.decompress_threads = valueint; - p.cpu_throttle_initial = valueint; - p.cpu_throttle_increment = valueint; - p.downtime_limit = valueint; - p.x_checkpoint_delay = valueint; - } - - qmp_migrate_set_parameters(&p, &err); + int val, ret; + + val = qapi_enum_parse(&MigrationParameter_lookup, param, -1, &err); + if (val < 0) { + goto cleanup; + } + + switch (val) { + case MIGRATION_PARAMETER_COMPRESS_LEVEL: + p->has_compress_level = true; + visit_type_int(v, param, &p->compress_level, &err); + break; + case MIGRATION_PARAMETER_COMPRESS_THREADS: + p->has_compress_threads = true; + visit_type_int(v, param, &p->compress_threads, &err); + break; + case MIGRATION_PARAMETER_DECOMPRESS_THREADS: + p->has_decompress_threads = true; + visit_type_int(v, param, &p->decompress_threads, &err); + break; + case MIGRATION_PARAMETER_CPU_THROTTLE_INITIAL: + p->has_cpu_throttle_initial = true; + visit_type_int(v, param, &p->cpu_throttle_initial, &err); + break; + case MIGRATION_PARAMETER_CPU_THROTTLE_INCREMENT: + p->has_cpu_throttle_increment = true; + visit_type_int(v, param, &p->cpu_throttle_increment, &err); + break; + case MIGRATION_PARAMETER_TLS_CREDS: + p->has_tls_creds = true; + p->tls_creds = g_new0(StrOrNull, 1); + p->tls_creds->type = QTYPE_QSTRING; + visit_type_str(v, param, &p->tls_creds->u.s, &err); + break; + case MIGRATION_PARAMETER_TLS_HOSTNAME: + p->has_tls_hostname = true; + p->tls_hostname = g_new0(StrOrNull, 1); + p->tls_hostname->type = QTYPE_QSTRING; + visit_type_str(v, param, &p->tls_hostname->u.s, &err); + break; + case MIGRATION_PARAMETER_MAX_BANDWIDTH: + p->has_max_bandwidth = true; + /* + * Can't use visit_type_size() here, because it + * defaults to Bytes rather than Mebibytes. + */ + ret = qemu_strtosz_MiB(valuestr, NULL, &valuebw); + if (ret < 0 || valuebw > INT64_MAX + || (size_t)valuebw != valuebw) { + error_setg(&err, "Invalid size %s", valuestr); + break; + } + p->max_bandwidth = valuebw; + break; + case MIGRATION_PARAMETER_DOWNTIME_LIMIT: + p->has_downtime_limit = true; + visit_type_int(v, param, &p->downtime_limit, &err); + break; + case MIGRATION_PARAMETER_X_CHECKPOINT_DELAY: + p->has_x_checkpoint_delay = true; + visit_type_int(v, param, &p->x_checkpoint_delay, &err); + break; + case MIGRATION_PARAMETER_BLOCK_INCREMENTAL: + p->has_block_incremental = true; + visit_type_bool(v, param, &p->block_incremental, &err); + break; + case MIGRATION_PARAMETER_X_MULTIFD_CHANNELS: + p->has_x_multifd_channels = true; + visit_type_int(v, param, &p->x_multifd_channels, &err); + break; + case MIGRATION_PARAMETER_X_MULTIFD_PAGE_COUNT: + p->has_x_multifd_page_count = true; + visit_type_int(v, param, &p->x_multifd_page_count, &err); + break; + case MIGRATION_PARAMETER_XBZRLE_CACHE_SIZE: + p->has_xbzrle_cache_size = true; + visit_type_size(v, param, &cache_size, &err); + if (err || cache_size > INT64_MAX + || (size_t)cache_size != cache_size) { + error_setg(&err, "Invalid size %s", valuestr); break; } + p->xbzrle_cache_size = cache_size; + break; + default: + assert(0); } - if (i == MIGRATION_PARAMETER__MAX) { - error_setg(&err, QERR_INVALID_PARAMETER, param); + if (err) { + goto cleanup; } + qmp_migrate_set_parameters(p, &err); + cleanup: + qapi_free_MigrateSetParameters(p); visit_free(v); - if (err) { - error_report_err(err); - } + hmp_handle_error(mon, &err); } void hmp_client_migrate_info(Monitor *mon, const QDict *qdict) @@ -1725,8 +1771,8 @@ void hmp_change(Monitor *mon, const QDict *qdict) } else { if (read_only) { read_only_mode = - qapi_enum_parse(BlockdevChangeReadOnlyMode_lookup, - read_only, BLOCKDEV_CHANGE_READ_ONLY_MODE__MAX, + qapi_enum_parse(&BlockdevChangeReadOnlyMode_lookup, + read_only, BLOCKDEV_CHANGE_READ_ONLY_MODE_RETAIN, &err); if (err) { hmp_handle_error(mon, &err); @@ -1737,12 +1783,6 @@ void hmp_change(Monitor *mon, const QDict *qdict) qmp_blockdev_change_medium(true, device, false, NULL, target, !!arg, arg, !!read_only, read_only_mode, &err); - if (err && - error_get_class(err) == ERROR_CLASS_DEVICE_ENCRYPTED) { - error_free(err); - monitor_read_block_device_key(mon, device, NULL, NULL); - return; - } } hmp_handle_error(mon, &err); @@ -1886,7 +1926,7 @@ void hmp_migrate(Monitor *mon, const QDict *qdict) qmp_migrate(uri, !!blk, blk, !!inc, inc, false, false, &err); if (err) { - error_report_err(err); + hmp_handle_error(mon, &err); return; } @@ -2224,6 +2264,40 @@ void hmp_chardev_add(Monitor *mon, const QDict *qdict) hmp_handle_error(mon, &err); } +void hmp_chardev_change(Monitor *mon, const QDict *qdict) +{ + const char *args = qdict_get_str(qdict, "args"); + const char *id; + Error *err = NULL; + ChardevBackend *backend = NULL; + ChardevReturn *ret = NULL; + QemuOpts *opts = qemu_opts_parse_noisily(qemu_find_opts("chardev"), args, + true); + if (!opts) { + error_setg(&err, "Parsing chardev args failed"); + goto end; + } + + id = qdict_get_str(qdict, "id"); + if (qemu_opts_id(opts)) { + error_setg(&err, "Unexpected 'id' parameter"); + goto end; + } + + backend = qemu_chr_parse_opts(opts, &err); + if (!backend) { + goto end; + } + + ret = qmp_chardev_change(id, backend, &err); + +end: + qapi_free_ChardevReturn(ret); + qapi_free_ChardevBackend(backend); + qemu_opts_del(opts); + hmp_handle_error(mon, &err); +} + void hmp_chardev_remove(Monitor *mon, const QDict *qdict) { Error *local_err = NULL; @@ -2232,11 +2306,18 @@ void hmp_chardev_remove(Monitor *mon, const QDict *qdict) hmp_handle_error(mon, &local_err); } +void hmp_chardev_send_break(Monitor *mon, const QDict *qdict) +{ + Error *local_err = NULL; + + qmp_chardev_send_break(qdict_get_str(qdict, "id"), &local_err); + hmp_handle_error(mon, &local_err); +} + void hmp_qemu_io(Monitor *mon, const QDict *qdict) { BlockBackend *blk; BlockBackend *local_blk = NULL; - AioContext *aio_context; const char* device = qdict_get_str(qdict, "device"); const char* command = qdict_get_str(qdict, "command"); Error *err = NULL; @@ -2256,9 +2337,6 @@ void hmp_qemu_io(Monitor *mon, const QDict *qdict) } } - aio_context = blk_get_aio_context(blk); - aio_context_acquire(aio_context); - /* * Notably absent: Proper permission management. This is sad, but it seems * almost impossible to achieve without changing the semantics and thereby @@ -2286,8 +2364,6 @@ void hmp_qemu_io(Monitor *mon, const QDict *qdict) */ qemuio_command(blk, command); - aio_context_release(aio_context); - fail: blk_unref(local_blk); hmp_handle_error(mon, &err); @@ -2322,7 +2398,7 @@ void hmp_info_memdev(Monitor *mon, const QDict *qdict) monitor_printf(mon, " prealloc: %s\n", m->value->prealloc ? "true" : "false"); monitor_printf(mon, " policy: %s\n", - HostMemPolicy_lookup[m->value->policy]); + HostMemPolicy_str(m->value->policy)); visit_complete(v, &str); monitor_printf(mon, " host nodes: %s\n", str); @@ -2334,6 +2410,7 @@ void hmp_info_memdev(Monitor *mon, const QDict *qdict) monitor_printf(mon, "\n"); qapi_free_MemdevList(memdev_list); + hmp_handle_error(mon, &err); } void hmp_info_memory_devices(Monitor *mon, const QDict *qdict) @@ -2353,7 +2430,7 @@ void hmp_info_memory_devices(Monitor *mon, const QDict *qdict) di = value->u.dimm.data; monitor_printf(mon, "Memory device [%s]: \"%s\"\n", - MemoryDeviceInfoKind_lookup[value->type], + MemoryDeviceInfoKind_str(value->type), di->id ? di->id : ""); monitor_printf(mon, " addr: 0x%" PRIx64 "\n", di->addr); monitor_printf(mon, " slot: %" PRId64 "\n", di->slot); @@ -2372,6 +2449,7 @@ void hmp_info_memory_devices(Monitor *mon, const QDict *qdict) } qapi_free_MemoryDeviceInfoList(info_list); + hmp_handle_error(mon, &err); } void hmp_info_iothreads(Monitor *mon, const QDict *qdict) @@ -2747,7 +2825,7 @@ void hmp_info_dump(Monitor *mon, const QDict *qdict) DumpQueryResult *result = qmp_query_dump(NULL); assert(result && result->status < DUMP_STATUS__MAX); - monitor_printf(mon, "Status: %s\n", DumpStatus_lookup[result->status]); + monitor_printf(mon, "Status: %s\n", DumpStatus_str(result->status)); if (result->status == DUMP_STATUS_ACTIVE) { float percent = 0; @@ -2816,3 +2894,21 @@ void hmp_info_vm_generation_id(Monitor *mon, const QDict *qdict) hmp_handle_error(mon, &err); qapi_free_GuidInfo(info); } + +void hmp_info_memory_size_summary(Monitor *mon, const QDict *qdict) +{ + Error *err = NULL; + MemoryInfo *info = qmp_query_memory_size_summary(&err); + if (info) { + monitor_printf(mon, "base memory: %" PRIu64 "\n", + info->base_memory); + + if (info->has_plugged_memory) { + monitor_printf(mon, "plugged memory: %" PRIu64 "\n", + info->plugged_memory); + } + + qapi_free_MemoryInfo(info); + } + hmp_handle_error(mon, &err); +}