From: John Snow <jsnow@redhat.com>
To: Markus Armbruster <armbru@redhat.com>
Cc: QEMU Developers <qemu-devel@nongnu.org>
Subject: Re: QMP and the 'id' parameter
Date: Tue, 10 Nov 2020 11:32:57 -0500 [thread overview]
Message-ID: <ab509dba-7cd8-aaed-7ded-9dd82c040b6d@redhat.com> (raw)
In-Reply-To: <87361h20kd.fsf@dusky.pond.sub.org>
On 11/10/20 1:22 AM, Markus Armbruster wrote:
> John Snow <jsnow@redhat.com> writes:
>
>> The QMP specification states:
>>
>>> NOTE: Some errors can occur before the Server is able to read the "id"
>>> member, in these cases the "id" member will not be part of the error
>>> response, even if provided by the client.
>>
>> I am assuming this case ONLY occurs for Parse errors:
>>
>> {'class': 'GenericError', 'desc': 'JSON parse error, expecting value'}
>
> There are more "desc" possible, actually.
>
> The JSON parser gets fed chunks of input, and calls a callback for every
> full JSON value, and on parse error.
>
> QMP's callback is handle_qmp_command(). Parameter @req is the parsed
> JSON value, parameter @err is the (parse) error object, and exactly one
> of them is non-null.
>
> 1. Parse error
>
> If @err, we send an error response for it. It never has "id". See
> qmp_error_response() caller monitor_qmp_dispatcher_co(). The possible
> @err are:
>
> $ grep error_setg qobject/json-*[ch]
> qobject/json-parser.c: error_setg(&ctxt->err, "JSON parse error, %s", message);
>
> This is a syntax error.
>
> Search for parse_error() to see the possible @message patterns.
>
> qobject/json-streamer.c: error_setg(&err, "JSON parse error, stray '%s'", input->str);
>
> This is a lexical error.
>
> qobject/json-streamer.c: error_setg(&err, "JSON token size limit exceeded");
> qobject/json-streamer.c: error_setg(&err, "JSON token count limit exceeded");
> qobject/json-streamer.c: error_setg(&err, "JSON nesting depth limit exceeded");
>
> These are (intentional) parser limits.
>
> 2. Successful parse
>
> If @req, it's a successful parse.
>
> If @req is not a JSON object, there is no "id". qmp_dispatch() reports
>
> error_setg(&err, "QMP input must be a JSON object");
>
> If @req is a JSON object, it has "id" exactly when the client supplied
> one. The response mirrors @req's "id". See qmp_error_response() caller
> qmp_dispatch().
>
That's very helpful, thank you. So in summary, the possibilities are:
1. syntax error (with several descriptions)
2. lexical error (with several descriptions, templated from one message)
3. lexical limitation (with several descriptions)
4. grammatical error ("QMP input must be a JSON object")
(I know we have declared the error_class passe and we now prefer
"generic_error", but I lack the history lesson on why we do that.
Wouldn't the error_class here be helpful for interpreting the response?
It helps differentiate between 'The RPC call was received' vs 'The RPC
call was received, but failed.' which may have semantic differences for
who wants to consume the error: the QMP library itself, or the user
making the RPC call. No?)
>> And I am assuming, in the context of a client that /always/ sets an
>> 'id' for its execute statements, that this means that any error
>> response we receive without an 'id' field *must* be associated with
>> the most-recently-sent command.
>
> Only if the client keeps no more than one command in flight.
>
OK, so without engaging the OOB capability, we receive responses
strictly in a FIFO manner, always.
So if we have:
Send exec A, Send exec B, Send exec C
and then we receive an error response with no ID attached, we know it
must be "A" that errored. Correct?
> Command responses get sent strictly in order (even parse errors), except
> for commands executed out-of-band.
>
> If the client sends N JSON values, and only then reads responses, and
> there are no parse errors, then it'll get N responses. The i-th
> response is for the i-th JSON value, except responses to OOB command may
> "jump the queue".
>
Let's assume now that A, B, and C are *all* OOB commands:
- Send exec-oob A
- Send exec-oob B
- Send exec-oob C
My client now reads an error message that has no ID attached. Which
command execution was this associated with?
Is it necessarily "A" if we have not yet received any other response?
> With parse errors, it can get a different number of responses.
>
Oh, uhm -- if the parse error was bad enough that it didn't even notice
we sent it three commands, right? ... So if we see a parse error, we
might not know which, if any, of our queued commands were seen or can
still expect a response.
That seems difficult to code around, unless I misunderstand.
(Every parser error I receive -- which I can "guess" that it's a parser
error by the lack of an 'id' field, potentially invalidates the entire
queue?)
> Questions?
>
A few :)
next prev parent reply other threads:[~2020-11-10 16:34 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-11-10 1:47 QMP and the 'id' parameter John Snow
2020-11-10 6:22 ` Markus Armbruster
2020-11-10 9:15 ` Daniel P. Berrangé
2020-11-10 10:27 ` Markus Armbruster
2020-11-10 16:32 ` John Snow [this message]
2020-11-11 8:27 ` Markus Armbruster
2020-11-20 0:22 ` John Snow
2020-11-20 10:25 ` Markus Armbruster
2020-11-20 16:49 ` John Snow
2020-11-23 6:57 ` Markus Armbruster
2020-11-30 18:32 ` John Snow
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=ab509dba-7cd8-aaed-7ded-9dd82c040b6d@redhat.com \
--to=jsnow@redhat.com \
--cc=armbru@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).