From: Markus Armbruster <armbru@redhat.com>
To: Fabiano Rosas <farosas@suse.de>
Cc: qemu-devel@nongnu.org, Peter Xu <peterx@redhat.com>,
"Dr . David Alan Gilbert" <dave@treblig.org>,
Laurent Vivier <lvivier@redhat.com>,
Paolo Bonzini <pbonzini@redhat.com>
Subject: Re: [PATCH v2 13/18] migration: Use keyval input visitor in HMP set command
Date: Fri, 11 Sep 2026 10:12:25 +0200 [thread overview]
Message-ID: <8733vgb40m.fsf@pond.sub.org> (raw)
In-Reply-To: <87qzj1tcpl.fsf@suse.de> (Fabiano Rosas's message of "Thu, 10 Sep 2026 11:15:02 -0300")
Fabiano Rosas <farosas@suse.de> writes:
> Markus Armbruster <armbru@redhat.com> writes:
>
>> Fabiano Rosas <farosas@suse.de> writes:
>>
>>> Change the hmp_migrate_set_parameter command to use a keyval input
>>> visitor.
>>>
>>> Currently a string visitor is used and due to limitations of that
>>> particular visitor's implementation it's necessary to consult the QAPI
>>> type enum (MigrationParameter_lookup) and call each visit_type_*
>>> function individually. Which makes using a visitor pointless.
>>
>> Also, the less the string visitors are used, the happier I am.
>>
>>> Since there are other visitors implemented properly and generated code
>>> to iterate the QAPI object, prefer using one of those. The keyval
>>> input visitor is adequate because HMP provides basically one key and
>>> one value for each migrate_set_parameter command.
>>>
>>> To switch from string_input_visitor to keyval_input_visitor simply put
>>> the parameter name and value into a dict and invoke
>>> visit_type_MigrationParameters().
>>
>> This works for scalar types: the value is a QString, and the QObject
>> keyval input visitor automatically converts to the C type the visitor
>> expects. It doesn't work for non-scalar types; see cpr-exec-command
>> below.
>>
>>> Note that it's not necessary to go through any of the keyval_* code
>>> because due to the nature of HMP, there's no parsing to do (no '=', no
>>> ',', etc).
>>
>> migrate_set_parameter syntax isn't keyval, only val is, i.e. its value
>> argument is in keyval value syntax (more or less).
>>
>> "More or less" is my hedge against differences between the string input
>> visitor and the QObject keyval input visitor. Did you check?
>>
>
> They ultimately use the same functions to do the conversion
> (qemu_strtou64, qemu_strtod_finite, etc). The differences are in
> slightly different wording of error messages and the fact that the
> string input visitor has a different message for -ERANGE while the
> qobject input visitor has a TODO for that case.
>
> I think those differences are of no consequence. The error messages that
> we really care about are the ones resulting from the migration code
> validation (because they're informative to the user). The API level
> messages are too generic anyway.
Should the commit message make this argument?
>> Aside: we could create migrate_set_parameters with keyval syntax if we
>> cared.
>>
>>> With this the migrate_set_parameters HMP commands will be
>>> automatically updated anytime a new migration parameter is added.
>>>
>>> One parameter, "cpr-exec-command", takes the strList type which needs
>>> to be built manually. This moves to a "legacy" suffixed function.
>>
>> When visit_type_MigrationParameters() visits "cpr-exec-command", it
>> calls visit_type_strList(). With the QObject keyval input visitor, this
>> expects a QList, not a QString.
>>
>> Thus, hmp_migrate_set_parameter() needs to parse the value argument into
>> a list at least. That's why it needs to be a special case.
>>
>
> I'm having some difficulty understanding why isn't that the job of the
> visit function.
>
> I think what you're saying is that we can convert QAPI's strList into
> QObject's QList of QString, but cannot convert the HMP string directly
> into QList even though we know that string represents a strList. I feel
> like there's code missing somewhere...
This is due to separation of concerns in the design of the visitor
pipelines. Example:
JSON input
parser visitor
JSON ---> QObject ---> QAPI-generated C type
JSON output
formatter visitor
JSON <--- QObject <--- QAPI-generated C type
Parser/formatter deal with JSON. All they know about QAPI is QObject.
Visitors deal with QAPI-generated C types. All they know about JSON is
QObject.
Keyval came much later, and we had to accept a weaker separation for it.
In JSON, the type of scalars is explicit in the syntax. In keyval, it
is not. So scalar values are always strings in the parser's output, and
the QObject keyval visitor needs to parse these strings. This leads to
restrictions discussed in keyval.c's big comment.
But this applies *only* to scalars! The separation still holds for
objects and arrays.
> ... although it wouldn't help with cpr-exec-command because of the
> "shell parsing" semantics. But that's another issue.
Yes.
>> It parses it with g_shell_parse_argv(). GLib docs "specify" this to
>> parse "a command line [...] in much the same way the shell would, but
>> without many of the expansions the shell would perform (variable
>> expansion, globs, operators, filename expansion, etc. are not
>> supported)." Ugh! But I digress.
>
> One side-effect of having code that handles parameters genericly is that
> there is less room for inventing custom parsing when new parameters are
> introduced.
We use g_shell_parse_argv() for cpr-exec-command and nothing else, which
effectively makes it custom syntax. At least it's custom syntax we
didn't design and implement, but still. Too. Much. Syntax. Too.
Many. Parsers.
>>> Signed-off-by: Fabiano Rosas <farosas@suse.de>
[...]
>>> diff --git a/tests/qtest/migration/misc-tests.c b/tests/qtest/migration/misc-tests.c
>>> index 2261ae7c89..4ac2f42a5a 100644
>>> --- a/tests/qtest/migration/misc-tests.c
>>> +++ b/tests/qtest/migration/misc-tests.c
>>> @@ -50,7 +50,7 @@ typedef struct HMPTestData {
>>> HMPTestData test_cases[] = {
>>> TEST("", "", "migrate_set_parameter: string expected"),
>>> TEST("foo", "", "migrate_set_parameter: string expected"),
>>> - TEST("foo", "on", "Error: invalid parameter value: foo"),
>>> + TEST("foo", "on", "Error: Parameter 'foo' is unexpected"),
>>
>> This appears to be an improvement. Where does it come from?
>>
>
> Old code went through the enum lookup whereas now the QObject visitor's
> qobject_input_check_struct flags the struct member name.
hmp_migrate_set_parameter() takes a parameter argument that names a
member of MigrationParameters. Trick: it parses it as a member of
related type MigrationParameter, with qapi_enum_parse(). Since the
members of MigrationParameter are *values*, qapi_enum_parse() reasonably
reports "invalid parameter value".
Trickery breed bad error messages, film at eleven.
Suggest to mention the improvement in the commit message.
>>>
>>> /* bool */
>>> TEST("cpu-throttle-tailslow", "on", "on"),
next prev parent reply other threads:[~2026-09-11 8:13 UTC|newest]
Thread overview: 45+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-09 21:44 [PATCH v2 00/18] migration: MigrationParameters changes Fabiano Rosas
2026-09-09 21:44 ` [PATCH v2 01/18] checkpatch: Fix checking of newlines in error messages Fabiano Rosas
2026-09-09 21:44 ` [PATCH v2 02/18] migration/options.c: Don't export migrate_tls_opts_free Fabiano Rosas
2026-09-09 21:44 ` [PATCH v2 03/18] migration: Rename variables in qmp_migrate_set_parameters Fabiano Rosas
2026-09-09 21:44 ` [PATCH v2 04/18] migration: Use QAPI_CLONE_MEMBERS in migrate_params_apply Fabiano Rosas
2026-09-09 21:44 ` [PATCH v2 05/18] migration: Merge parameter structs instead of assigning one by one Fabiano Rosas
2026-09-10 12:28 ` Peter Xu
2026-09-09 21:44 ` [PATCH v2 06/18] migration: Open code migrate_params_apply Fabiano Rosas
2026-09-09 21:44 ` [PATCH v2 07/18] migration: Stop freeing s->parameters members individually Fabiano Rosas
2026-09-09 21:44 ` [PATCH v2 08/18] migration: Use migrate_params_free during finalize Fabiano Rosas
2026-09-09 21:44 ` [PATCH v2 09/18] tests/qtest/migration: Add a test for HMP Fabiano Rosas
2026-09-10 14:02 ` Peter Xu
2026-09-13 20:30 ` Dr. David Alan Gilbert
2026-09-09 21:45 ` [PATCH v2 10/18] tests/qtest/migration: Add a test for HMP completion Fabiano Rosas
2026-09-10 17:36 ` Peter Xu
2026-09-13 20:58 ` Dr. David Alan Gilbert
2026-09-09 21:45 ` [PATCH v2 11/18] migration: HMP: Fix bandwidth parameters Fabiano Rosas
2026-09-10 6:05 ` Markus Armbruster
2026-09-10 12:37 ` Fabiano Rosas
2026-09-11 6:19 ` Markus Armbruster
2026-09-10 13:20 ` Dr. David Alan Gilbert
2026-09-10 13:26 ` Dr. David Alan Gilbert
2026-09-10 17:38 ` Peter Xu
2026-09-09 21:45 ` [PATCH v2 12/18] migration: Change HMP 'info migrate_parameters' output Fabiano Rosas
2026-09-10 7:32 ` Markus Armbruster
2026-09-10 13:02 ` Fabiano Rosas
2026-09-11 6:46 ` Markus Armbruster
2026-09-09 21:45 ` [PATCH v2 13/18] migration: Use keyval input visitor in HMP set command Fabiano Rosas
2026-09-10 11:07 ` Markus Armbruster
2026-09-10 14:15 ` Fabiano Rosas
2026-09-10 22:10 ` Fabiano Rosas
2026-09-11 8:22 ` Markus Armbruster
2026-09-11 12:54 ` Fabiano Rosas
2026-09-11 8:12 ` Markus Armbruster [this message]
2026-09-09 21:45 ` [PATCH v2 14/18] migration: Use output visitor in info command Fabiano Rosas
2026-09-09 21:45 ` [PATCH v2 15/18] migration: Rewrite migrate_set_parameter_completion using QDict Fabiano Rosas
2026-09-10 11:17 ` Markus Armbruster
2026-09-10 13:09 ` Fabiano Rosas
2026-09-11 7:15 ` Markus Armbruster
2026-09-09 21:45 ` [PATCH v2 16/18] migration: Add capabilities into MigrationParameters Fabiano Rosas
2026-09-10 11:22 ` Markus Armbruster
2026-09-09 21:45 ` [PATCH v2 17/18] migration: Remove s->capabilities Fabiano Rosas
2026-09-09 21:45 ` [PATCH v2 18/18] qapi/migration: Deprecate capabilities commands Fabiano Rosas
2026-09-10 17:35 ` [PATCH v2 00/18] migration: MigrationParameters changes Peter Xu
2026-09-10 19:27 ` Fabiano Rosas
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=8733vgb40m.fsf@pond.sub.org \
--to=armbru@redhat.com \
--cc=dave@treblig.org \
--cc=farosas@suse.de \
--cc=lvivier@redhat.com \
--cc=pbonzini@redhat.com \
--cc=peterx@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.