qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH 05/21] qmp: Clean up how we enforce capability n


From: Markus Armbruster
Subject: Re: [Qemu-devel] [PATCH 05/21] qmp: Clean up how we enforce capability negotiation
Date: Sat, 25 Feb 2017 07:33:18 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/25.1 (gnu/linux)

Eric Blake <address@hidden> writes:

> On 02/23/2017 03:45 PM, Markus Armbruster wrote:
>> To enforce capability negotiation before normal operation,
>> handle_qmp_command() inspects every command before it's handed off to
>> qmp_dispatch().  This is a bit of a layering violation, and results in
>> duplicated code.
>> 
>> Before capability negotiation (!cur_mon->in_command_mode), we fail
>> commands other than "qmp_capabilities".  This is what enforces
>> capability negotiation.
>> 
>> Afterwards, we fail command "qmp_capabilities".
>> 
>> Clean this up as follows.
>> 
>> The obvious place to fail a command is the command itself, so move the
>> "afterwards" check to qmp_qmp_capabilities().
>> 
>> We do the "before" check in every other command, but that would be
>> bothersome.  Instead, start without all the other commands, by
>> registering only qmp_qmp_capabilities().  Register the others in
>> qmp_qmp_capabilities().
>> 
>> Additionally, replace the generic human-readable error message for
>> CommandNotFound by one that reminds the user to run qmp_capabilities.
>> Without that, we'd regress commit 2d5a834.
>> 
>> Signed-off-by: Markus Armbruster <address@hidden>
>> ---
>>  monitor.c | 70 
>> ++++++++++++++++++++++++++++++++++++---------------------------
>>  1 file changed, 40 insertions(+), 30 deletions(-)
>> 
>
>> @@ -3781,12 +3782,21 @@ static void handle_qmp_command(JSONMessageParser 
>> *parser, GQueue *tokens)
>>      cmd_name = qdict_get_str(qdict, "execute");
>>      trace_handle_qmp_command(mon, cmd_name);
>>  
>> -    if (invalid_qmp_mode(mon, cmd_name, &err)) {
>> -        goto err_out;
>> -    }
>> -
>>      rsp = qmp_dispatch(req);
>>  
>> +    qdict = qdict_get_qdict(qobject_to_qdict(rsp), "error");
>> +    if (qdict) {
>> +        if (!mon->qmp.in_command_mode
>> +            && !strcmp(qdict_get_try_str(qdict, "class"),
>
> Ouch - this can call strcmp(NULL, ...) if the error is ill-formed.  Is
> that a problem?  Can we assert that "class" will always exist as a string?

It's safe, because it comes from qmp_build_error_object().  But I'll
switch to g_strcmp0() to make it more obviously safe.

>> +                       
>> QapiErrorClass_lookup[ERROR_CLASS_COMMAND_NOT_FOUND])) {
>> +            /* Provide a more useful error message */
>> +            qdict_del(qdict, "desc");
>> +            qdict_put(qdict, "desc",
>> +                      qstring_from_str("Expecting capabilities negotiation"
>> +                                       " with 'qmp_capabilities'"));
>> +        }
>> +    }
>> +
>
> Otherwise, I like it.

Thanks!



reply via email to

[Prev in Thread] Current Thread [Next in Thread]