Fabiano Rosas <[email protected]> writes:

> 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.
>
> Signed-off-by: Fabiano Rosas <[email protected]>

Old output of info migrate_parameters for me:

    announce-initial: 50
    announce-max: 550
    announce-rounds: 5
    announce-step: 100
    throttle-trigger-threshold: 50
    cpu-throttle-initial: 20
    cpu-throttle-increment: 10
    cpu-throttle-tailslow: off
    max-cpu-throttle: 99
    tls-creds: 
    tls-hostname: 
    tls-authz: 
    max-bandwidth: 134217728
    avail-switchover-bandwidth: 0
    max-postcopy-bandwidth: 0
    downtime-limit: 300
    x-checkpoint-delay: 20000
    multifd-channels: 2
    multifd-compression: none
    zero-page-detection: multifd
    xbzrle-cache-size: 67108864
    x-vcpu-dirty-limit-period: 1000
    vcpu-dirty-limit: 1
    mode: normal
    direct-io: off
    x-rdma-chunk-size: 1048576
    cpr-exec-command:

New output:

    cpu-throttle-tailslow: off
    xbzrle-cache-size: 67108864
    cpu-throttle-initial: 20
    announce-max: 550
    direct-io: off
    avail-switchover-bandwidth: 0
    local: off
    zero-page-detection: multifd
    multifd-qatzip-level: 1
    x-rdma-chunk-size: 1048576
    multifd-channels: 2
    mode: normal
    multifd-zstd-level: 1
    announce-initial: 50
    downtime-limit: 300
    tls-authz: 
    cpr-exec-command:

    vcpu-dirty-limit: 1
    multifd-compression: none
    announce-rounds: 5
    announce-step: 100
    tls-creds: 
    x-vcpu-dirty-limit-period: 1000
    multifd-zlib-level: 1
    max-cpu-throttle: 99
    max-postcopy-bandwidth: 0
    tls-hostname: 
    throttle-trigger-threshold: 50
    max-bandwidth: 134217728
    x-checkpoint-delay: 20000
    cpu-throttle-increment: 10

New output has an unwanted blank line after "cpr-exec-command:".

New output adds @local, @multifd-qatzip-level, @multifd-zlib-level,
@multifd-zstd-level.  Commit message should point that out.

Order of parameters changes, and not for the better.  Hmm.

> ---
>  migration/migration-hmp-cmds.c | 234 +++++++++++----------------------
>  migration/options.c            |   2 +-
>  migration/options.h            |   1 +
>  3 files changed, 81 insertions(+), 156 deletions(-)
>
> diff --git a/migration/migration-hmp-cmds.c b/migration/migration-hmp-cmds.c
> index 7491c79a2e..00d2d310af 100644
> --- a/migration/migration-hmp-cmds.c
> +++ b/migration/migration-hmp-cmds.c
> @@ -26,8 +26,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"
> @@ -318,171 +322,91 @@ void hmp_info_migrate_capabilities(MonitorHMP *hmp, 
> const QDict *qdict)
>      qapi_free_MigrationCapabilityStatusList(caps);
>  }
>  
> -static void monitor_print_cpr_exec_command(MonitorHMP *hmp, strList *args)
> +static void hmp_migrate_print_qobject(MonitorHMP *hmp, const char *label,
> +                                      QObject *obj)
>  {
> -    monitor_hmp_printf(hmp, "%s:",
> -        MigrationParameter_str(MIGRATION_PARAMETER_CPR_EXEC_COMMAND));
> +    const char *sep;
>  
> -    while (args) {
> -        monitor_hmp_printf(hmp, " %s", args->value);
> -        args = args->next;
> +    if (!obj) {
> +        return;
> +    }
> +
> +    /*
> +     * Put a space after labels
> +     * foo: bar
> +     *     ^
> +     */
> +    if (label && label[0] && label[strlen(label) - 1] == ':') {
> +        sep = " ";
> +    } else {
> +        sep = "";
> +    }

Awkward.

Could simply we pass "foo: " instead of "foo"?  Hmm, see case
QTYPE_QLIST below.

> +
> +    switch (qobject_type(obj)) {
> +    case QTYPE_QNUM: {
> +        g_autofree char *str = qnum_to_string(qobject_to(QNum, obj));
> +
> +        monitor_hmp_printf(hmp, "%s%s%s", label, sep, str);
> +        break;
> +    }
> +    case QTYPE_QSTRING:
> +        monitor_hmp_printf(hmp, "%s%s%s", label, sep,
> +                           qstring_get_str(qobject_to(QString, obj)));
> +        break;
> +    case QTYPE_QDICT: {
> +        QDict *d = qobject_to(QDict, obj);
> +        const QDictEntry *e;
> +        int i = 0;
> +
> +        monitor_hmp_printf(hmp, "%s%s", label, sep);
> +
> +        for (e = qdict_first(d); e; e = qdict_next(d, e), i++) {

Printing members in alphabetic order would be much better.

> +            g_autofree char *l = g_strdup_printf("%s:", qdict_entry_key(e));
> +            if (i) {
> +                monitor_hmp_printf(hmp, " ");
> +            }
> +            hmp_migrate_print_qobject(hmp, l, qdict_entry_value(e));
> +        }
> +        break;
> +    }

dump_qobject() prints nested stuff indented.  This function doesn't.  I
fear the output will be confusing.  Can you show us some example output
with a non-empty QDict?

> +    case QTYPE_QLIST: {
> +        const QListEntry *e;
> +
> +        monitor_hmp_printf(hmp, "%s\n", label);

Here we print @label and not @sep.  Why?  Can you show us some example
output with a non-empty QList?

> +        for (e = qlist_first(qobject_to(QList, obj)); e; e = qlist_next(e)) {
> +            hmp_migrate_print_qobject(hmp, " ", e->value);
> +            monitor_hmp_printf(hmp, "\n");
> +        }
> +

Recommend to scratch the blank line.

> +        break;

This case's output ends with a newline, unlike the other cases.
hmp_info_migrate_parameters() adds another newline.  That's where the
unwanted blank line mentioned above comes from.
> +    }
> +    case QTYPE_QBOOL:
> +        monitor_hmp_printf(hmp, "%s%s%s", label, sep,
> +                           qbool_get_bool(qobject_to(QBool, obj)) ?
> +                           "on" : "off");
> +        break;
> +    case QTYPE_NONE:
> +    case QTYPE_QNULL:

I'd scratch these two lines.  Matter of taste.

> +    default:
> +        g_assert_not_reached();
> +        break;
>      }
> -    monitor_hmp_printf(hmp, "\n");
>  }
>  
>  void hmp_info_migrate_parameters(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    MigrationParameters *params;
> -    MigrationState *s = migrate_get_current();
> +    MigrationParameters *params = qmp_query_migrate_parameters(NULL);
> +    g_autoptr(QDict) d;
> +    const QDictEntry *e;
>  
> -    params = qmp_query_migrate_parameters(NULL);
> +    assert(params);
>  
> -    if (params) {
> -        monitor_hmp_printf(hmp, "%s: %" PRIu64 "\n",
> -            MigrationParameter_str(MIGRATION_PARAMETER_ANNOUNCE_INITIAL),
> -            params->announce_initial);
> -        monitor_hmp_printf(hmp, "%s: %" PRIu64 "\n",
> -            MigrationParameter_str(MIGRATION_PARAMETER_ANNOUNCE_MAX),
> -            params->announce_max);
> -        monitor_hmp_printf(hmp, "%s: %" PRIu64 "\n",
> -            MigrationParameter_str(MIGRATION_PARAMETER_ANNOUNCE_ROUNDS),
> -            params->announce_rounds);
> -        monitor_hmp_printf(hmp, "%s: %" PRIu64 "\n",
> -            MigrationParameter_str(MIGRATION_PARAMETER_ANNOUNCE_STEP),
> -            params->announce_step);
> -        assert(params->has_throttle_trigger_threshold);
> -        monitor_hmp_printf(hmp, "%s: %u\n",
> -            
> MigrationParameter_str(MIGRATION_PARAMETER_THROTTLE_TRIGGER_THRESHOLD),
> -            params->throttle_trigger_threshold);
> -        assert(params->has_cpu_throttle_initial);
> -        monitor_hmp_printf(hmp, "%s: %u\n",
> -            MigrationParameter_str(MIGRATION_PARAMETER_CPU_THROTTLE_INITIAL),
> -            params->cpu_throttle_initial);
> -        assert(params->has_cpu_throttle_increment);
> -        monitor_hmp_printf(hmp, "%s: %u\n",
> -            
> MigrationParameter_str(MIGRATION_PARAMETER_CPU_THROTTLE_INCREMENT),
> -            params->cpu_throttle_increment);
> -        assert(params->has_cpu_throttle_tailslow);
> -        monitor_hmp_printf(hmp, "%s: %s\n",
> -            
> MigrationParameter_str(MIGRATION_PARAMETER_CPU_THROTTLE_TAILSLOW),
> -            params->cpu_throttle_tailslow ? "on" : "off");
> -        assert(params->has_max_cpu_throttle);
> -        monitor_hmp_printf(hmp, "%s: %u\n",
> -            MigrationParameter_str(MIGRATION_PARAMETER_MAX_CPU_THROTTLE),
> -            params->max_cpu_throttle);
> -        assert(params->tls_creds);
> -        monitor_hmp_printf(hmp, "%s: %s\n",
> -            MigrationParameter_str(MIGRATION_PARAMETER_TLS_CREDS),
> -                       params->tls_creds->u.s);
> -        assert(params->tls_hostname);
> -        monitor_hmp_printf(hmp, "%s: %s\n",
> -            MigrationParameter_str(MIGRATION_PARAMETER_TLS_HOSTNAME),
> -                       params->tls_hostname->u.s);
> -        assert(params->tls_authz);
> -        monitor_hmp_printf(hmp, "%s: %s\n",
> -            MigrationParameter_str(MIGRATION_PARAMETER_TLS_AUTHZ),
> -                       params->tls_authz->u.s);
> -        assert(params->has_max_bandwidth);
> -        monitor_hmp_printf(hmp, "%s: %" PRIu64 "\n",
> -            MigrationParameter_str(MIGRATION_PARAMETER_MAX_BANDWIDTH),
> -            params->max_bandwidth);
> -        assert(params->has_avail_switchover_bandwidth);
> -        monitor_hmp_printf(hmp, "%s: %" PRIu64 "\n",
> -            
> MigrationParameter_str(MIGRATION_PARAMETER_AVAIL_SWITCHOVER_BANDWIDTH),
> -            params->avail_switchover_bandwidth);
> -        assert(params->has_max_postcopy_bandwidth);
> -        monitor_hmp_printf(hmp, "%s: %" PRIu64 "\n",
> -            
> MigrationParameter_str(MIGRATION_PARAMETER_MAX_POSTCOPY_BANDWIDTH),
> -            params->max_postcopy_bandwidth);
> -        assert(params->has_downtime_limit);
> -        monitor_hmp_printf(hmp, "%s: %" PRIu64 "\n",
> -            MigrationParameter_str(MIGRATION_PARAMETER_DOWNTIME_LIMIT),
> -            params->downtime_limit);
> -        assert(params->has_x_checkpoint_delay);
> -        monitor_hmp_printf(hmp, "%s: %u\n",
> -            MigrationParameter_str(MIGRATION_PARAMETER_X_CHECKPOINT_DELAY),
> -            params->x_checkpoint_delay);
> -        monitor_hmp_printf(hmp, "%s: %u\n",
> -            MigrationParameter_str(MIGRATION_PARAMETER_MULTIFD_CHANNELS),
> -            params->multifd_channels);
> -        monitor_hmp_printf(hmp, "%s: %s\n",
> -            MigrationParameter_str(MIGRATION_PARAMETER_MULTIFD_COMPRESSION),
> -            MultiFDCompression_str(params->multifd_compression));
> -        assert(params->has_zero_page_detection);
> -        monitor_hmp_printf(hmp, "%s: %s\n",
> -            MigrationParameter_str(MIGRATION_PARAMETER_ZERO_PAGE_DETECTION),
> -            qapi_enum_lookup(&ZeroPageDetection_lookup,
> -                params->zero_page_detection));
> -        monitor_hmp_printf(hmp, "%s: %" PRIu64 "\n",
> -            MigrationParameter_str(MIGRATION_PARAMETER_XBZRLE_CACHE_SIZE),
> -            params->xbzrle_cache_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));
>  
> -        if (s->has_block_bitmap_mapping) {
> -            BitmapMigrationNodeAliasList *nal;
> -            BitmapMigrationNodeAlias *na;
> -            BitmapMigrationBitmapAliasList *bal;
> -            BitmapMigrationBitmapAlias *ba;
> -            BitmapMigrationBitmapAliasTransform *bat;
> -
> -            monitor_hmp_printf(hmp, "%s:\n",
> -                           MigrationParameter_str(
> -                               MIGRATION_PARAMETER_BLOCK_BITMAP_MAPPING));
> -
> -            for (nal = params->block_bitmap_mapping; nal; nal = nal->next)
> -            {
> -                na = nal->value;
> -                monitor_hmp_printf(hmp, " bitmaps:\n");
> -                for (bal = na->bitmaps; bal; bal = bal->next) {
> -                    ba = bal->value;
> -                    bat = ba->transform;
> -
> -                    monitor_hmp_printf(hmp, " name: %s", ba->name);
> -                    if (bat && bat->has_persistent) {
> -                        monitor_hmp_printf(hmp, " transform:");
> -                        if (bat->persistent) {
> -                            monitor_hmp_printf(hmp, " persistent: on");
> -                        } else {
> -                            monitor_hmp_printf(hmp, " persistent: off");
> -                        }
> -                    }
> -                    monitor_hmp_printf(hmp, " alias: %s\n", ba->alias);
> -                }
> -                monitor_hmp_printf(hmp, " node-name: %s alias: %s\n",
> -                                   na->node_name, na->alias);
> -            }
> -
> -            monitor_hmp_printf(hmp, "\n");
> -        }
> -
> -        monitor_hmp_printf(hmp, "%s: %" PRIu64 "\n",
> -        
> MigrationParameter_str(MIGRATION_PARAMETER_X_VCPU_DIRTY_LIMIT_PERIOD),
> -        params->x_vcpu_dirty_limit_period);
> -
> -        monitor_hmp_printf(hmp, "%s: %" PRIu64 "\n",
> -            MigrationParameter_str(MIGRATION_PARAMETER_VCPU_DIRTY_LIMIT),
> -            params->vcpu_dirty_limit);
> -
> -        assert(params->has_mode);
> -        monitor_hmp_printf(hmp, "%s: %s\n",
> -            MigrationParameter_str(MIGRATION_PARAMETER_MODE),
> -            qapi_enum_lookup(&MigMode_lookup, params->mode));
> -
> -        if (params->has_direct_io) {
> -            monitor_hmp_printf(hmp, "%s: %s\n",
> -                               MigrationParameter_str(
> -                                   MIGRATION_PARAMETER_DIRECT_IO),
> -                               params->direct_io ? "on" : "off");
> -        }
> -
> -        if (params->has_x_rdma_chunk_size) {
> -            monitor_hmp_printf(hmp, "%s: %" PRIu64 "\n",
> -                           MigrationParameter_str(
> -                               MIGRATION_PARAMETER_X_RDMA_CHUNK_SIZE),
> -                           params->x_rdma_chunk_size);
> -        }
> -
> -        assert(params->has_cpr_exec_command);
> -        monitor_print_cpr_exec_command(hmp, params->cpr_exec_command);
> +        hmp_migrate_print_qobject(hmp, label, qdict_entry_value(e));
> +        monitor_hmp_printf(hmp, "\n");
>      }

Why not something like

       hmp_migrate_print_qobject(hmp, NULL, d)

?

>  
>      qapi_free_MigrationParameters(params);
> diff --git a/migration/options.c b/migration/options.c
> index 46d040fc3f..29b96f48c1 100644
> --- a/migration/options.c
> +++ b/migration/options.c
> @@ -1097,7 +1097,7 @@ static void tls_opt_to_str(StrOrNull *opt)
>      opt->u.s = g_strdup("");
>  }
>  
> -static QDict *migrate_params_to_dict(MigrationParameters *p, Error **errp)
> +QDict *migrate_params_to_dict(MigrationParameters *p, Error **errp)
>  {
>      QObject *obj = NULL;
>      Visitor *v = qobject_output_visitor_new(&obj);
> diff --git a/migration/options.h b/migration/options.h
> index c7da2d0b5b..0d9f88c11e 100644
> --- a/migration/options.h
> +++ b/migration/options.h
> @@ -94,4 +94,5 @@ uint64_t migrate_rdma_chunk_size(void);
>  bool migrate_params_check(MigrationParameters *params, Error **errp);
>  void migrate_params_init(MigrationParameters *params);
>  bool migrate_params_free(MigrationParameters *params, Error **errp);
> +QDict *migrate_params_to_dict(MigrationParameters *p, Error **errp);
>  #endif


Reply via email to