The hmp_info_migrate_parameters function currently open-codes the mon_printf calls for each migration parameter. As with the set command in the last patch, this should not be necessary as the QAPI infrastructure already has generated code that takes type and struct member names into account, including converting _ from C into the '-' character as part of parameter names strings.
The current code is also quite painful to rebase if a series has been carried for a long time while parameters have been added in master. Replace all of this with a conversion from MigrationParameters to QDict using an output visitor and a loop over the QDict that prints per-QAPI-type formatted strings. Modelled after block/qapi.c:dump_qobject, but with some changes to keep the migration command output formatting. Note that this was not a for-free improvement, the HMP command format output was changed incompatibly in a previous patch. It doesn't output units anymore. Signed-off-by: Fabiano Rosas <[email protected]> --- migration/migration-hmp-cmds.c | 243 ++++++++++++++------------------- 1 file changed, 100 insertions(+), 143 deletions(-) diff --git a/migration/migration-hmp-cmds.c b/migration/migration-hmp-cmds.c index 089c6d4ff46..dff69650a0c 100644 --- a/migration/migration-hmp-cmds.c +++ b/migration/migration-hmp-cmds.c @@ -25,7 +25,12 @@ #include "qapi/qapi-commands-migration.h" #include "qapi/qapi-visit-migration.h" #include "qapi/qobject-input-visitor.h" +#include "qapi/qobject-output-visitor.h" +#include "qobject/qbool.h" #include "qobject/qdict.h" +#include "qobject/qjson.h" +#include "qobject/qlist.h" +#include "qobject/qnum.h" #include "qobject/qstring.h" #include "qapi/string-input-visitor.h" #include "qapi/string-output-visitor.h" @@ -316,170 +321,122 @@ void hmp_info_migrate_capabilities(Monitor *mon, const QDict *qdict) qapi_free_MigrationCapabilityStatusList(caps); } -static void monitor_print_cpr_exec_command(Monitor *mon, strList *args) +static QDict *migrate_params_to_dict(MigrationParameters *p, Error **errp) { - monitor_printf(mon, "%s:", - MigrationParameter_str(MIGRATION_PARAMETER_CPR_EXEC_COMMAND)); + QObject *obj = NULL; + Visitor *v = qobject_output_visitor_new(&obj); - while (args) { - monitor_printf(mon, " %s", args->value); - args = args->next; + if (visit_type_MigrationParameters(v, NULL, &p, errp)) { + visit_complete(v, &obj); } - monitor_printf(mon, "\n"); + visit_free(v); + return qobject_to(QDict, obj); } -void hmp_info_migrate_parameters(Monitor *mon, const QDict *qdict) +static void hmp_migrate_print_qobject(Monitor *mon, const char *label, + QObject *obj) { - MigrationParameters *params; - MigrationState *s = migrate_get_current(); + const char *sep; - params = qmp_query_migrate_parameters(NULL); + if (!obj) { + return; + } - if (params) { - monitor_printf(mon, "%s: %" PRIu64 "\n", - MigrationParameter_str(MIGRATION_PARAMETER_ANNOUNCE_INITIAL), - params->announce_initial); - monitor_printf(mon, "%s: %" PRIu64 "\n", - MigrationParameter_str(MIGRATION_PARAMETER_ANNOUNCE_MAX), - params->announce_max); - monitor_printf(mon, "%s: %" PRIu64 "\n", - MigrationParameter_str(MIGRATION_PARAMETER_ANNOUNCE_ROUNDS), - params->announce_rounds); - monitor_printf(mon, "%s: %" PRIu64 "\n", - MigrationParameter_str(MIGRATION_PARAMETER_ANNOUNCE_STEP), - params->announce_step); - assert(params->has_throttle_trigger_threshold); - monitor_printf(mon, "%s: %u\n", - MigrationParameter_str(MIGRATION_PARAMETER_THROTTLE_TRIGGER_THRESHOLD), - params->throttle_trigger_threshold); - assert(params->has_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: %u\n", - MigrationParameter_str(MIGRATION_PARAMETER_CPU_THROTTLE_INCREMENT), - params->cpu_throttle_increment); - assert(params->has_cpu_throttle_tailslow); - monitor_printf(mon, "%s: %s\n", - MigrationParameter_str(MIGRATION_PARAMETER_CPU_THROTTLE_TAILSLOW), - params->cpu_throttle_tailslow ? "on" : "off"); - assert(params->has_max_cpu_throttle); - monitor_printf(mon, "%s: %u\n", - MigrationParameter_str(MIGRATION_PARAMETER_MAX_CPU_THROTTLE), - params->max_cpu_throttle); - assert(params->tls_creds); - monitor_printf(mon, "%s: %s\n", - MigrationParameter_str(MIGRATION_PARAMETER_TLS_CREDS), - params->tls_creds->u.s); - assert(params->tls_hostname); - monitor_printf(mon, "%s: %s\n", - MigrationParameter_str(MIGRATION_PARAMETER_TLS_HOSTNAME), - params->tls_hostname->u.s); - assert(params->tls_authz); - monitor_printf(mon, "%s: %s\n", - MigrationParameter_str(MIGRATION_PARAMETER_TLS_AUTHZ), - params->tls_authz->u.s); - assert(params->has_max_bandwidth); - monitor_printf(mon, "%s: %" PRIu64 "\n", - MigrationParameter_str(MIGRATION_PARAMETER_MAX_BANDWIDTH), - params->max_bandwidth); - assert(params->has_avail_switchover_bandwidth); - monitor_printf(mon, "%s: %" PRIu64 "\n", - MigrationParameter_str(MIGRATION_PARAMETER_AVAIL_SWITCHOVER_BANDWIDTH), - params->avail_switchover_bandwidth); - assert(params->has_max_postcopy_bandwidth); - monitor_printf(mon, "%s: %" PRIu64 "\n", - MigrationParameter_str(MIGRATION_PARAMETER_MAX_POSTCOPY_BANDWIDTH), - params->max_postcopy_bandwidth); - assert(params->has_downtime_limit); - monitor_printf(mon, "%s: %" PRIu64 "\n", - MigrationParameter_str(MIGRATION_PARAMETER_DOWNTIME_LIMIT), - params->downtime_limit); - assert(params->has_x_checkpoint_delay); - monitor_printf(mon, "%s: %u\n", - MigrationParameter_str(MIGRATION_PARAMETER_X_CHECKPOINT_DELAY), - params->x_checkpoint_delay); - monitor_printf(mon, "%s: %u\n", - MigrationParameter_str(MIGRATION_PARAMETER_MULTIFD_CHANNELS), - params->multifd_channels); - monitor_printf(mon, "%s: %s\n", - MigrationParameter_str(MIGRATION_PARAMETER_MULTIFD_COMPRESSION), - MultiFDCompression_str(params->multifd_compression)); - assert(params->has_zero_page_detection); - monitor_printf(mon, "%s: %s\n", - MigrationParameter_str(MIGRATION_PARAMETER_ZERO_PAGE_DETECTION), - qapi_enum_lookup(&ZeroPageDetection_lookup, - params->zero_page_detection)); - monitor_printf(mon, "%s: %" PRIu64 "\n", - MigrationParameter_str(MIGRATION_PARAMETER_XBZRLE_CACHE_SIZE), - params->xbzrle_cache_size); + /* + * Put a space after labels + * foo: bar + * ^ + */ + if (label && label[0] && label[strlen(label) - 1] == ':') { + sep = " "; + } else { + sep = ""; + } - if (s->has_block_bitmap_mapping) { - BitmapMigrationNodeAliasList *nal; - BitmapMigrationNodeAlias *na; - BitmapMigrationBitmapAliasList *bal; - BitmapMigrationBitmapAlias *ba; - BitmapMigrationBitmapAliasTransform *bat; + switch (qobject_type(obj)) { + case QTYPE_NONE: + g_assert_not_reached(); + case QTYPE_QNULL: + break; + case QTYPE_QNUM: { + int64_t i64; - monitor_printf(mon, "%s:", - MigrationParameter_str( - MIGRATION_PARAMETER_BLOCK_BITMAP_MAPPING)); + if (qnum_get_try_int(qobject_to(QNum, obj), &i64)) { + monitor_printf(mon, "%s%s%" PRId64, label, sep, i64); + } + break; + } + case QTYPE_QSTRING: { + QString *str = qobject_to(QString, obj); - for (nal = params->block_bitmap_mapping; nal; nal = nal->next) - { - na = nal->value; - monitor_printf(mon, " bitmaps:"); - for (bal = na->bitmaps; bal; bal = bal->next) { - ba = bal->value; - bat = ba->transform; + if (str) { + monitor_printf(mon, "%s%s%s", label, sep, qstring_get_str(str)); + } + break; + } + case QTYPE_QDICT: { + QDict *d = qobject_to(QDict, obj); + const QDictEntry *e; + int i = 0; - monitor_printf(mon, " name: %s", ba->name); - if (bat && bat->has_persistent) { - if (bat->persistent) { - monitor_printf(mon, " persistent: on"); - } else { - monitor_printf(mon, " persistent: off"); - } - } - monitor_printf(mon, " alias: %s", ba->alias); + if (d) { + for (e = qdict_first(d); e; e = qdict_next(d, e), i++) { + g_autofree char *l = g_strdup_printf("%s:", qdict_entry_key(e)); + if (i) { + monitor_printf(mon, " "); } - monitor_printf(mon, " node-name: %s alias: %s", - na->node_name, na->alias); + hmp_migrate_print_qobject(mon, l, qdict_entry_value(e)); } - - monitor_printf(mon, "\n"); } + break; + } + case QTYPE_QLIST: { + QList *l = qobject_to(QList, obj); + const QListEntry *e; - monitor_printf(mon, "%s: %" PRIu64 "\n", - MigrationParameter_str(MIGRATION_PARAMETER_X_VCPU_DIRTY_LIMIT_PERIOD), - params->x_vcpu_dirty_limit_period); + if (l) { + monitor_printf(mon, "%s", label); - monitor_printf(mon, "%s: %" PRIu64 "\n", - MigrationParameter_str(MIGRATION_PARAMETER_VCPU_DIRTY_LIMIT), - params->vcpu_dirty_limit); + for (e = qlist_first(l); e; e = qlist_next(e)) { + /* + * In the first iteration, this is the space after the + * colon, otherwise it's the space between list + * elements. + */ + monitor_printf(mon, " "); + hmp_migrate_print_qobject(mon, "", e->value); + } + } + break; + } + case QTYPE_QBOOL: { + QBool *b = qobject_to(QBool, obj); + if (b) { + monitor_printf(mon, "%s%s%s", label, sep, + qbool_get_bool(b) ? "on" : "off"); + } + break; + } + default: + g_assert_not_reached(); + break; + } +} - assert(params->has_mode); - monitor_printf(mon, "%s: %s\n", - MigrationParameter_str(MIGRATION_PARAMETER_MODE), - qapi_enum_lookup(&MigMode_lookup, params->mode)); +void hmp_info_migrate_parameters(Monitor *mon, const QDict *qdict) +{ + MigrationParameters *params = qmp_query_migrate_parameters(NULL); + g_autoptr(QDict) d; + const QDictEntry *e; - if (params->has_direct_io) { - monitor_printf(mon, "%s: %s\n", - MigrationParameter_str( - MIGRATION_PARAMETER_DIRECT_IO), - params->direct_io ? "on" : "off"); - } + assert(params); - if (params->has_x_rdma_chunk_size) { - monitor_printf(mon, "%s: %" PRIu64 "\n", - MigrationParameter_str( - MIGRATION_PARAMETER_X_RDMA_CHUNK_SIZE), - params->x_rdma_chunk_size); - } + d = migrate_params_to_dict(params, NULL); + for (e = qdict_first(d); e; e = qdict_next(d, e)) { + g_autofree char *label = g_strdup_printf("%s:", qdict_entry_key(e)); - assert(params->has_cpr_exec_command); - monitor_print_cpr_exec_command(mon, params->cpr_exec_command); + hmp_migrate_print_qobject(mon, label, qdict_entry_value(e)); + monitor_printf(mon, "\n"); } qapi_free_MigrationParameters(params); -- 2.53.0
