Peter Xu <[email protected]> writes:

> On Wed, Sep 02, 2026 at 07:15:38PM -0300, Fabiano Rosas wrote:
>> There are a couple of situations where all fields of a
>> MigrationParameters object need to be marked as present: when cloning
>> an entire object and when creating the transient object in
>> qmp_query_migrate(). The query-migrate-parameters QMP command contract
>> requires that all parameters, except block-bitmap-mapping, are present
>> in the output.
>> 
>> Validate that a given object has all has_* fields set to true.
>> 
>> Signed-off-by: Fabiano Rosas <[email protected]>
>> ---
>>  migration/options.c | 54 +++++++++++++++++++++++++++++++++++++++++++++
>>  1 file changed, 54 insertions(+)
>> 
>> diff --git a/migration/options.c b/migration/options.c
>> index bd7be8f9832..5d17acdd881 100644
>> --- a/migration/options.c
>> +++ b/migration/options.c
>> @@ -12,6 +12,7 @@
>>   */
>>  
>>  #include "qemu/osdep.h"
>> +#include "qemu/cutils.h"
>>  #include "qemu/error-report.h"
>>  #include "qemu/units.h"
>>  #include "exec/target_page.h"
>> @@ -23,8 +24,10 @@
>>  #include "qapi/qmp/qerror.h"
>>  #include "qapi/qobject-input-visitor.h"
>>  #include "qapi/qobject-output-visitor.h"
>> +#include "qobject/qbool.h"
>>  #include "qobject/qdict.h"
>>  #include "qobject/qnull.h"
>> +#include "qobject/qstring.h"
>>  #include "system/runstate.h"
>>  #include "migration/colo.h"
>>  #include "migration/cpr.h"
>> @@ -1149,12 +1152,63 @@ static void 
>> migrate_mark_all_params_present(MigrationParameters *p)
>>      }
>>  }
>>  
>> +static bool assert_all_params_present(MigrationParameters *params, Error 
>> **errp)
>> +{
>> +    g_autoptr(QDict) d = migrate_params_to_dict(params, errp);
>> +    const QDictEntry *e = NULL;
>> +    int i = 0;
>> +
>> +    if (!d) {
>> +        return false;
>> +    }
>> +
>> +    for (e = qdict_first(d); e; e = qdict_next(d, e), i++) {
>> +        const char *key = qdict_entry_key(e);
>> +        const char *p;
>> +
>> +        if (strstart(key, "tls-", &p)) {
>> +            QString *s = qobject_to(QString, qdict_entry_value(e));
>> +
>> +            if (!s) {
>> +                break;
>> +            }
>> +        } else if (strstart(key, "has-", &p)) {
>
> Does the qdict contain any has- field?  
>

¬¬

I guess that decides the fate of the MigrationParameter enum.

> visit_type_MigrationParameters_members:
>
>     if (visit_optional(v, "announce-initial", &obj->has_announce_initial)) {
>         if (!visit_type_size(v, "announce-initial", &obj->announce_initial, 
> errp)) {
>             return false;
>         }
>     }
>     ...
>
> It seems the has_* fields are only used to identify existance of objects,
> not converted.
>
>> +            if (qdict_haskey(d, p)) {
>> +                QBool *b = qobject_to(QBool, qdict_entry_value(e));
>> +
>> +                If (!b || !qbool_get_bool(b)) {
>> +                    break;
>> +                }
>> +            }
>> +        }
>> +    }
>> +
>> +    if (i && !e) {
>> +        return true;
>> +    }
>> +
>> +    /*
>> +     * Should never happen, but avoid asserting becase this is
>> +     * reachable from QMP.
>
> IIUC as long as this fact shouldn't be changed by any possible user input,
> we could still assert.  But I understand you want to be careful, maybe
> either (1) directly assert, or (2) change the function name,
> s/assert/check/?  I vote (1).
>
> Said that, if the qdict trick didn't work it beats the whole patch.. so
> IMHO we can also leave this sanity check for later too.  Your call.
>
>> +     */
>> +    error_setg(errp, "Missing parameter. Query output will be incomplete.");
>> +    return false;
>> +}
>> +
>>  MigrationParameters *qmp_query_migrate_parameters(Error **errp)
>>  {
>>      MigrationState *s = migrate_get_current();
>>      MigrationParameters *params = QAPI_CLONE(MigrationParameters,
>>                                               &s->parameters);
>>  
>> +    /*
>> +     * Validate all parameters have their has_* field set to true as
>> +     * consequence of the initial migrate_mark_all_params_present().
>> +     */
>> +    if (!assert_all_params_present(params, errp)) {
>> +        return NULL;
>> +    }
>> +
>>      /*
>>       * The block-bitmap-mapping breaks the expected API of
>>       * query-migrate-parameters of having all members present. To keep
>> -- 
>> 2.53.0
>> 

Reply via email to