X-Git-Url: https://repo.jachan.dev/qemu.git/blobdiff_plain/a2aa09e18186801931763fbd40a751fa39971b18..86ae191163d48ff4ff9d9996868e6cfe92a82449:/hmp.c diff --git a/hmp.c b/hmp.c index 3f807b75f1..c6419da72f 100644 --- a/hmp.c +++ b/hmp.c @@ -13,6 +13,7 @@ * GNU GPL, version 2 or (at your option) any later version. */ +#include "qemu/osdep.h" #include "hmp.h" #include "net/net.h" #include "net/eth.h" @@ -27,6 +28,7 @@ #include "qapi/opts-visitor.h" #include "qapi/qmp/qerror.h" #include "qapi/string-output-visitor.h" +#include "qapi/util.h" #include "qapi-visit.h" #include "ui/console.h" #include "block/qapi.h" @@ -40,8 +42,7 @@ static void hmp_handle_error(Monitor *mon, Error **errp) { assert(errp); if (*errp) { - monitor_printf(mon, "%s\n", error_get_pretty(*errp)); - error_free(*errp); + error_report_err(*errp); } } @@ -232,6 +233,11 @@ void hmp_info_migrate(Monitor *mon, const QDict *qdict) info->xbzrle_cache->overflow); } + if (info->has_x_cpu_throttle_percentage) { + monitor_printf(mon, "cpu throttle percentage: %" PRIu64 "\n", + info->x_cpu_throttle_percentage); + } + qapi_free_MigrationInfo(info); qapi_free_MigrationCapabilityStatusList(caps); } @@ -272,6 +278,12 @@ void hmp_info_migrate_parameters(Monitor *mon, const QDict *qdict) monitor_printf(mon, " %s: %" PRId64, MigrationParameter_lookup[MIGRATION_PARAMETER_DECOMPRESS_THREADS], params->decompress_threads); + monitor_printf(mon, " %s: %" PRId64, + MigrationParameter_lookup[MIGRATION_PARAMETER_X_CPU_THROTTLE_INITIAL], + params->x_cpu_throttle_initial); + monitor_printf(mon, " %s: %" PRId64, + MigrationParameter_lookup[MIGRATION_PARAMETER_X_CPU_THROTTLE_INCREMENT], + params->x_cpu_throttle_increment); monitor_printf(mon, "\n"); } @@ -299,17 +311,27 @@ void hmp_info_cpus(Monitor *mon, const QDict *qdict) monitor_printf(mon, "%c CPU #%" PRId64 ":", active, cpu->value->CPU); - if (cpu->value->has_pc) { - monitor_printf(mon, " pc=0x%016" PRIx64, cpu->value->pc); - } - if (cpu->value->has_nip) { - monitor_printf(mon, " nip=0x%016" PRIx64, cpu->value->nip); - } - if (cpu->value->has_npc) { - monitor_printf(mon, " npc=0x%016" PRIx64, cpu->value->npc); - } - if (cpu->value->has_PC) { - monitor_printf(mon, " PC=0x%016" PRIx64, cpu->value->PC); + switch (cpu->value->arch) { + case CPU_INFO_ARCH_X86: + monitor_printf(mon, " pc=0x%016" PRIx64, cpu->value->u.x86->pc); + break; + case CPU_INFO_ARCH_PPC: + monitor_printf(mon, " nip=0x%016" PRIx64, cpu->value->u.ppc->nip); + break; + case CPU_INFO_ARCH_SPARC: + monitor_printf(mon, " pc=0x%016" PRIx64, + cpu->value->u.q_sparc->pc); + monitor_printf(mon, " npc=0x%016" PRIx64, + cpu->value->u.q_sparc->npc); + break; + case CPU_INFO_ARCH_MIPS: + monitor_printf(mon, " PC=0x%016" PRIx64, cpu->value->u.q_mips->PC); + break; + case CPU_INFO_ARCH_TRICORE: + monitor_printf(mon, " PC=0x%016" PRIx64, cpu->value->u.tricore->PC); + break; + default: + break; } if (cpu->value->halted) { @@ -510,6 +532,7 @@ void hmp_info_blockstats(Monitor *mon, const QDict *qdict) " flush_total_time_ns=%" PRId64 " rd_merged=%" PRId64 " wr_merged=%" PRId64 + " idle_time_ns=%" PRId64 "\n", stats->value->stats->rd_bytes, stats->value->stats->wr_bytes, @@ -520,7 +543,8 @@ void hmp_info_blockstats(Monitor *mon, const QDict *qdict) stats->value->stats->rd_total_time_ns, stats->value->stats->flush_total_time_ns, stats->value->stats->rd_merged, - stats->value->stats->wr_merged); + stats->value->stats->wr_merged, + stats->value->stats->idle_time_ns); } qapi_free_BlockStatsList(stats_list); @@ -534,8 +558,7 @@ void hmp_info_vnc(Monitor *mon, const QDict *qdict) info = qmp_query_vnc(&err); if (err) { - monitor_printf(mon, "%s\n", error_get_pretty(err)); - error_free(err); + error_report_err(err); return; } @@ -558,8 +581,8 @@ void hmp_info_vnc(Monitor *mon, const QDict *qdict) for (client = info->clients; client; client = client->next) { monitor_printf(mon, "Client:\n"); monitor_printf(mon, " address: %s:%s\n", - client->value->base->host, - client->value->base->service); + client->value->host, + client->value->service); monitor_printf(mon, " x509_dname: %s\n", client->value->x509_dname ? client->value->x509_dname : "none"); @@ -627,7 +650,7 @@ void hmp_info_spice(Monitor *mon, const QDict *qdict) for (chan = info->channels; chan; chan = chan->next) { monitor_printf(mon, "Channel:\n"); monitor_printf(mon, " address: %s:%s%s\n", - chan->value->base->host, chan->value->base->port, + chan->value->host, chan->value->port, chan->value->tls ? " [tls]" : ""); monitor_printf(mon, " session: %" PRId64 "\n", chan->value->connection_id); @@ -657,8 +680,7 @@ void hmp_info_balloon(Monitor *mon, const QDict *qdict) info = qmp_query_balloon(&err); if (err) { - monitor_printf(mon, "%s\n", error_get_pretty(err)); - error_free(err); + error_report_err(err); return; } @@ -830,18 +852,18 @@ void hmp_info_tpm(Monitor *mon, const QDict *qdict) c, TpmModel_lookup[ti->model]); monitor_printf(mon, " \\ %s: type=%s", - ti->id, TpmTypeOptionsKind_lookup[ti->options->kind]); + ti->id, TpmTypeOptionsKind_lookup[ti->options->type]); - switch (ti->options->kind) { + switch (ti->options->type) { case TPM_TYPE_OPTIONS_KIND_PASSTHROUGH: - tpo = ti->options->passthrough; + tpo = ti->options->u.passthrough; monitor_printf(mon, "%s%s%s%s", tpo->has_path ? ",path=" : "", tpo->has_path ? tpo->path : "", tpo->has_cancel_path ? ",cancel-path=" : "", tpo->has_cancel_path ? tpo->cancel_path : ""); break; - case TPM_TYPE_OPTIONS_KIND_MAX: + case TPM_TYPE_OPTIONS_KIND__MAX: break; } monitor_printf(mon, "\n"); @@ -926,8 +948,7 @@ void hmp_ringbuf_read(Monitor *mon, const QDict *qdict) data = qmp_ringbuf_read(chardev, size, false, 0, &err); if (err) { - monitor_printf(mon, "%s\n", error_get_pretty(err)); - error_free(err); + error_report_err(err); return; } @@ -1020,8 +1041,7 @@ void hmp_balloon(Monitor *mon, const QDict *qdict) qmp_balloon(value, &err); if (err) { - monitor_printf(mon, "balloon: %s\n", error_get_pretty(err)); - error_free(err); + error_report_err(err); } } @@ -1169,8 +1189,7 @@ void hmp_migrate_set_cache_size(Monitor *mon, const QDict *qdict) qmp_migrate_set_cache_size(value, &err); if (err) { - monitor_printf(mon, "%s\n", error_get_pretty(err)); - error_free(err); + error_report_err(err); return; } } @@ -1189,7 +1208,7 @@ void hmp_migrate_set_capability(Monitor *mon, const QDict *qdict) MigrationCapabilityStatusList *caps = g_malloc0(sizeof(*caps)); int i; - for (i = 0; i < MIGRATION_CAPABILITY_MAX; i++) { + 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; @@ -1200,16 +1219,14 @@ void hmp_migrate_set_capability(Monitor *mon, const QDict *qdict) } } - if (i == MIGRATION_CAPABILITY_MAX) { + if (i == MIGRATION_CAPABILITY__MAX) { error_setg(&err, QERR_INVALID_PARAMETER, cap); } qapi_free_MigrationCapabilityStatusList(caps); if (err) { - monitor_printf(mon, "migrate_set_capability: %s\n", - error_get_pretty(err)); - error_free(err); + error_report_err(err); } } @@ -1221,9 +1238,11 @@ void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict) bool has_compress_level = false; bool has_compress_threads = false; bool has_decompress_threads = false; + bool has_x_cpu_throttle_initial = false; + bool has_x_cpu_throttle_increment = false; int i; - for (i = 0; i < MIGRATION_PARAMETER_MAX; i++) { + for (i = 0; i < MIGRATION_PARAMETER__MAX; i++) { if (strcmp(param, MigrationParameter_lookup[i]) == 0) { switch (i) { case MIGRATION_PARAMETER_COMPRESS_LEVEL: @@ -1235,23 +1254,29 @@ void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict) case MIGRATION_PARAMETER_DECOMPRESS_THREADS: has_decompress_threads = true; break; + case MIGRATION_PARAMETER_X_CPU_THROTTLE_INITIAL: + has_x_cpu_throttle_initial = true; + break; + case MIGRATION_PARAMETER_X_CPU_THROTTLE_INCREMENT: + has_x_cpu_throttle_increment = true; + break; } qmp_migrate_set_parameters(has_compress_level, value, has_compress_threads, value, has_decompress_threads, value, + has_x_cpu_throttle_initial, value, + has_x_cpu_throttle_increment, value, &err); break; } } - if (i == MIGRATION_PARAMETER_MAX) { + if (i == MIGRATION_PARAMETER__MAX) { error_setg(&err, QERR_INVALID_PARAMETER, param); } if (err) { - monitor_printf(mon, "migrate_set_parameter: %s\n", - error_get_pretty(err)); - error_free(err); + error_report_err(err); } } @@ -1272,6 +1297,13 @@ void hmp_client_migrate_info(Monitor *mon, const QDict *qdict) hmp_handle_error(mon, &err); } +void hmp_migrate_start_postcopy(Monitor *mon, const QDict *qdict) +{ + Error *err = NULL; + qmp_migrate_start_postcopy(&err); + hmp_handle_error(mon, &err); +} + void hmp_set_password(Monitor *mon, const QDict *qdict) { const char *protocol = qdict_get_str(qdict, "protocol"); @@ -1315,24 +1347,46 @@ void hmp_change(Monitor *mon, const QDict *qdict) const char *device = qdict_get_str(qdict, "device"); const char *target = qdict_get_str(qdict, "target"); const char *arg = qdict_get_try_str(qdict, "arg"); + const char *read_only = qdict_get_try_str(qdict, "read-only-mode"); + BlockdevChangeReadOnlyMode read_only_mode = 0; Error *err = NULL; - if (strcmp(device, "vnc") == 0 && - (strcmp(target, "passwd") == 0 || - strcmp(target, "password") == 0)) { - if (!arg) { - monitor_read_password(mon, hmp_change_read_arg, NULL); + if (strcmp(device, "vnc") == 0) { + if (read_only) { + monitor_printf(mon, + "Parameter 'read-only-mode' is invalid for VNC\n"); return; } - } + if (strcmp(target, "passwd") == 0 || + strcmp(target, "password") == 0) { + if (!arg) { + monitor_read_password(mon, hmp_change_read_arg, NULL); + return; + } + } + qmp_change("vnc", target, !!arg, arg, &err); + } else { + if (read_only) { + read_only_mode = + qapi_enum_parse(BlockdevChangeReadOnlyMode_lookup, + read_only, BLOCKDEV_CHANGE_READ_ONLY_MODE__MAX, + BLOCKDEV_CHANGE_READ_ONLY_MODE_RETAIN, &err); + if (err) { + hmp_handle_error(mon, &err); + return; + } + } - qmp_change(device, target, !!arg, arg, &err); - if (err && - error_get_class(err) == ERROR_CLASS_DEVICE_ENCRYPTED) { - error_free(err); - monitor_read_block_device_key(mon, device, NULL, NULL); - return; + qmp_blockdev_change_medium(device, 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); } @@ -1483,8 +1537,7 @@ void hmp_migrate(Monitor *mon, const QDict *qdict) qmp_migrate(uri, !!blk, blk, !!inc, inc, false, false, &err); if (err) { - monitor_printf(mon, "migrate: %s\n", error_get_pretty(err)); - error_free(err); + error_report_err(err); return; } @@ -1606,9 +1659,9 @@ void hmp_object_add(Monitor *mon, const QDict *qdict) QemuOpts *opts; char *type = NULL; char *id = NULL; - void *dummy = NULL; OptsVisitor *ov; QDict *pdict; + Visitor *v; opts = qemu_opts_from_qdict(qemu_find_opts("object"), qdict, &err); if (err) { @@ -1617,28 +1670,29 @@ void hmp_object_add(Monitor *mon, const QDict *qdict) ov = opts_visitor_new(opts); pdict = qdict_clone_shallow(qdict); + v = opts_get_visitor(ov); - visit_start_struct(opts_get_visitor(ov), &dummy, NULL, NULL, 0, &err); + visit_start_struct(v, NULL, NULL, 0, &err); if (err) { goto out_clean; } qdict_del(pdict, "qom-type"); - visit_type_str(opts_get_visitor(ov), &type, "qom-type", &err); + visit_type_str(v, "qom-type", &type, &err); if (err) { goto out_end; } qdict_del(pdict, "id"); - visit_type_str(opts_get_visitor(ov), &id, "id", &err); + visit_type_str(v, "id", &id, &err); if (err) { goto out_end; } - object_add(type, id, pdict, opts_get_visitor(ov), &err); + object_add(type, id, pdict, v, &err); out_end: - visit_end_struct(opts_get_visitor(ov), &err_end); + visit_end_struct(v, &err_end); if (!err && err_end) { qmp_object_del(id, NULL); } @@ -1650,7 +1704,6 @@ out_clean: qemu_opts_del(opts); g_free(id); g_free(type); - g_free(dummy); out: hmp_handle_error(mon, &err); @@ -1681,21 +1734,18 @@ void hmp_sendkey(Monitor *mon, const QDict *qdict) int has_hold_time = qdict_haskey(qdict, "hold-time"); int hold_time = qdict_get_try_int(qdict, "hold-time", -1); Error *err = NULL; - char keyname_buf[16]; char *separator; int keyname_len; while (1) { separator = strchr(keys, '-'); keyname_len = separator ? separator - keys : strlen(keys); - pstrcpy(keyname_buf, sizeof(keyname_buf), keys); /* Be compatible with old interface, convert user inputted "<" */ - if (!strncmp(keyname_buf, "<", 1) && keyname_len == 1) { - pstrcpy(keyname_buf, sizeof(keyname_buf), "less"); + if (keys[0] == '<' && keyname_len == 1) { + keys = "less"; keyname_len = 4; } - keyname_buf[keyname_len] = 0; keylist = g_malloc0(sizeof(*keylist)); keylist->value = g_malloc0(sizeof(*keylist->value)); @@ -1708,21 +1758,22 @@ void hmp_sendkey(Monitor *mon, const QDict *qdict) } tmp = keylist; - if (strstart(keyname_buf, "0x", NULL)) { + if (strstart(keys, "0x", NULL)) { char *endp; - int value = strtoul(keyname_buf, &endp, 0); - if (*endp != '\0') { + int value = strtoul(keys, &endp, 0); + assert(endp <= keys + keyname_len); + if (endp != keys + keyname_len) { goto err_out; } - keylist->value->kind = KEY_VALUE_KIND_NUMBER; - keylist->value->number = value; + keylist->value->type = KEY_VALUE_KIND_NUMBER; + keylist->value->u.number = value; } else { - int idx = index_from_key(keyname_buf); - if (idx == Q_KEY_CODE_MAX) { + int idx = index_from_key(keys, keyname_len); + if (idx == Q_KEY_CODE__MAX) { goto err_out; } - keylist->value->kind = KEY_VALUE_KIND_QCODE; - keylist->value->qcode = idx; + keylist->value->type = KEY_VALUE_KIND_QCODE; + keylist->value->u.qcode = idx; } if (!separator) { @@ -1739,7 +1790,7 @@ out: return; err_out: - monitor_printf(mon, "invalid parameter: %s\n", keyname_buf); + monitor_printf(mon, "invalid parameter: %.*s\n", keyname_len, keys); goto out; } @@ -1899,8 +1950,8 @@ void hmp_info_memdev(Monitor *mon, const QDict *qdict) while (m) { ov = string_output_visitor_new(false); - visit_type_uint16List(string_output_get_visitor(ov), - &m->value->host_nodes, NULL, NULL); + visit_type_uint16List(string_output_get_visitor(ov), NULL, + &m->value->host_nodes, NULL); monitor_printf(mon, "memory backend: %d\n", i); monitor_printf(mon, " size: %" PRId64 "\n", m->value->size); monitor_printf(mon, " merge: %s\n", @@ -1937,12 +1988,12 @@ void hmp_info_memory_devices(Monitor *mon, const QDict *qdict) value = info->value; if (value) { - switch (value->kind) { + switch (value->type) { case MEMORY_DEVICE_INFO_KIND_DIMM: - di = value->dimm; + di = value->u.dimm; monitor_printf(mon, "Memory device [%s]: \"%s\"\n", - MemoryDeviceInfoKind_lookup[value->kind], + MemoryDeviceInfoKind_lookup[value->type], di->id ? di->id : ""); monitor_printf(mon, " addr: 0x%" PRIx64 "\n", di->addr); monitor_printf(mon, " slot: %" PRId64 "\n", di->slot); @@ -2028,11 +2079,11 @@ void hmp_rocker(Monitor *mon, const QDict *qdict) { const char *name = qdict_get_str(qdict, "name"); RockerSwitch *rocker; - Error *errp = NULL; + Error *err = NULL; - rocker = qmp_query_rocker(name, &errp); - if (errp != NULL) { - hmp_handle_error(mon, &errp); + rocker = qmp_query_rocker(name, &err); + if (err != NULL) { + hmp_handle_error(mon, &err); return; } @@ -2047,11 +2098,11 @@ void hmp_rocker_ports(Monitor *mon, const QDict *qdict) { RockerPortList *list, *port; const char *name = qdict_get_str(qdict, "name"); - Error *errp = NULL; + Error *err = NULL; - list = qmp_query_rocker_ports(name, &errp); - if (errp != NULL) { - hmp_handle_error(mon, &errp); + list = qmp_query_rocker_ports(name, &err); + if (err != NULL) { + hmp_handle_error(mon, &err); return; } @@ -2076,11 +2127,11 @@ void hmp_rocker_of_dpa_flows(Monitor *mon, const QDict *qdict) RockerOfDpaFlowList *list, *info; const char *name = qdict_get_str(qdict, "name"); uint32_t tbl_id = qdict_get_try_int(qdict, "tbl_id", -1); - Error *errp = NULL; + Error *err = NULL; - list = qmp_query_rocker_of_dpa_flows(name, tbl_id != -1, tbl_id, &errp); - if (errp != NULL) { - hmp_handle_error(mon, &errp); + list = qmp_query_rocker_of_dpa_flows(name, tbl_id != -1, tbl_id, &err); + if (err != NULL) { + hmp_handle_error(mon, &err); return; } @@ -2226,12 +2277,12 @@ void hmp_rocker_of_dpa_groups(Monitor *mon, const QDict *qdict) RockerOfDpaGroupList *list, *g; const char *name = qdict_get_str(qdict, "name"); uint8_t type = qdict_get_try_int(qdict, "type", 9); - Error *errp = NULL; + Error *err = NULL; bool set = false; - list = qmp_query_rocker_of_dpa_groups(name, type != 9, type, &errp); - if (errp != NULL) { - hmp_handle_error(mon, &errp); + list = qmp_query_rocker_of_dpa_groups(name, type != 9, type, &err); + if (err != NULL) { + hmp_handle_error(mon, &err); return; }