Fabiano Rosas <faro...@suse.de> writes:

> The migration parameters tls_creds, tls_authz and tls_hostname
> currently have a non-uniform handling. When used as arguments to
> migrate-set-parameters, their type is StrOrNull and when used as
> return value from query-migrate-parameters their type is a plain
> string.
>
> Not only having to convert between the types is cumbersome, but it
> also creates the issue of requiring two different QAPI types to be
> used, one for each command. MigrateSetParameters is used for
> migrate-set-parameters with the TLS arguments as StrOrNull while
> MigrationParameters is used for query-migrate-parameters with the TLS
> arguments as str.
>
> Since StrOrNull could be considered a superset of str, change the type
> of the TLS arguments in MigrationParameters to StrOrNull. Also ensure
> that QTYPE_QNULL is never used.
>
> 1) migrate-set-parameters will always write QTYPE_QSTRING to
>   s->parameters, either an empty or non-empty string.
>
> 2) query-migrate-parameters will always return a QTYPE_QSTRING, either
>   empty or non-empty.
>
> 3) the migrate_tls_* helpers will always return a non-empty string or
>   NULL, for the internal migration code's consumption.
>
> Points (1) and (2) above help simplify the parameters validation and
> the query command handling because s->parameters is already kept in
> the format that query-migrate-parameters (and info migrate_paramters)
> expect. Point (3) is so people don't need to care about StrOrNull in
> migration code.
>
> This will allow the type duplication to be removed in the next
> patches.
>
> Note that the type of @tls_creds, @tls-hostname, @tls-authz changes
> from str to StrOrNull in introspection of the query-migrate-parameters
> command. We accept this imprecision to enable de-duplication.
>
> There's no need to free the TLS options in
> migration_instance_finalize() because they're freed by the qdev
> properties .release method.
>
> Temporary in this patch:
> migrate_params_test_apply() copies s->parameters into a temporary
> structure, so it's necessary to drop the references to the TLS options
> if they were not set by the user to avoid double-free. This is fixed
> in the next patches.
>
> Signed-off-by: Fabiano Rosas <faro...@suse.de>

[...]

> diff --git a/migration/options.c b/migration/options.c
> index 384ef9e421..f7bbdba5fc 100644
> --- a/migration/options.c
> +++ b/migration/options.c

[...]

> @@ -935,6 +951,37 @@ AnnounceParameters *migrate_announce_params(void)
>      return &ap;
>  }
>  
> +void migrate_tls_opts_free(MigrationParameters *params)
> +{
> +    qapi_free_StrOrNull(params->tls_creds);
> +    qapi_free_StrOrNull(params->tls_hostname);
> +    qapi_free_StrOrNull(params->tls_authz);
> +}
> +
> +/* either non-empty or empty string */

This isn't true, because ...

> +static void tls_opt_to_str(StrOrNull **tls_opt)
> +{
> +    StrOrNull *opt = *tls_opt;
> +
> +    if (!opt) {
> +        return;

... it can also be null.

Maybe

   /* Normalize QTYPE_QNULL to QTYPE_QSTRING "" */

> +    }
> +
> +    switch (opt->type) {
> +    case QTYPE_QSTRING:
> +        return;
> +    case QTYPE_QNULL:
> +        qobject_unref(opt->u.n);
> +        break;
> +    default:
> +        g_assert_not_reached();
> +    }
> +
> +    opt->type = QTYPE_QSTRING;
> +    opt->u.s = g_strdup("");
> +    *tls_opt = opt;
> +}

I'd prefer something like

       if (!opt || opt->type == QTYPE_QSTRING) {
           return;
       }
       qobject_unref(opt->u.n);
       opt->type = QTYPE_QSTRING;
       opt->u.s = g_strdup("");
       *tls_opt = opt;

But this is clearly a matter of taste.

> +
>  MigrationParameters *qmp_query_migrate_parameters(Error **errp)
>  {
>      MigrationParameters *params;

[...]

> @@ -1251,18 +1294,24 @@ static void 
> migrate_params_test_apply(MigrateSetParameters *params,
>      }
>  
>      if (params->tls_creds) {
> -        assert(params->tls_creds->type == QTYPE_QSTRING);
> -        dest->tls_creds = params->tls_creds->u.s;
> +        dest->tls_creds = QAPI_CLONE(StrOrNull, params->tls_creds);
> +    } else {
> +        /* drop the reference, it's owned by s->parameters */
> +        dest->tls_creds = NULL;

Suggest "clear the reference" to avoid associations with reference
counting.

>      }
>  
>      if (params->tls_hostname) {
> -        assert(params->tls_hostname->type == QTYPE_QSTRING);
> -        dest->tls_hostname = params->tls_hostname->u.s;
> +        dest->tls_hostname = QAPI_CLONE(StrOrNull, params->tls_hostname);
> +    } else {
> +        /* drop the reference, it's owned by s->parameters */
> +        dest->tls_hostname = NULL;
>      }
>  
>      if (params->tls_authz) {
> -        assert(params->tls_authz->type == QTYPE_QSTRING);
> -        dest->tls_authz = params->tls_authz->u.s;
> +        dest->tls_authz = QAPI_CLONE(StrOrNull, params->tls_authz);
> +    } else {
> +        /* drop the reference, it's owned by s->parameters */
> +        dest->tls_authz = NULL;
>      }
>  
>      if (params->has_max_bandwidth) {

[...]

> diff --git a/qapi/migration.json b/qapi/migration.json
> index 4963f6ca12..97bb022c45 100644
> --- a/qapi/migration.json
> +++ b/qapi/migration.json
> @@ -1293,9 +1293,9 @@
>              '*cpu-throttle-initial': 'uint8',
>              '*cpu-throttle-increment': 'uint8',
>              '*cpu-throttle-tailslow': 'bool',
> -            '*tls-creds': 'str',
> -            '*tls-hostname': 'str',
> -            '*tls-authz': 'str',
> +            '*tls-creds': 'StrOrNull',
> +            '*tls-hostname': 'StrOrNull',
> +            '*tls-authz': 'StrOrNull',
>              '*max-bandwidth': 'size',
>              '*avail-switchover-bandwidth': 'size',
>              '*downtime-limit': 'uint64',

QAPI schema
Acked-by: Markus Armbruster <arm...@redhat.com>


Reply via email to