All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH] qmp: Give saner messages related to qmp_capabilities misuse
@ 2015-04-15 15:19 Eric Blake
  2015-04-15 16:07 ` Kashyap Chamarthy
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: Eric Blake @ 2015-04-15 15:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: erik.rull, paulo.vital, lcapitulino

Pretending that QMP doesn't understand a command merely because
we are not in the right mode doesn't help first-time users figure
out what to do to correct things.  Although the documentation for
QMP calls out capabilities negotiation, we should also make it
clear in our error messages what we were expecting.  With this
patch, I now get the following transcript:

$ ./x86_64-softmmu/qemu-system-x86_64 -qmp stdio -nodefaults
{"QMP": {"version": {"qemu": {"micro": 93, "minor": 2, "major": 2}, "package": ""}, "capabilities": []}}
{"execute":"huh"}
{"error": {"class": "CommandNotFound", "desc": "The command huh has not been found"}}
{"execute":"quit"}
{"error": {"class": "CommandNotFound", "desc": "Expecting capabilities negotiation with 'qmp_capabilities' before command 'quit'"}}
{"execute":"qmp_capabilities"}
{"return": {}}
{"execute":"qmp_capabilities"}
{"error": {"class": "CommandNotFound", "desc": "Capabilities negotiation is already complete, command 'qmp_capabilities' ignored"}}
{"execute":"quit"}
{"return": {}}
{"timestamp": {"seconds": 1429110729, "microseconds": 181935}, "event": "SHUTDOWN"}

Signed-off-by: Eric Blake <eblake@redhat.com>
---

Based in part on this thread:
https://lists.gnu.org/archive/html/qemu-devel/2015-04/msg00831.html

 monitor.c | 23 +++++++++++++++++++----
 1 file changed, 19 insertions(+), 4 deletions(-)

diff --git a/monitor.c b/monitor.c
index 68873ec..9f37700 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4783,10 +4783,22 @@ static int monitor_can_read(void *opaque)
     return (mon->suspend_cnt == 0) ? 1 : 0;
 }

-static int invalid_qmp_mode(const Monitor *mon, const mon_cmd_t *cmd)
+static bool invalid_qmp_mode(const Monitor *mon, const mon_cmd_t *cmd)
 {
-    int is_cap = cmd->mhandler.cmd_new == do_qmp_capabilities;
-    return (qmp_cmd_mode(mon) ? is_cap : !is_cap);
+    bool is_cap = cmd->mhandler.cmd_new == do_qmp_capabilities;
+    if (is_cap && qmp_cmd_mode(mon)) {
+        qerror_report(ERROR_CLASS_COMMAND_NOT_FOUND,
+                      "Capabilities negotiation is already complete, command "
+                      "'%s' ignored", cmd->name);
+        return true;
+    }
+    if (!is_cap && !qmp_cmd_mode(mon)) {
+        qerror_report(ERROR_CLASS_COMMAND_NOT_FOUND,
+                      "Expecting capabilities negotiation with "
+                      "'qmp_capabilities' before command '%s'", cmd->name);
+        return true;
+    }
+    return false;
 }

 /*
@@ -5080,11 +5092,14 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens)
     cmd_name = qdict_get_str(input, "execute");
     trace_handle_qmp_command(mon, cmd_name);
     cmd = qmp_find_cmd(cmd_name);
-    if (!cmd || invalid_qmp_mode(mon, cmd)) {
+    if (!cmd) {
         qerror_report(ERROR_CLASS_COMMAND_NOT_FOUND,
                       "The command %s has not been found", cmd_name);
         goto err_out;
     }
+    if (invalid_qmp_mode(mon, cmd)) {
+        goto err_out;
+    }

     obj = qdict_get(input, "arguments");
     if (!obj) {
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [Qemu-devel] [PATCH] qmp: Give saner messages related to qmp_capabilities misuse
  2015-04-15 15:19 [Qemu-devel] [PATCH] qmp: Give saner messages related to qmp_capabilities misuse Eric Blake
@ 2015-04-15 16:07 ` Kashyap Chamarthy
  2015-04-15 16:30 ` Paulo Ricardo Paz Vital
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 7+ messages in thread
From: Kashyap Chamarthy @ 2015-04-15 16:07 UTC (permalink / raw)
  To: Eric Blake; +Cc: erik.rull, qemu-devel, paulo.vital, lcapitulino

On Wed, Apr 15, 2015 at 09:19:23AM -0600, Eric Blake wrote:
> Pretending that QMP doesn't understand a command merely because
> we are not in the right mode doesn't help first-time users figure
> out what to do to correct things.  Although the documentation for
> QMP calls out capabilities negotiation, we should also make it
> clear in our error messages what we were expecting.  With this
> patch, I now get the following transcript:
> 
> $ ./x86_64-softmmu/qemu-system-x86_64 -qmp stdio -nodefaults
> {"QMP": {"version": {"qemu": {"micro": 93, "minor": 2, "major": 2}, "package": ""}, "capabilities": []}}
> {"execute":"huh"}
> {"error": {"class": "CommandNotFound", "desc": "The command huh has not been found"}}
> {"execute":"quit"}
> {"error": {"class": "CommandNotFound", "desc": "Expecting capabilities negotiation with 'qmp_capabilities' before command 'quit'"}}
> {"execute":"qmp_capabilities"}
> {"return": {}}
> {"execute":"qmp_capabilities"}
> {"error": {"class": "CommandNotFound", "desc": "Capabilities negotiation is already complete, command 'qmp_capabilities' ignored"}}
> {"execute":"quit"}
> {"return": {}}
> {"timestamp": {"seconds": 1429110729, "microseconds": 181935}, "event": "SHUTDOWN"}

Thanks for this (much needed) nice improvement! Long time ago when I
began testing directly w/ QMP, and was wondering _why_ the commands
weren't taking effect despite correct symtax, Marku Armbruster on #qemu
helpfully mentioned I _must_:

    'execute': 'qmp_capabilities'

before invoking any other QMP commands.

Tested this locally, w/ similar test as yours:

    $ ./x86_64-softmmu/qemu-system-x86_64 -qmp stdio -nodefaults
    {"QMP": {"version": {"qemu": {"micro": 93, "minor": 2, "major": 2}, "package": ""}, "capabilities": []}}
    { "execute": "query-version" }
    {"error": {"class": "CommandNotFound", "desc": "Expecting capabilities negotiation with 'qmp_capabilities' before command 'query-version'"}}
    {"execute":"qmp_capabilities"}
    {"return": {}}
    { "execute": "query-version" }
    {"return": {"qemu": {"micro": 93, "minor": 2, "major": 2}, "package": ""}}

So, FWIW:

Tested-By: Kashyap Chamarthy <kchamart@redhat.com>

> Signed-off-by: Eric Blake <eblake@redhat.com>
> ---
> 
> Based in part on this thread:
> https://lists.gnu.org/archive/html/qemu-devel/2015-04/msg00831.html
> 
>  monitor.c | 23 +++++++++++++++++++----
>  1 file changed, 19 insertions(+), 4 deletions(-)
> 
> diff --git a/monitor.c b/monitor.c
> index 68873ec..9f37700 100644
> --- a/monitor.c
> +++ b/monitor.c
> @@ -4783,10 +4783,22 @@ static int monitor_can_read(void *opaque)
>      return (mon->suspend_cnt == 0) ? 1 : 0;
>  }
> 
> -static int invalid_qmp_mode(const Monitor *mon, const mon_cmd_t *cmd)
> +static bool invalid_qmp_mode(const Monitor *mon, const mon_cmd_t *cmd)
>  {
> -    int is_cap = cmd->mhandler.cmd_new == do_qmp_capabilities;
> -    return (qmp_cmd_mode(mon) ? is_cap : !is_cap);
> +    bool is_cap = cmd->mhandler.cmd_new == do_qmp_capabilities;
> +    if (is_cap && qmp_cmd_mode(mon)) {
> +        qerror_report(ERROR_CLASS_COMMAND_NOT_FOUND,
> +                      "Capabilities negotiation is already complete, command "
> +                      "'%s' ignored", cmd->name);
> +        return true;
> +    }
> +    if (!is_cap && !qmp_cmd_mode(mon)) {
> +        qerror_report(ERROR_CLASS_COMMAND_NOT_FOUND,
> +                      "Expecting capabilities negotiation with "
> +                      "'qmp_capabilities' before command '%s'", cmd->name);
> +        return true;
> +    }
> +    return false;
>  }
> 
>  /*
> @@ -5080,11 +5092,14 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens)
>      cmd_name = qdict_get_str(input, "execute");
>      trace_handle_qmp_command(mon, cmd_name);
>      cmd = qmp_find_cmd(cmd_name);
> -    if (!cmd || invalid_qmp_mode(mon, cmd)) {
> +    if (!cmd) {
>          qerror_report(ERROR_CLASS_COMMAND_NOT_FOUND,
>                        "The command %s has not been found", cmd_name);
>          goto err_out;
>      }
> +    if (invalid_qmp_mode(mon, cmd)) {
> +        goto err_out;
> +    }
> 
>      obj = qdict_get(input, "arguments");
>      if (!obj) {
> -- 
> 2.1.0
> 
> 

-- 
/kashyap

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Qemu-devel] [PATCH] qmp: Give saner messages related to qmp_capabilities misuse
  2015-04-15 15:19 [Qemu-devel] [PATCH] qmp: Give saner messages related to qmp_capabilities misuse Eric Blake
  2015-04-15 16:07 ` Kashyap Chamarthy
@ 2015-04-15 16:30 ` Paulo Ricardo Paz Vital
  2015-04-15 18:13 ` John Snow
  2015-04-21 14:09 ` Luiz Capitulino
  3 siblings, 0 replies; 7+ messages in thread
From: Paulo Ricardo Paz Vital @ 2015-04-15 16:30 UTC (permalink / raw)
  To: Eric Blake; +Cc: erik.rull, qemu-devel, lcapitulino

Reviewed-by: Paulo Vital <paulo.vital@profitbricks.com>

On Wed, 2015-04-15 at 09:19 -0600, Eric Blake wrote:
> Pretending that QMP doesn't understand a command merely because
> we are not in the right mode doesn't help first-time users figure
> out what to do to correct things.  Although the documentation for
> QMP calls out capabilities negotiation, we should also make it
> clear in our error messages what we were expecting.  With this
> patch, I now get the following transcript:
> 
> $ ./x86_64-softmmu/qemu-system-x86_64 -qmp stdio -nodefaults
> {"QMP": {"version": {"qemu": {"micro": 93, "minor": 2, "major": 2}, "package": ""}, "capabilities": []}}
> {"execute":"huh"}
> {"error": {"class": "CommandNotFound", "desc": "The command huh has not been found"}}
> {"execute":"quit"}
> {"error": {"class": "CommandNotFound", "desc": "Expecting capabilities negotiation with 'qmp_capabilities' before command 'quit'"}}
> {"execute":"qmp_capabilities"}
> {"return": {}}
> {"execute":"qmp_capabilities"}
> {"error": {"class": "CommandNotFound", "desc": "Capabilities negotiation is already complete, command 'qmp_capabilities' ignored"}}
> {"execute":"quit"}
> {"return": {}}
> {"timestamp": {"seconds": 1429110729, "microseconds": 181935}, "event": "SHUTDOWN"}
> 
> Signed-off-by: Eric Blake <eblake@redhat.com>
> ---
> 
> Based in part on this thread:
> https://lists.gnu.org/archive/html/qemu-devel/2015-04/msg00831.html
> 
>  monitor.c | 23 +++++++++++++++++++----
>  1 file changed, 19 insertions(+), 4 deletions(-)
> 
> diff --git a/monitor.c b/monitor.c
> index 68873ec..9f37700 100644
> --- a/monitor.c
> +++ b/monitor.c
> @@ -4783,10 +4783,22 @@ static int monitor_can_read(void *opaque)
>      return (mon->suspend_cnt == 0) ? 1 : 0;
>  }
> 
> -static int invalid_qmp_mode(const Monitor *mon, const mon_cmd_t *cmd)
> +static bool invalid_qmp_mode(const Monitor *mon, const mon_cmd_t *cmd)
>  {
> -    int is_cap = cmd->mhandler.cmd_new == do_qmp_capabilities;
> -    return (qmp_cmd_mode(mon) ? is_cap : !is_cap);
> +    bool is_cap = cmd->mhandler.cmd_new == do_qmp_capabilities;
> +    if (is_cap && qmp_cmd_mode(mon)) {
> +        qerror_report(ERROR_CLASS_COMMAND_NOT_FOUND,
> +                      "Capabilities negotiation is already complete, command "
> +                      "'%s' ignored", cmd->name);
> +        return true;
> +    }
> +    if (!is_cap && !qmp_cmd_mode(mon)) {
> +        qerror_report(ERROR_CLASS_COMMAND_NOT_FOUND,
> +                      "Expecting capabilities negotiation with "
> +                      "'qmp_capabilities' before command '%s'", cmd->name);
> +        return true;
> +    }
> +    return false;
>  }
> 
>  /*
> @@ -5080,11 +5092,14 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens)
>      cmd_name = qdict_get_str(input, "execute");
>      trace_handle_qmp_command(mon, cmd_name);
>      cmd = qmp_find_cmd(cmd_name);
> -    if (!cmd || invalid_qmp_mode(mon, cmd)) {
> +    if (!cmd) {
>          qerror_report(ERROR_CLASS_COMMAND_NOT_FOUND,
>                        "The command %s has not been found", cmd_name);
>          goto err_out;
>      }
> +    if (invalid_qmp_mode(mon, cmd)) {
> +        goto err_out;
> +    }
> 
>      obj = qdict_get(input, "arguments");
>      if (!obj) {

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Qemu-devel] [PATCH] qmp: Give saner messages related to qmp_capabilities misuse
  2015-04-15 15:19 [Qemu-devel] [PATCH] qmp: Give saner messages related to qmp_capabilities misuse Eric Blake
  2015-04-15 16:07 ` Kashyap Chamarthy
  2015-04-15 16:30 ` Paulo Ricardo Paz Vital
@ 2015-04-15 18:13 ` John Snow
  2015-04-15 18:31   ` Eric Blake
  2015-04-21 14:09 ` Luiz Capitulino
  3 siblings, 1 reply; 7+ messages in thread
From: John Snow @ 2015-04-15 18:13 UTC (permalink / raw)
  To: Eric Blake, qemu-devel; +Cc: erik.rull, paulo.vital, lcapitulino



On 04/15/2015 11:19 AM, Eric Blake wrote:
> Pretending that QMP doesn't understand a command merely because
> we are not in the right mode doesn't help first-time users figure
> out what to do to correct things.  Although the documentation for
> QMP calls out capabilities negotiation, we should also make it
> clear in our error messages what we were expecting.  With this
> patch, I now get the following transcript:
>
> $ ./x86_64-softmmu/qemu-system-x86_64 -qmp stdio -nodefaults
> {"QMP": {"version": {"qemu": {"micro": 93, "minor": 2, "major": 2}, "package": ""}, "capabilities": []}}
> {"execute":"huh"}
> {"error": {"class": "CommandNotFound", "desc": "The command huh has not been found"}}
> {"execute":"quit"}
> {"error": {"class": "CommandNotFound", "desc": "Expecting capabilities negotiation with 'qmp_capabilities' before command 'quit'"}}

Any particular reason why we should keep the "CommandNotFound" error 
class here? Backwards compat? Inertia?

> {"execute":"qmp_capabilities"}
> {"return": {}}
> {"execute":"qmp_capabilities"}
> {"error": {"class": "CommandNotFound", "desc": "Capabilities negotiation is already complete, command 'qmp_capabilities' ignored"}}

Same here.

> {"execute":"quit"}
> {"return": {}}
> {"timestamp": {"seconds": 1429110729, "microseconds": 181935}, "event": "SHUTDOWN"}
>
> Signed-off-by: Eric Blake <eblake@redhat.com>
> ---
>
> Based in part on this thread:
> https://lists.gnu.org/archive/html/qemu-devel/2015-04/msg00831.html
>
>   monitor.c | 23 +++++++++++++++++++----
>   1 file changed, 19 insertions(+), 4 deletions(-)
>
> diff --git a/monitor.c b/monitor.c
> index 68873ec..9f37700 100644
> --- a/monitor.c
> +++ b/monitor.c
> @@ -4783,10 +4783,22 @@ static int monitor_can_read(void *opaque)
>       return (mon->suspend_cnt == 0) ? 1 : 0;
>   }
>
> -static int invalid_qmp_mode(const Monitor *mon, const mon_cmd_t *cmd)
> +static bool invalid_qmp_mode(const Monitor *mon, const mon_cmd_t *cmd)
>   {
> -    int is_cap = cmd->mhandler.cmd_new == do_qmp_capabilities;
> -    return (qmp_cmd_mode(mon) ? is_cap : !is_cap);
> +    bool is_cap = cmd->mhandler.cmd_new == do_qmp_capabilities;
> +    if (is_cap && qmp_cmd_mode(mon)) {
> +        qerror_report(ERROR_CLASS_COMMAND_NOT_FOUND,
> +                      "Capabilities negotiation is already complete, command "
> +                      "'%s' ignored", cmd->name);
> +        return true;
> +    }
> +    if (!is_cap && !qmp_cmd_mode(mon)) {
> +        qerror_report(ERROR_CLASS_COMMAND_NOT_FOUND,
> +                      "Expecting capabilities negotiation with "
> +                      "'qmp_capabilities' before command '%s'", cmd->name);
> +        return true;
> +    }
> +    return false;
>   }
>
>   /*
> @@ -5080,11 +5092,14 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens)
>       cmd_name = qdict_get_str(input, "execute");
>       trace_handle_qmp_command(mon, cmd_name);
>       cmd = qmp_find_cmd(cmd_name);
> -    if (!cmd || invalid_qmp_mode(mon, cmd)) {
> +    if (!cmd) {
>           qerror_report(ERROR_CLASS_COMMAND_NOT_FOUND,
>                         "The command %s has not been found", cmd_name);
>           goto err_out;
>       }
> +    if (invalid_qmp_mode(mon, cmd)) {
> +        goto err_out;
> +    }
>
>       obj = qdict_get(input, "arguments");
>       if (!obj) {
>

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Qemu-devel] [PATCH] qmp: Give saner messages related to qmp_capabilities misuse
  2015-04-15 18:13 ` John Snow
@ 2015-04-15 18:31   ` Eric Blake
  2015-04-15 18:33     ` John Snow
  0 siblings, 1 reply; 7+ messages in thread
From: Eric Blake @ 2015-04-15 18:31 UTC (permalink / raw)
  To: John Snow, qemu-devel; +Cc: erik.rull, paulo.vital, lcapitulino

[-- Attachment #1: Type: text/plain, Size: 2045 bytes --]

On 04/15/2015 12:13 PM, John Snow wrote:
> 
> 
> On 04/15/2015 11:19 AM, Eric Blake wrote:
>> Pretending that QMP doesn't understand a command merely because
>> we are not in the right mode doesn't help first-time users figure
>> out what to do to correct things.  Although the documentation for
>> QMP calls out capabilities negotiation, we should also make it
>> clear in our error messages what we were expecting.  With this
>> patch, I now get the following transcript:
>>
>> $ ./x86_64-softmmu/qemu-system-x86_64 -qmp stdio -nodefaults
>> {"QMP": {"version": {"qemu": {"micro": 93, "minor": 2, "major": 2},
>> "package": ""}, "capabilities": []}}
>> {"execute":"huh"}
>> {"error": {"class": "CommandNotFound", "desc": "The command huh has
>> not been found"}}
>> {"execute":"quit"}
>> {"error": {"class": "CommandNotFound", "desc": "Expecting capabilities
>> negotiation with 'qmp_capabilities' before command 'quit'"}}
> 
> Any particular reason why we should keep the "CommandNotFound" error
> class here? Backwards compat? Inertia?
> 
>> {"execute":"qmp_capabilities"}
>> {"return": {}}
>> {"execute":"qmp_capabilities"}
>> {"error": {"class": "CommandNotFound", "desc": "Capabilities
>> negotiation is already complete, command 'qmp_capabilities' ignored"}}
> 
> Same here.

Backwards compat. I can't prove that anyone else was relying on specific
classes (in particular, although it is unlikely that anyone was issuing
qmp_capabilities more than once, or cares what error class was returned,
it IS a useful test for probing if the connection is in capability
negotiation mode when reconnecting to a monitor after a libvirtd
restart).  It's better to be conservative and avoid changing the error
class (which must be reliable to machine readers) and only impact the
error message (which is human readable and is documented to not be
machine parseable, so we can change that at will).

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Qemu-devel] [PATCH] qmp: Give saner messages related to qmp_capabilities misuse
  2015-04-15 18:31   ` Eric Blake
@ 2015-04-15 18:33     ` John Snow
  0 siblings, 0 replies; 7+ messages in thread
From: John Snow @ 2015-04-15 18:33 UTC (permalink / raw)
  To: Eric Blake, qemu-devel; +Cc: erik.rull, paulo.vital, lcapitulino



On 04/15/2015 02:31 PM, Eric Blake wrote:
> On 04/15/2015 12:13 PM, John Snow wrote:
>>
>>
>> On 04/15/2015 11:19 AM, Eric Blake wrote:
>>> Pretending that QMP doesn't understand a command merely because
>>> we are not in the right mode doesn't help first-time users figure
>>> out what to do to correct things.  Although the documentation for
>>> QMP calls out capabilities negotiation, we should also make it
>>> clear in our error messages what we were expecting.  With this
>>> patch, I now get the following transcript:
>>>
>>> $ ./x86_64-softmmu/qemu-system-x86_64 -qmp stdio -nodefaults
>>> {"QMP": {"version": {"qemu": {"micro": 93, "minor": 2, "major": 2},
>>> "package": ""}, "capabilities": []}}
>>> {"execute":"huh"}
>>> {"error": {"class": "CommandNotFound", "desc": "The command huh has
>>> not been found"}}
>>> {"execute":"quit"}
>>> {"error": {"class": "CommandNotFound", "desc": "Expecting capabilities
>>> negotiation with 'qmp_capabilities' before command 'quit'"}}
>>
>> Any particular reason why we should keep the "CommandNotFound" error
>> class here? Backwards compat? Inertia?
>>
>>> {"execute":"qmp_capabilities"}
>>> {"return": {}}
>>> {"execute":"qmp_capabilities"}
>>> {"error": {"class": "CommandNotFound", "desc": "Capabilities
>>> negotiation is already complete, command 'qmp_capabilities' ignored"}}
>>
>> Same here.
>
> Backwards compat. I can't prove that anyone else was relying on specific
> classes (in particular, although it is unlikely that anyone was issuing
> qmp_capabilities more than once, or cares what error class was returned,
> it IS a useful test for probing if the connection is in capability
> negotiation mode when reconnecting to a monitor after a libvirtd
> restart).  It's better to be conservative and avoid changing the error
> class (which must be reliable to machine readers) and only impact the
> error message (which is human readable and is documented to not be
> machine parseable, so we can change that at will).
>

Blast ye, Backwards Compat...

Reviewed-by: John Snow <jsnow@redhat.com>

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Qemu-devel] [PATCH] qmp: Give saner messages related to qmp_capabilities misuse
  2015-04-15 15:19 [Qemu-devel] [PATCH] qmp: Give saner messages related to qmp_capabilities misuse Eric Blake
                   ` (2 preceding siblings ...)
  2015-04-15 18:13 ` John Snow
@ 2015-04-21 14:09 ` Luiz Capitulino
  3 siblings, 0 replies; 7+ messages in thread
From: Luiz Capitulino @ 2015-04-21 14:09 UTC (permalink / raw)
  To: Eric Blake; +Cc: erik.rull, qemu-devel, paulo.vital

On Wed, 15 Apr 2015 09:19:23 -0600
Eric Blake <eblake@redhat.com> wrote:

> Pretending that QMP doesn't understand a command merely because
> we are not in the right mode doesn't help first-time users figure
> out what to do to correct things.  Although the documentation for
> QMP calls out capabilities negotiation, we should also make it
> clear in our error messages what we were expecting.  With this
> patch, I now get the following transcript:
> 
> $ ./x86_64-softmmu/qemu-system-x86_64 -qmp stdio -nodefaults
> {"QMP": {"version": {"qemu": {"micro": 93, "minor": 2, "major": 2}, "package": ""}, "capabilities": []}}
> {"execute":"huh"}
> {"error": {"class": "CommandNotFound", "desc": "The command huh has not been found"}}
> {"execute":"quit"}
> {"error": {"class": "CommandNotFound", "desc": "Expecting capabilities negotiation with 'qmp_capabilities' before command 'quit'"}}
> {"execute":"qmp_capabilities"}
> {"return": {}}
> {"execute":"qmp_capabilities"}
> {"error": {"class": "CommandNotFound", "desc": "Capabilities negotiation is already complete, command 'qmp_capabilities' ignored"}}
> {"execute":"quit"}
> {"return": {}}
> {"timestamp": {"seconds": 1429110729, "microseconds": 181935}, "event": "SHUTDOWN"}
> 
> Signed-off-by: Eric Blake <eblake@redhat.com>

Applied to the qmp branch, thanks.

> ---
> 
> Based in part on this thread:
> https://lists.gnu.org/archive/html/qemu-devel/2015-04/msg00831.html
> 
>  monitor.c | 23 +++++++++++++++++++----
>  1 file changed, 19 insertions(+), 4 deletions(-)
> 
> diff --git a/monitor.c b/monitor.c
> index 68873ec..9f37700 100644
> --- a/monitor.c
> +++ b/monitor.c
> @@ -4783,10 +4783,22 @@ static int monitor_can_read(void *opaque)
>      return (mon->suspend_cnt == 0) ? 1 : 0;
>  }
> 
> -static int invalid_qmp_mode(const Monitor *mon, const mon_cmd_t *cmd)
> +static bool invalid_qmp_mode(const Monitor *mon, const mon_cmd_t *cmd)
>  {
> -    int is_cap = cmd->mhandler.cmd_new == do_qmp_capabilities;
> -    return (qmp_cmd_mode(mon) ? is_cap : !is_cap);
> +    bool is_cap = cmd->mhandler.cmd_new == do_qmp_capabilities;
> +    if (is_cap && qmp_cmd_mode(mon)) {
> +        qerror_report(ERROR_CLASS_COMMAND_NOT_FOUND,
> +                      "Capabilities negotiation is already complete, command "
> +                      "'%s' ignored", cmd->name);
> +        return true;
> +    }
> +    if (!is_cap && !qmp_cmd_mode(mon)) {
> +        qerror_report(ERROR_CLASS_COMMAND_NOT_FOUND,
> +                      "Expecting capabilities negotiation with "
> +                      "'qmp_capabilities' before command '%s'", cmd->name);
> +        return true;
> +    }
> +    return false;
>  }
> 
>  /*
> @@ -5080,11 +5092,14 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens)
>      cmd_name = qdict_get_str(input, "execute");
>      trace_handle_qmp_command(mon, cmd_name);
>      cmd = qmp_find_cmd(cmd_name);
> -    if (!cmd || invalid_qmp_mode(mon, cmd)) {
> +    if (!cmd) {
>          qerror_report(ERROR_CLASS_COMMAND_NOT_FOUND,
>                        "The command %s has not been found", cmd_name);
>          goto err_out;
>      }
> +    if (invalid_qmp_mode(mon, cmd)) {
> +        goto err_out;
> +    }
> 
>      obj = qdict_get(input, "arguments");
>      if (!obj) {

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2015-04-21 14:10 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-04-15 15:19 [Qemu-devel] [PATCH] qmp: Give saner messages related to qmp_capabilities misuse Eric Blake
2015-04-15 16:07 ` Kashyap Chamarthy
2015-04-15 16:30 ` Paulo Ricardo Paz Vital
2015-04-15 18:13 ` John Snow
2015-04-15 18:31   ` Eric Blake
2015-04-15 18:33     ` John Snow
2015-04-21 14:09 ` Luiz Capitulino

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.