qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Luiz Capitulino <lcapitulino@redhat.com>
To: qemu-devel@nongnu.org
Cc: kwolf@redhat.com, aliguori@us.ibm.com, armbru@redhat.com,
	mdroth@linux.vnet.ibm.com, pbonzini@redhat.com,
	eblake@redhat.com
Subject: [Qemu-devel] [PATCH 29/35] qmp: switch to the new error format on the wire
Date: Fri, 10 Aug 2012 14:44:07 -0300	[thread overview]
Message-ID: <1344620653-29067-30-git-send-email-lcapitulino@redhat.com> (raw)
In-Reply-To: <1344620653-29067-1-git-send-email-lcapitulino@redhat.com>

IMPORTANT: this BREAKS QMP's compatibility for the error response.

This commit changes QMP's wire protocol to make use of the simpler
error format introduced by previous commits.

There are two important (and mostly incompatible) changes:

 1. Almost all error classes have been replaced by GenericError. The
    only classes that are still supported for compatibility with
    libvirt are: CommandNotFound, DeviceNotActive, KVMMissingCap,
    DeviceNotFound and MigrationExpected

 2. The 'data' field of the error dictionary is gone

As an example, an error response like:

  { "error": { "class": "DeviceNotRemovable",
               "data": { "device": "virtio0" },
               "desc": "Device 'virtio0' is not removable" } }

Will now be emitted as:

  { "error": { "class": "GenericError",
               "desc": "Device 'virtio0' is not removable" } }

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
 QMP/qmp-spec.txt | 10 +++-------
 monitor.c        | 18 +++++++++++++-----
 qapi-schema.json | 55 -------------------------------------------------------
 qmp-commands.hx  |  4 ++--
 4 files changed, 18 insertions(+), 69 deletions(-)

diff --git a/QMP/qmp-spec.txt b/QMP/qmp-spec.txt
index 1ba916c..a277896 100644
--- a/QMP/qmp-spec.txt
+++ b/QMP/qmp-spec.txt
@@ -106,14 +106,11 @@ completed because of an error condition.
 
 The format is:
 
-{ "error": { "class": json-string, "data": json-object, "desc": json-string },
-  "id": json-value }
+{ "error": { "class": json-string, "desc": json-string }, "id": json-value }
 
  Where,
 
-- The "class" member contains the error class name (eg. "ServiceUnavailable")
-- The "data" member contains specific error data and is defined in a
-  per-command basis, it will be an empty json-object if the error has no data
+- The "class" member contains the error class name (eg. "GenericError")
 - The "desc" member is a human-readable error message. Clients should
   not attempt to parse this message.
 - The "id" member contains the transaction identification associated with
@@ -173,8 +170,7 @@ S: {"return": {"enabled": true, "present": true}, "id": "example"}
 ------------------
 
 C: { "execute": }
-S: {"error": {"class": "JSONParsing", "desc": "Invalid JSON syntax", "data":
-{}}}
+S: {"error": {"class": "GenericError", "desc": "Invalid JSON syntax" } }
 
 3.5 Powerdown event
 -------------------
diff --git a/monitor.c b/monitor.c
index aa57167..3694590 100644
--- a/monitor.c
+++ b/monitor.c
@@ -353,16 +353,26 @@ static void monitor_json_emitter(Monitor *mon, const QObject *data)
     QDECREF(json);
 }
 
+static QDict *build_qmp_error_dict(const QError *err)
+{
+    QObject *obj;
+
+    obj = qobject_from_jsonf("{ 'error': { 'class': %s, 'desc': %p } }",
+                             ErrorClass_lookup[err->err_class],
+                             qerror_human(err));
+
+    return qobject_to_qdict(obj);
+}
+
 static void monitor_protocol_emitter(Monitor *mon, QObject *data)
 {
     QDict *qmp;
 
     trace_monitor_protocol_emitter(mon);
 
-    qmp = qdict_new();
-
     if (!monitor_has_error(mon)) {
         /* success response */
+        qmp = qdict_new();
         if (data) {
             qobject_incref(data);
             qdict_put_obj(qmp, "return", data);
@@ -372,9 +382,7 @@ static void monitor_protocol_emitter(Monitor *mon, QObject *data)
         }
     } else {
         /* error response */
-        qdict_put(mon->error->error, "desc", qerror_human(mon->error));
-        qdict_put(qmp, "error", mon->error->error);
-        QINCREF(mon->error->error);
+        qmp = build_qmp_error_dict(mon->error);
         QDECREF(mon->error);
         mon->error = NULL;
     }
diff --git a/qapi-schema.json b/qapi-schema.json
index b513935..ec8d919 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -658,7 +658,6 @@
 # Returns information about the current VNC server
 #
 # Returns: @VncInfo
-#          If VNC support is not compiled in, FeatureDisabled
 #
 # Since: 0.14.0
 ##
@@ -1042,9 +1041,6 @@
 #                       virtual address (defaults to CPU 0)
 #
 # Returns: Nothing on success
-#          If @cpu is not a valid VCPU, InvalidParameterValue
-#          If @filename cannot be opened, OpenFileFailed
-#          If an I/O error occurs while writing the file, IOError
 #
 # Since: 0.14.0
 #
@@ -1065,8 +1061,6 @@
 # @filename: the file to save the memory to as binary data
 #
 # Returns: Nothing on success
-#          If @filename cannot be opened, OpenFileFailed
-#          If an I/O error occurs while writing the file, IOError
 #
 # Since: 0.14.0
 #
@@ -1108,7 +1102,6 @@
 # Injects an Non-Maskable Interrupt into all guest's VCPUs.
 #
 # Returns:  If successful, nothing
-#           If the Virtual Machine doesn't support NMI injection, Unsupported
 #
 # Since:  0.14.0
 #
@@ -1159,7 +1152,6 @@
 # Returns: nothing on success
 #          If @device is not a valid block device, DeviceNotFound
 #          If @device is not encrypted, DeviceNotEncrypted
-#          If @password is not valid for this device, InvalidPassword
 #
 # Notes:  Not all block formats support encryption and some that do are not
 #         able to validate that a password is correct.  Disk corruption may
@@ -1200,11 +1192,6 @@
 #
 # Returns: nothing on success
 #          If @device is not a valid block device, DeviceNotFound
-#          If @size is negative, InvalidParameterValue
-#          If the block device has no medium inserted, DeviceHasNoMedium
-#          If the block device does not support resize, Unsupported
-#          If the block device is read-only, DeviceIsReadOnly
-#          If a long-running operation is using the device, DeviceInUse
 #
 # Since: 0.14.0
 ##
@@ -1266,10 +1253,6 @@
 #
 # Returns: nothing on success
 #          If @device is not a valid block device, DeviceNotFound
-#          If @device is busy, DeviceInUse will be returned
-#          If @snapshot-file can't be created, OpenFileFailed
-#          If @snapshot-file can't be opened, OpenFileFailed
-#          If @format is invalid, InvalidBlockFormat
 #
 # Note: The transaction aborts on the first failure.  Therefore, there will
 # be only one device or snapshot file returned in an error condition, and
@@ -1298,8 +1281,6 @@
 #
 # Returns: nothing on success
 #          If @device is not a valid block device, DeviceNotFound
-#          If @snapshot-file can't be opened, OpenFileFailed
-#          If @format is invalid, InvalidBlockFormat
 #
 # Since 0.14.0
 ##
@@ -1501,11 +1482,6 @@
 #
 # Returns: Nothing on success
 #          If Spice is not enabled, DeviceNotFound
-#          If @protocol does not support connected, InvalidParameter
-#          If @protocol is invalid, InvalidParameter
-#          If any other error occurs, SetPasswdFailed
-#
-# Notes: If VNC is not enabled, SetPasswdFailed is returned.
 #
 # Since: 0.14.0
 ##
@@ -1527,8 +1503,6 @@
 #
 # Returns: Nothing on success
 #          If @protocol is `spice' and Spice is not active, DeviceNotFound
-#          If an error occurs setting password expiration, SetPasswdFailed
-#          If @protocol is not `spice' or 'vnc', InvalidParameter
 #
 # Since: 0.14.0
 #
@@ -1551,8 +1525,6 @@
 #
 # Returns:  Nothing on success
 #           If @device is not a valid block device, DeviceNotFound
-#           If @device is not removable and @force is false, DeviceNotRemovable
-#           If @force is false and @device is locked, DeviceLocked
 #
 # Notes:    Ejecting a device will no media results in success
 #
@@ -1595,7 +1567,6 @@
 #
 # Returns: Nothing on success.
 #          If @device is not a valid block device, DeviceNotFound
-#          If @format is not a valid block format, InvalidBlockFormat
 #          If the new block device is encrypted, DeviceEncrypted.  Note that
 #          if this error is returned, the device has been opened successfully
 #          and an additional call to @block_passwd is required to set the
@@ -1631,7 +1602,6 @@
 #
 # Returns: Nothing on success
 #          If @device is not a valid block device, DeviceNotFound
-#          If the argument combination is invalid, InvalidParameterCombination
 #
 # Since: 1.1
 ##
@@ -1665,11 +1635,7 @@
 # @speed:  #optional the maximum speed, in bytes per second
 #
 # Returns: Nothing on success
-#          If streaming is already active on this device, DeviceInUse
 #          If @device does not exist, DeviceNotFound
-#          If image streaming is not supported by this device, NotSupported
-#          If @base does not exist, BaseNotFound
-#          If @speed is invalid, InvalidParameter
 #
 # Since: 1.1
 ##
@@ -1691,8 +1657,6 @@
 #          Defaults to 0.
 #
 # Returns: Nothing on success
-#          If the job type does not support throttling, NotSupported
-#          If the speed value is invalid, InvalidParameter
 #          If no background operation is active on this device, DeviceNotActive
 #
 # Since: 1.1
@@ -1722,7 +1686,6 @@
 #
 # Returns: Nothing on success
 #          If no background operation is active on this device, DeviceNotActive
-#          If cancellation already in progress, DeviceInUse
 #
 # Since: 1.1
 ##
@@ -1792,8 +1755,6 @@
 # format.
 #
 # Returns: Nothing on success
-#          If @filename cannot be opened, OpenFileFailed
-#          If an I/O error occurs while writing the file, IOError
 #
 # Since: 1.1
 ##
@@ -1808,7 +1769,6 @@
 #
 # Returns: Nothing on success
 #          If @id is not a valid device, DeviceNotFound
-#          If the device does not support unplug, BusNoHotplug
 #
 # Notes: When this command completes, the device may not be removed from the
 #        guest.  Hot removal is an operation that requires guest cooperation.
@@ -1849,14 +1809,6 @@
 # want to dump all guest's memory, please specify the start @begin and @length
 #
 # Returns: nothing on success
-#          If @begin contains an invalid address, InvalidParameter
-#          If only one of @begin and @length is specified, MissingParameter
-#          If @protocol stats with "fd:", and the fd cannot be found, FdNotFound
-#          If @protocol starts with "file:", and the file cannot be
-#             opened, OpenFileFailed
-#          If @protocol does not start with "fd:" or "file:", InvalidParameter
-#          If an I/O error occurs while writing the file, IOError
-#          If the target does not support this command, Unsupported
 #
 # Since: 1.2
 ##
@@ -1883,10 +1835,6 @@
 #
 # Returns: Nothing on success
 #          If @type is not a valid network backend, DeviceNotFound
-#          If @id is not a valid identifier, InvalidParameterValue
-#          if @id already exists, DuplicateId
-#          If @props contains an invalid parameter for this backend,
-#            InvalidParameter
 ##
 { 'command': 'netdev_add',
   'data': {'type': 'str', 'id': 'str', '*props': '**'},
@@ -2206,8 +2154,6 @@
 # @fdname: file descriptor name
 #
 # Returns: Nothing on success
-#          If file descriptor was not received, FdNotSupplied
-#          If @fdname is not valid, InvalidParameterType
 #
 # Since: 0.14.0
 #
@@ -2227,7 +2173,6 @@
 # @fdname: file descriptor name
 #
 # Returns: Nothing on success
-#          If @fdname is not found, FdNotFound
 #
 # Since: 0.14.0
 ##
diff --git a/qmp-commands.hx b/qmp-commands.hx
index ac46638..e07c7b0 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -435,8 +435,8 @@ Example:
 -> { "execute": "inject-nmi" }
 <- { "return": {} }
 
-Note: inject-nmi is only supported for x86 guest currently, it will
-      returns "Unsupported" error for non-x86 guest.
+Note: inject-nmi fails when the guest doesn't support injecting.
+      Currently, only x86 guests do.
 
 EQMP
 
-- 
1.7.11.2.249.g31c7954.dirty

  parent reply	other threads:[~2012-08-10 17:45 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-08-10 17:43 [Qemu-devel] [PATCH v3 00/35]: add new error format Luiz Capitulino
2012-08-10 17:43 ` [Qemu-devel] [PATCH 01/35] monitor: drop unused monitor debug code Luiz Capitulino
2012-08-10 17:43 ` [Qemu-devel] [PATCH 02/35] qerror: QERR_AMBIGUOUS_PATH: drop %(object) from human msg Luiz Capitulino
2012-08-10 17:43 ` [Qemu-devel] [PATCH 03/35] qerror: QERR_DEVICE_ENCRYPTED: change error message Luiz Capitulino
2012-08-10 17:43 ` [Qemu-devel] [PATCH 04/35] qerror: reduce public exposure Luiz Capitulino
2012-08-10 17:43 ` [Qemu-devel] [PATCH 05/35] qerror: drop qerror_abort() Luiz Capitulino
2012-08-10 17:43 ` [Qemu-devel] [PATCH 06/35] qerror: avoid passing qerr pointer Luiz Capitulino
2012-08-10 17:43 ` [Qemu-devel] [PATCH 07/35] qerror: QError: drop file, linenr, func Luiz Capitulino
2012-08-10 17:43 ` [Qemu-devel] [PATCH 08/35] qerror: qerror_format(): return an allocated string Luiz Capitulino
2012-08-10 17:43 ` [Qemu-devel] [PATCH 09/35] qerror: don't delay error message construction Luiz Capitulino
2012-08-10 17:43 ` [Qemu-devel] [PATCH 10/35] error: " Luiz Capitulino
2012-08-10 17:43 ` [Qemu-devel] [PATCH 11/35] qmp: query-block: add 'encryption_key_missing' field Luiz Capitulino
2012-08-10 17:43 ` [Qemu-devel] [PATCH 12/35] hmp: hmp_cont(): don't rely on QERR_DEVICE_ENCRYPTED Luiz Capitulino
2012-08-10 17:43 ` [Qemu-devel] [PATCH 13/35] hmp_change(): don't access DeviceEncrypted's data Luiz Capitulino
2012-08-10 17:43 ` [Qemu-devel] [PATCH 14/35] net: inet_connect(), inet_connect_opts(): add in_progress argument Luiz Capitulino
2012-08-10 17:43 ` [Qemu-devel] [PATCH 15/35] migration: don't rely on any QERR_SOCKET_* Luiz Capitulino
2012-08-10 17:43 ` [Qemu-devel] [PATCH 16/35] qerror: drop QERR_SOCKET_CONNECT_IN_PROGRESS Luiz Capitulino
2012-08-10 17:43 ` [Qemu-devel] [PATCH 17/35] block: block_int: include qerror.h Luiz Capitulino
2012-08-10 17:43 ` [Qemu-devel] [PATCH 18/35] hmp: hmp.h: include qdict.h Luiz Capitulino
2012-08-10 17:43 ` [Qemu-devel] [PATCH 19/35] qapi: qapi-types.h: don't include qapi/qapi-types-core.h Luiz Capitulino
2012-08-10 17:43 ` [Qemu-devel] [PATCH 20/35] qapi: generate correct enum names for camel case enums Luiz Capitulino
2012-08-10 17:43 ` [Qemu-devel] [PATCH 21/35] qapi: don't convert enum strings to lowercase Luiz Capitulino
2012-08-10 17:44 ` [Qemu-devel] [PATCH 22/35] qapi-schema: add ErrorClass enum Luiz Capitulino
2012-08-10 17:44 ` [Qemu-devel] [PATCH 23/35] qerror: qerror_table: don't use C99 struct initializers Luiz Capitulino
2012-08-10 17:44 ` [Qemu-devel] [PATCH 24/35] error, qerror: add ErrorClass argument to error functions Luiz Capitulino
2012-08-10 17:44 ` [Qemu-devel] [PATCH 25/35] qerror: add proper ErrorClass value for QERR_ macros Luiz Capitulino
2012-08-10 17:44 ` [Qemu-devel] [PATCH 26/35] error: add error_get_class() Luiz Capitulino
2012-08-10 17:44 ` [Qemu-devel] [PATCH 27/35] hmp: hmp_change(): use error_get_class() Luiz Capitulino
2012-08-10 17:44 ` [Qemu-devel] [PATCH 28/35] error: drop unused functions Luiz Capitulino
2012-08-10 19:42   ` Eric Blake
2012-08-10 17:44 ` Luiz Capitulino [this message]
2012-08-10 17:44 ` [Qemu-devel] [PATCH 30/35] qemu-ga: switch to the new error format on the wire Luiz Capitulino
2012-08-10 17:44 ` [Qemu-devel] [PATCH 31/35] error: drop error_get_qobject()/error_set_qobject() Luiz Capitulino
2012-08-10 17:44 ` [Qemu-devel] [PATCH 32/35] error, qerror: pass desc string to error calls Luiz Capitulino
2012-08-10 17:44 ` [Qemu-devel] [PATCH 33/35] qerror: drop qerror_table and qerror_format() Luiz Capitulino
2012-08-10 17:44 ` [Qemu-devel] [PATCH 34/35] error, qerror: drop QDict member Luiz Capitulino
2012-08-10 17:44 ` [Qemu-devel] [PATCH 35/35] docs: writing-qmp-commands.txt: update error section Luiz Capitulino
2012-08-11  7:05 ` [Qemu-devel] [PATCH v3 00/35]: add new error format Markus Armbruster
2012-08-13 13:32   ` Luiz Capitulino
  -- strict thread matches above, loose matches on Subject: below --
2012-08-07 15:53 [Qemu-devel] [PATCH v2 " Luiz Capitulino
2012-08-07 15:53 ` [Qemu-devel] [PATCH 29/35] qmp: switch to the new error format on the wire Luiz Capitulino

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=1344620653-29067-30-git-send-email-lcapitulino@redhat.com \
    --to=lcapitulino@redhat.com \
    --cc=aliguori@us.ibm.com \
    --cc=armbru@redhat.com \
    --cc=eblake@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=mdroth@linux.vnet.ibm.com \
    --cc=pbonzini@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).