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)) { + 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. + */ + 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
