qapi: First integration of qapi definitions.

Brings headers (and some sources) related to the QEMU object
model up to date with regards to upstream. Note that this misses
several implementation files which are currently not used.

Also misses qemu/cpu.h since it defines CPUState in a completely
different way than our current sources.

Change-Id: I8ece10ff9fcab28cb2e7de3493be21b793b3c98a
diff --git a/include/qapi/dealloc-visitor.h b/include/qapi/dealloc-visitor.h
new file mode 100644
index 0000000..cf4c36d
--- /dev/null
+++ b/include/qapi/dealloc-visitor.h
@@ -0,0 +1,26 @@
+/*
+ * Dealloc Visitor
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ *  Michael Roth   <mdroth@linux.vnet.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#ifndef QAPI_DEALLOC_VISITOR_H
+#define QAPI_DEALLOC_VISITOR_H
+
+#include "qapi/visitor.h"
+
+typedef struct QapiDeallocVisitor QapiDeallocVisitor;
+
+QapiDeallocVisitor *qapi_dealloc_visitor_new(void);
+void qapi_dealloc_visitor_cleanup(QapiDeallocVisitor *d);
+
+Visitor *qapi_dealloc_get_visitor(QapiDeallocVisitor *v);
+
+#endif
diff --git a/include/qapi/error.h b/include/qapi/error.h
new file mode 100644
index 0000000..7d4c696
--- /dev/null
+++ b/include/qapi/error.h
@@ -0,0 +1,98 @@
+/*
+ * QEMU Error Objects
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ *  Anthony Liguori   <aliguori@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.  See
+ * the COPYING.LIB file in the top-level directory.
+ */
+#ifndef ERROR_H
+#define ERROR_H
+
+#include "qemu/compiler.h"
+#include "qapi-types.h"
+#include <stdbool.h>
+
+/**
+ * A class representing internal errors within QEMU.  An error has a ErrorClass
+ * code and a human message.
+ */
+typedef struct Error Error;
+
+/**
+ * Set an indirect pointer to an error given a ErrorClass value and a
+ * printf-style human message.  This function is not meant to be used outside
+ * of QEMU.
+ */
+void error_set(Error **err, ErrorClass err_class, const char *fmt, ...) GCC_FMT_ATTR(3, 4);
+
+/**
+ * Set an indirect pointer to an error given a ErrorClass value and a
+ * printf-style human message, followed by a strerror() string if
+ * @os_error is not zero.
+ */
+void error_set_errno(Error **err, int os_error, ErrorClass err_class, const char *fmt, ...) GCC_FMT_ATTR(4, 5);
+
+#ifdef _WIN32
+/**
+ * Set an indirect pointer to an error given a ErrorClass value and a
+ * printf-style human message, followed by a g_win32_error_message() string if
+ * @win32_err is not zero.
+ */
+void error_set_win32(Error **err, int win32_err, ErrorClass err_class, const char *fmt, ...) GCC_FMT_ATTR(4, 5);
+#endif
+
+/**
+ * Same as error_set(), but sets a generic error
+ */
+#define error_setg(err, fmt, ...) \
+    error_set(err, ERROR_CLASS_GENERIC_ERROR, fmt, ## __VA_ARGS__)
+#define error_setg_errno(err, os_error, fmt, ...) \
+    error_set_errno(err, os_error, ERROR_CLASS_GENERIC_ERROR, fmt, ## __VA_ARGS__)
+#ifdef _WIN32
+#define error_setg_win32(err, win32_err, fmt, ...) \
+    error_set_win32(err, win32_err, ERROR_CLASS_GENERIC_ERROR, fmt, ## __VA_ARGS__)
+#endif
+
+/**
+ * Helper for open() errors
+ */
+void error_setg_file_open(Error **errp, int os_errno, const char *filename);
+
+/**
+ * Returns true if an indirect pointer to an error is pointing to a valid
+ * error object.
+ */
+bool error_is_set(Error **err);
+
+/*
+ * Get the error class of an error object.
+ */
+ErrorClass error_get_class(const Error *err);
+
+/**
+ * Returns an exact copy of the error passed as an argument.
+ */
+Error *error_copy(const Error *err);
+
+/**
+ * Get a human readable representation of an error object.
+ */
+const char *error_get_pretty(Error *err);
+
+/**
+ * Propagate an error to an indirect pointer to an error.  This function will
+ * always transfer ownership of the error reference and handles the case where
+ * dst_err is NULL correctly.  Errors after the first are discarded.
+ */
+void error_propagate(Error **dst_err, Error *local_err);
+
+/**
+ * Free an error object.
+ */
+void error_free(Error *err);
+
+#endif
diff --git a/include/qapi/opts-visitor.h b/include/qapi/opts-visitor.h
new file mode 100644
index 0000000..fd48c14
--- /dev/null
+++ b/include/qapi/opts-visitor.h
@@ -0,0 +1,37 @@
+/*
+ * Options Visitor
+ *
+ * Copyright Red Hat, Inc. 2012
+ *
+ * Author: Laszlo Ersek <lersek@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#ifndef OPTS_VISITOR_H
+#define OPTS_VISITOR_H
+
+#include "qapi/visitor.h"
+#include "qemu/option.h"
+
+/* Inclusive upper bound on the size of any flattened range. This is a safety
+ * (= anti-annoyance) measure; wrong ranges should not cause long startup
+ * delays nor exhaust virtual memory.
+ */
+#define OPTS_VISITOR_RANGE_MAX 65536
+
+typedef struct OptsVisitor OptsVisitor;
+
+/* Contrarily to qemu-option.c::parse_option_number(), OptsVisitor's "int"
+ * parser relies on strtoll() instead of strtoull(). Consequences:
+ * - string representations of negative numbers yield negative values,
+ * - values below INT64_MIN or LLONG_MIN are rejected,
+ * - values above INT64_MAX or LLONG_MAX are rejected.
+ */
+OptsVisitor *opts_visitor_new(const QemuOpts *opts);
+void opts_visitor_cleanup(OptsVisitor *nv);
+Visitor *opts_get_visitor(OptsVisitor *nv);
+
+#endif
diff --git a/include/qapi/qmp-input-visitor.h b/include/qapi/qmp-input-visitor.h
new file mode 100644
index 0000000..3ed499c
--- /dev/null
+++ b/include/qapi/qmp-input-visitor.h
@@ -0,0 +1,29 @@
+/*
+ * Input Visitor
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ *  Anthony Liguori   <aliguori@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#ifndef QMP_INPUT_VISITOR_H
+#define QMP_INPUT_VISITOR_H
+
+#include "qapi/visitor.h"
+#include "qapi/qmp/qobject.h"
+
+typedef struct QmpInputVisitor QmpInputVisitor;
+
+QmpInputVisitor *qmp_input_visitor_new(QObject *obj);
+QmpInputVisitor *qmp_input_visitor_new_strict(QObject *obj);
+
+void qmp_input_visitor_cleanup(QmpInputVisitor *v);
+
+Visitor *qmp_input_get_visitor(QmpInputVisitor *v);
+
+#endif
diff --git a/include/qapi/qmp-output-visitor.h b/include/qapi/qmp-output-visitor.h
new file mode 100644
index 0000000..2266770
--- /dev/null
+++ b/include/qapi/qmp-output-visitor.h
@@ -0,0 +1,28 @@
+/*
+ * Output Visitor
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ *  Anthony Liguori   <aliguori@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#ifndef QMP_OUTPUT_VISITOR_H
+#define QMP_OUTPUT_VISITOR_H
+
+#include "qapi/visitor.h"
+#include "qapi/qmp/qobject.h"
+
+typedef struct QmpOutputVisitor QmpOutputVisitor;
+
+QmpOutputVisitor *qmp_output_visitor_new(void);
+void qmp_output_visitor_cleanup(QmpOutputVisitor *v);
+
+QObject *qmp_output_get_qobject(QmpOutputVisitor *v);
+Visitor *qmp_output_get_visitor(QmpOutputVisitor *v);
+
+#endif
diff --git a/include/qapi/qmp/dispatch.h b/include/qapi/qmp/dispatch.h
new file mode 100644
index 0000000..cea3818
--- /dev/null
+++ b/include/qapi/qmp/dispatch.h
@@ -0,0 +1,58 @@
+/*
+ * Core Definitions for QAPI/QMP Dispatch
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ *  Anthony Liguori   <aliguori@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#ifndef QMP_CORE_H
+#define QMP_CORE_H
+
+#include "qapi/qmp/qobject.h"
+#include "qapi/qmp/qdict.h"
+#include "qapi/error.h"
+
+typedef void (QmpCommandFunc)(QDict *, QObject **, Error **);
+
+typedef enum QmpCommandType
+{
+    QCT_NORMAL,
+} QmpCommandType;
+
+typedef enum QmpCommandOptions
+{
+    QCO_NO_OPTIONS = 0x0,
+    QCO_NO_SUCCESS_RESP = 0x1,
+} QmpCommandOptions;
+
+typedef struct QmpCommand
+{
+    const char *name;
+    QmpCommandType type;
+    QmpCommandFunc *fn;
+    QmpCommandOptions options;
+    QTAILQ_ENTRY(QmpCommand) node;
+    bool enabled;
+} QmpCommand;
+
+void qmp_register_command(const char *name, QmpCommandFunc *fn,
+                          QmpCommandOptions options);
+QmpCommand *qmp_find_command(const char *name);
+QObject *qmp_dispatch(QObject *request);
+void qmp_disable_command(const char *name);
+void qmp_enable_command(const char *name);
+bool qmp_command_is_enabled(const QmpCommand *cmd);
+const char *qmp_command_name(const QmpCommand *cmd);
+bool qmp_has_success_response(const QmpCommand *cmd);
+QObject *qmp_build_error_object(Error *errp);
+typedef void (*qmp_cmd_callback_fn)(QmpCommand *cmd, void *opaque);
+void qmp_for_each_command(qmp_cmd_callback_fn fn, void *opaque);
+
+#endif
+
diff --git a/include/qapi/qmp/json-lexer.h b/include/qapi/qmp/json-lexer.h
index cd81943..cdff046 100644
--- a/include/qapi/qmp/json-lexer.h
+++ b/include/qapi/qmp/json-lexer.h
@@ -25,6 +25,7 @@
     JSON_STRING,
     JSON_ESCAPE,
     JSON_SKIP,
+    JSON_ERROR,
 } JSONTokenType;
 
 typedef struct JSONLexer JSONLexer;
diff --git a/include/qapi/qmp/json-parser.h b/include/qapi/qmp/json-parser.h
index 1bbac16..44d88f3 100644
--- a/include/qapi/qmp/json-parser.h
+++ b/include/qapi/qmp/json-parser.h
@@ -16,7 +16,9 @@
 
 #include "qemu-common.h"
 #include "qapi/qmp/qlist.h"
+#include "qapi/error.h"
 
 QObject *json_parser_parse(QList *tokens, va_list *ap);
+QObject *json_parser_parse_err(QList *tokens, va_list *ap, Error **errp);
 
 #endif
diff --git a/include/qapi/qmp/json-streamer.h b/include/qapi/qmp/json-streamer.h
index 209b0ec..823f7d7 100644
--- a/include/qapi/qmp/json-streamer.h
+++ b/include/qapi/qmp/json-streamer.h
@@ -24,6 +24,7 @@
     int brace_count;
     int bracket_count;
     QList *tokens;
+    uint64_t token_size;
 } JSONMessageParser;
 
 void json_message_parser_init(JSONMessageParser *parser,
diff --git a/include/qapi/qmp/qdict.h b/include/qapi/qmp/qdict.h
index 6d9a4be..5cefd80 100644
--- a/include/qapi/qmp/qdict.h
+++ b/include/qapi/qmp/qdict.h
@@ -64,4 +64,9 @@
 int qdict_get_try_bool(const QDict *qdict, const char *key, int def_value);
 const char *qdict_get_try_str(const QDict *qdict, const char *key);
 
+QDict *qdict_clone_shallow(const QDict *src);
+void qdict_flatten(QDict *qdict);
+
+void qdict_extract_subqdict(QDict *src, QDict **dst, const char *start);
+
 #endif /* QDICT_H */
diff --git a/include/qapi/qmp/qerror.h b/include/qapi/qmp/qerror.h
index 3b51948..c30c2f6 100644
--- a/include/qapi/qmp/qerror.h
+++ b/include/qapi/qmp/qerror.h
@@ -15,163 +15,235 @@
 #include "qapi/qmp/qdict.h"
 #include "qapi/qmp/qstring.h"
 #include "qemu/error-report.h"
+#include "qapi/error.h"
+#include "qapi-types.h"
 #include <stdarg.h>
 
-typedef struct QErrorStringTable {
-    const char *desc;
-    const char *error_fmt;
-} QErrorStringTable;
-
 typedef struct QError {
     QObject_HEAD;
-    QDict *error;
     Location loc;
-    int linenr;
-    const char *file;
-    const char *func;
-    const QErrorStringTable *entry;
+    char *err_msg;
+    ErrorClass err_class;
 } QError;
 
-QError *qerror_new(void);
-QError *qerror_from_info(const char *file, int linenr, const char *func,
-                         const char *fmt, va_list *va) GCC_FMT_ATTR(4, 0);
 QString *qerror_human(const QError *qerror);
-void qerror_print(QError *qerror);
-void qerror_report_internal(const char *file, int linenr, const char *func,
-                            const char *fmt, ...) GCC_FMT_ATTR(4, 5);
-#define qerror_report(fmt, ...) \
-    qerror_report_internal(__FILE__, __LINE__, __func__, fmt, ## __VA_ARGS__)
-QError *qobject_to_qerror(const QObject *obj);
+void qerror_report(ErrorClass err_class, const char *fmt, ...) GCC_FMT_ATTR(2, 3);
+void qerror_report_err(Error *err);
+void assert_no_error(Error *err);
 
 /*
  * QError class list
  * Please keep the definitions in alphabetical order.
- * Use "grep '^#define QERR_' qerror.h | sort -c" to check.
+ * Use scripts/check-qerror.sh to check.
  */
-#define QERR_BAD_BUS_FOR_DEVICE \
-    "{ 'class': 'BadBusForDevice', 'data': { 'device': %s, 'bad_bus_type': %s } }"
+#define QERR_ADD_CLIENT_FAILED \
+    ERROR_CLASS_GENERIC_ERROR, "Could not add client"
 
-#define QERR_BUS_NOT_FOUND \
-    "{ 'class': 'BusNotFound', 'data': { 'bus': %s } }"
+#define QERR_AMBIGUOUS_PATH \
+    ERROR_CLASS_GENERIC_ERROR, "Path '%s' does not uniquely identify an object"
+
+#define QERR_BAD_BUS_FOR_DEVICE \
+    ERROR_CLASS_GENERIC_ERROR, "Device '%s' can't go on a %s bus"
+
+#define QERR_BASE_NOT_FOUND \
+    ERROR_CLASS_GENERIC_ERROR, "Base '%s' not found"
+
+#define QERR_BLOCK_JOB_NOT_ACTIVE \
+    ERROR_CLASS_DEVICE_NOT_ACTIVE, "No active block job on device '%s'"
+
+#define QERR_BLOCK_JOB_PAUSED \
+    ERROR_CLASS_GENERIC_ERROR, "The block job for device '%s' is currently paused"
+
+#define QERR_BLOCK_JOB_NOT_READY \
+    ERROR_CLASS_GENERIC_ERROR, "The active block job for device '%s' cannot be completed"
+
+#define QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED \
+    ERROR_CLASS_GENERIC_ERROR, "Block format '%s' used by device '%s' does not support feature '%s'"
+
+#define QERR_BUFFER_OVERRUN \
+    ERROR_CLASS_GENERIC_ERROR, "An internal buffer overran"
 
 #define QERR_BUS_NO_HOTPLUG \
-    "{ 'class': 'BusNoHotplug', 'data': { 'bus': %s } }"
+    ERROR_CLASS_GENERIC_ERROR, "Bus '%s' does not support hotplugging"
+
+#define QERR_BUS_NOT_FOUND \
+    ERROR_CLASS_GENERIC_ERROR, "Bus '%s' not found"
+
+#define QERR_COMMAND_DISABLED \
+    ERROR_CLASS_GENERIC_ERROR, "The command %s has been disabled for this instance"
 
 #define QERR_COMMAND_NOT_FOUND \
-    "{ 'class': 'CommandNotFound', 'data': { 'name': %s } }"
+    ERROR_CLASS_COMMAND_NOT_FOUND, "The command %s has not been found"
 
 #define QERR_DEVICE_ENCRYPTED \
-    "{ 'class': 'DeviceEncrypted', 'data': { 'device': %s } }"
+    ERROR_CLASS_DEVICE_ENCRYPTED, "'%s' (%s) is encrypted"
+
+#define QERR_DEVICE_FEATURE_BLOCKS_MIGRATION \
+    ERROR_CLASS_GENERIC_ERROR, "Migration is disabled when using feature '%s' in device '%s'"
+
+#define QERR_DEVICE_HAS_NO_MEDIUM \
+    ERROR_CLASS_GENERIC_ERROR, "Device '%s' has no medium"
 
 #define QERR_DEVICE_INIT_FAILED \
-    "{ 'class': 'DeviceInitFailed', 'data': { 'device': %s } }"
+    ERROR_CLASS_GENERIC_ERROR, "Device '%s' could not be initialized"
 
 #define QERR_DEVICE_IN_USE \
-    "{ 'class': 'DeviceInUse', 'data': { 'device': %s } }"
+    ERROR_CLASS_GENERIC_ERROR, "Device '%s' is in use"
+
+#define QERR_DEVICE_IS_READ_ONLY \
+    ERROR_CLASS_GENERIC_ERROR, "Device '%s' is read only"
 
 #define QERR_DEVICE_LOCKED \
-    "{ 'class': 'DeviceLocked', 'data': { 'device': %s } }"
+    ERROR_CLASS_GENERIC_ERROR, "Device '%s' is locked"
 
 #define QERR_DEVICE_MULTIPLE_BUSSES \
-    "{ 'class': 'DeviceMultipleBusses', 'data': { 'device': %s } }"
-
-#define QERR_DEVICE_NOT_ACTIVE \
-    "{ 'class': 'DeviceNotActive', 'data': { 'device': %s } }"
-
-#define QERR_DEVICE_NOT_ENCRYPTED \
-    "{ 'class': 'DeviceNotEncrypted', 'data': { 'device': %s } }"
-
-#define QERR_DEVICE_NOT_FOUND \
-    "{ 'class': 'DeviceNotFound', 'data': { 'device': %s } }"
-
-#define QERR_DEVICE_NOT_REMOVABLE \
-    "{ 'class': 'DeviceNotRemovable', 'data': { 'device': %s } }"
+    ERROR_CLASS_GENERIC_ERROR, "Device '%s' has multiple child busses"
 
 #define QERR_DEVICE_NO_BUS \
-    "{ 'class': 'DeviceNoBus', 'data': { 'device': %s } }"
+    ERROR_CLASS_GENERIC_ERROR, "Device '%s' has no child bus"
 
 #define QERR_DEVICE_NO_HOTPLUG \
-    "{ 'class': 'DeviceNoHotplug', 'data': { 'device': %s } }"
+    ERROR_CLASS_GENERIC_ERROR, "Device '%s' does not support hotplugging"
+
+#define QERR_DEVICE_NOT_ACTIVE \
+    ERROR_CLASS_DEVICE_NOT_ACTIVE, "Device '%s' has not been activated"
+
+#define QERR_DEVICE_NOT_ENCRYPTED \
+    ERROR_CLASS_GENERIC_ERROR, "Device '%s' is not encrypted"
+
+#define QERR_DEVICE_NOT_FOUND \
+    ERROR_CLASS_DEVICE_NOT_FOUND, "Device '%s' not found"
+
+#define QERR_DEVICE_NOT_REMOVABLE \
+    ERROR_CLASS_GENERIC_ERROR, "Device '%s' is not removable"
 
 #define QERR_DUPLICATE_ID \
-    "{ 'class': 'DuplicateId', 'data': { 'id': %s, 'object': %s } }"
+    ERROR_CLASS_GENERIC_ERROR, "Duplicate ID '%s' for %s"
 
 #define QERR_FD_NOT_FOUND \
-    "{ 'class': 'FdNotFound', 'data': { 'name': %s } }"
+    ERROR_CLASS_GENERIC_ERROR, "File descriptor named '%s' not found"
 
 #define QERR_FD_NOT_SUPPLIED \
-    "{ 'class': 'FdNotSupplied', 'data': {} }"
-
-#define QERR_INVALID_BLOCK_FORMAT \
-    "{ 'class': 'InvalidBlockFormat', 'data': { 'name': %s } }"
-
-#define QERR_INVALID_PARAMETER \
-    "{ 'class': 'InvalidParameter', 'data': { 'name': %s } }"
-
-#define QERR_INVALID_PARAMETER_TYPE \
-    "{ 'class': 'InvalidParameterType', 'data': { 'name': %s,'expected': %s } }"
-
-#define QERR_INVALID_PARAMETER_VALUE \
-    "{ 'class': 'InvalidParameterValue', 'data': { 'name': %s, 'expected': %s } }"
-
-#define QERR_INVALID_PASSWORD \
-    "{ 'class': 'InvalidPassword', 'data': {} }"
-
-#define QERR_JSON_PARSING \
-    "{ 'class': 'JSONParsing', 'data': {} }"
-
-#define QERR_KVM_MISSING_CAP \
-    "{ 'class': 'KVMMissingCap', 'data': { 'capability': %s, 'feature': %s } }"
-
-#define QERR_MIGRATION_EXPECTED \
-    "{ 'class': 'MigrationExpected', 'data': {} }"
-
-#define QERR_MISSING_PARAMETER \
-    "{ 'class': 'MissingParameter', 'data': { 'name': %s } }"
-
-#define QERR_NO_BUS_FOR_DEVICE \
-    "{ 'class': 'NoBusForDevice', 'data': { 'device': %s, 'bus': %s } }"
-
-#define QERR_OPEN_FILE_FAILED \
-    "{ 'class': 'OpenFileFailed', 'data': { 'filename': %s } }"
-
-#define QERR_PROPERTY_NOT_FOUND \
-    "{ 'class': 'PropertyNotFound', 'data': { 'device': %s, 'property': %s } }"
-
-#define QERR_PROPERTY_VALUE_BAD \
-    "{ 'class': 'PropertyValueBad', 'data': { 'device': %s, 'property': %s, 'value': %s } }"
-
-#define QERR_PROPERTY_VALUE_IN_USE \
-    "{ 'class': 'PropertyValueInUse', 'data': { 'device': %s, 'property': %s, 'value': %s } }"
-
-#define QERR_PROPERTY_VALUE_NOT_FOUND \
-    "{ 'class': 'PropertyValueNotFound', 'data': { 'device': %s, 'property': %s, 'value': %s } }"
-
-#define QERR_QMP_BAD_INPUT_OBJECT \
-    "{ 'class': 'QMPBadInputObject', 'data': { 'expected': %s } }"
-
-#define QERR_QMP_BAD_INPUT_OBJECT_MEMBER \
-    "{ 'class': 'QMPBadInputObjectMember', 'data': { 'member': %s, 'expected': %s } }"
-
-#define QERR_QMP_EXTRA_MEMBER \
-    "{ 'class': 'QMPExtraInputObjectMember', 'data': { 'member': %s } }"
-
-#define QERR_SET_PASSWD_FAILED \
-    "{ 'class': 'SetPasswdFailed', 'data': {} }"
-
-#define QERR_TOO_MANY_FILES \
-    "{ 'class': 'TooManyFiles', 'data': {} }"
-
-#define QERR_UNDEFINED_ERROR \
-    "{ 'class': 'UndefinedError', 'data': {} }"
-
-#define QERR_UNKNOWN_BLOCK_FORMAT_FEATURE \
-    "{ 'class': 'UnknownBlockFormatFeature', 'data': { 'device': %s, 'format': %s, 'feature': %s } }"
-
-#define QERR_VNC_SERVER_FAILED \
-    "{ 'class': 'VNCServerFailed', 'data': { 'target': %s } }"
+    ERROR_CLASS_GENERIC_ERROR, "No file descriptor supplied via SCM_RIGHTS"
 
 #define QERR_FEATURE_DISABLED \
-    "{ 'class': 'FeatureDisabled', 'data': { 'name': %s } }"
+    ERROR_CLASS_GENERIC_ERROR, "The feature '%s' is not enabled"
+
+#define QERR_INVALID_BLOCK_FORMAT \
+    ERROR_CLASS_GENERIC_ERROR, "Invalid block format '%s'"
+
+#define QERR_INVALID_OPTION_GROUP \
+    ERROR_CLASS_GENERIC_ERROR, "There is no option group '%s'"
+
+#define QERR_INVALID_PARAMETER \
+    ERROR_CLASS_GENERIC_ERROR, "Invalid parameter '%s'"
+
+#define QERR_INVALID_PARAMETER_COMBINATION \
+    ERROR_CLASS_GENERIC_ERROR, "Invalid parameter combination"
+
+#define QERR_INVALID_PARAMETER_TYPE \
+    ERROR_CLASS_GENERIC_ERROR, "Invalid parameter type for '%s', expected: %s"
+
+#define QERR_INVALID_PARAMETER_VALUE \
+    ERROR_CLASS_GENERIC_ERROR, "Parameter '%s' expects %s"
+
+#define QERR_INVALID_PASSWORD \
+    ERROR_CLASS_GENERIC_ERROR, "Password incorrect"
+
+#define QERR_IO_ERROR \
+    ERROR_CLASS_GENERIC_ERROR, "An IO error has occurred"
+
+#define QERR_JSON_PARSE_ERROR \
+    ERROR_CLASS_GENERIC_ERROR, "JSON parse error, %s"
+
+#define QERR_JSON_PARSING \
+    ERROR_CLASS_GENERIC_ERROR, "Invalid JSON syntax"
+
+#define QERR_KVM_MISSING_CAP \
+    ERROR_CLASS_K_V_M_MISSING_CAP, "Using KVM without %s, %s unavailable"
+
+#define QERR_MIGRATION_ACTIVE \
+    ERROR_CLASS_GENERIC_ERROR, "There's a migration process in progress"
+
+#define QERR_MIGRATION_NOT_SUPPORTED \
+    ERROR_CLASS_GENERIC_ERROR, "State blocked by non-migratable device '%s'"
+
+#define QERR_MISSING_PARAMETER \
+    ERROR_CLASS_GENERIC_ERROR, "Parameter '%s' is missing"
+
+#define QERR_NO_BUS_FOR_DEVICE \
+    ERROR_CLASS_GENERIC_ERROR, "No '%s' bus found for device '%s'"
+
+#define QERR_NOT_SUPPORTED \
+    ERROR_CLASS_GENERIC_ERROR, "Not supported"
+
+#define QERR_PERMISSION_DENIED \
+    ERROR_CLASS_GENERIC_ERROR, "Insufficient permission to perform this operation"
+
+#define QERR_PROPERTY_NOT_FOUND \
+    ERROR_CLASS_GENERIC_ERROR, "Property '%s.%s' not found"
+
+#define QERR_PROPERTY_VALUE_BAD \
+    ERROR_CLASS_GENERIC_ERROR, "Property '%s.%s' doesn't take value '%s'"
+
+#define QERR_PROPERTY_VALUE_IN_USE \
+    ERROR_CLASS_GENERIC_ERROR, "Property '%s.%s' can't take value '%s', it's in use"
+
+#define QERR_PROPERTY_VALUE_NOT_FOUND \
+    ERROR_CLASS_GENERIC_ERROR, "Property '%s.%s' can't find value '%s'"
+
+#define QERR_PROPERTY_VALUE_NOT_POWER_OF_2 \
+    ERROR_CLASS_GENERIC_ERROR, "Property %s.%s doesn't take value '%" PRId64 "', it's not a power of 2"
+
+#define QERR_PROPERTY_VALUE_OUT_OF_RANGE \
+    ERROR_CLASS_GENERIC_ERROR, "Property %s.%s doesn't take value %" PRId64 " (minimum: %" PRId64 ", maximum: %" PRId64 ")"
+
+#define QERR_QGA_COMMAND_FAILED \
+    ERROR_CLASS_GENERIC_ERROR, "Guest agent command failed, error was '%s'"
+
+#define QERR_QGA_LOGGING_FAILED \
+    ERROR_CLASS_GENERIC_ERROR, "Guest agent failed to log non-optional log statement"
+
+#define QERR_QMP_BAD_INPUT_OBJECT \
+    ERROR_CLASS_GENERIC_ERROR, "Expected '%s' in QMP input"
+
+#define QERR_QMP_BAD_INPUT_OBJECT_MEMBER \
+    ERROR_CLASS_GENERIC_ERROR, "QMP input object member '%s' expects '%s'"
+
+#define QERR_QMP_EXTRA_MEMBER \
+    ERROR_CLASS_GENERIC_ERROR, "QMP input object member '%s' is unexpected"
+
+#define QERR_RESET_REQUIRED \
+    ERROR_CLASS_GENERIC_ERROR, "Resetting the Virtual Machine is required"
+
+#define QERR_SET_PASSWD_FAILED \
+    ERROR_CLASS_GENERIC_ERROR, "Could not set password"
+
+#define QERR_TOO_MANY_FILES \
+    ERROR_CLASS_GENERIC_ERROR, "Too many open files"
+
+#define QERR_UNDEFINED_ERROR \
+    ERROR_CLASS_GENERIC_ERROR, "An undefined error has occurred"
+
+#define QERR_UNKNOWN_BLOCK_FORMAT_FEATURE \
+    ERROR_CLASS_GENERIC_ERROR, "'%s' uses a %s feature which is not supported by this qemu version: %s"
+
+#define QERR_UNSUPPORTED \
+    ERROR_CLASS_GENERIC_ERROR, "this feature or command is not currently supported"
+
+#define QERR_VIRTFS_FEATURE_BLOCKS_MIGRATION \
+    ERROR_CLASS_GENERIC_ERROR, "Migration is disabled when VirtFS export path '%s' is mounted in the guest using mount_tag '%s'"
+
+#define QERR_SOCKET_CONNECT_FAILED \
+    ERROR_CLASS_GENERIC_ERROR, "Failed to connect to socket"
+
+#define QERR_SOCKET_LISTEN_FAILED \
+    ERROR_CLASS_GENERIC_ERROR, "Failed to set socket to listening mode"
+
+#define QERR_SOCKET_BIND_FAILED \
+    ERROR_CLASS_GENERIC_ERROR, "Failed to bind socket"
+
+#define QERR_SOCKET_CREATE_FAILED \
+    ERROR_CLASS_GENERIC_ERROR, "Failed to create socket"
 
 #endif /* QERROR_H */
diff --git a/include/qapi/qmp/qjson.h b/include/qapi/qmp/qjson.h
index 0bebab4..73351ed 100644
--- a/include/qapi/qmp/qjson.h
+++ b/include/qapi/qmp/qjson.h
@@ -15,6 +15,7 @@
 #define QJSON_H
 
 #include <stdarg.h>
+#include "qemu/compiler.h"
 #include "qapi/qmp/qobject.h"
 #include "qapi/qmp/qstring.h"
 
diff --git a/include/qapi/qmp/qlist.h b/include/qapi/qmp/qlist.h
index 08eaea1..6cc4831 100644
--- a/include/qapi/qmp/qlist.h
+++ b/include/qapi/qmp/qlist.h
@@ -15,7 +15,6 @@
 
 #include "qapi/qmp/qobject.h"
 #include "qemu/queue.h"
-#include "qemu-common.h"
 
 typedef struct QListEntry {
     QObject *value;
@@ -48,6 +47,17 @@
 QObject *qlist_pop(QList *qlist);
 QObject *qlist_peek(QList *qlist);
 int qlist_empty(const QList *qlist);
+size_t qlist_size(const QList *qlist);
 QList *qobject_to_qlist(const QObject *obj);
 
+static inline const QListEntry *qlist_first(const QList *qlist)
+{
+    return QTAILQ_FIRST(&qlist->head);
+}
+
+static inline const QListEntry *qlist_next(const QListEntry *entry)
+{
+    return QTAILQ_NEXT(entry, next);
+}
+
 #endif /* QLIST_H */
diff --git a/include/qapi/qmp/qobject.h b/include/qapi/qmp/qobject.h
index d42386d..d0bbc7c 100644
--- a/include/qapi/qmp/qobject.h
+++ b/include/qapi/qmp/qobject.h
@@ -44,6 +44,7 @@
     QTYPE_QFLOAT,
     QTYPE_QBOOL,
     QTYPE_QERROR,
+    QTYPE_MAX,
 } qtype_code;
 
 struct QObject;
@@ -71,7 +72,7 @@
 
 /* High-level interface for qobject_decref() */
 #define QDECREF(obj)              \
-    qobject_decref(QOBJECT(obj))
+    qobject_decref(obj ? QOBJECT(obj) : NULL)
 
 /* Initialize an object to default values */
 #define QOBJECT_INIT(obj, qtype_type)   \
diff --git a/include/qapi/qmp/qstring.h b/include/qapi/qmp/qstring.h
index 0e690f4..1bc3666 100644
--- a/include/qapi/qmp/qstring.h
+++ b/include/qapi/qmp/qstring.h
@@ -26,6 +26,7 @@
 QString *qstring_new(void);
 QString *qstring_from_str(const char *str);
 QString *qstring_from_substr(const char *str, int start, int end);
+size_t qstring_get_length(const QString *qstring);
 const char *qstring_get_str(const QString *qstring);
 void qstring_append_int(QString *qstring, int64_t value);
 void qstring_append(QString *qstring, const char *str);
diff --git a/include/qapi/string-input-visitor.h b/include/qapi/string-input-visitor.h
new file mode 100644
index 0000000..089243c
--- /dev/null
+++ b/include/qapi/string-input-visitor.h
@@ -0,0 +1,25 @@
+/*
+ * String parsing Visitor
+ *
+ * Copyright Red Hat, Inc. 2012
+ *
+ * Author: Paolo Bonzini <pbonzini@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#ifndef STRING_INPUT_VISITOR_H
+#define STRING_INPUT_VISITOR_H
+
+#include "qapi/visitor.h"
+
+typedef struct StringInputVisitor StringInputVisitor;
+
+StringInputVisitor *string_input_visitor_new(const char *str);
+void string_input_visitor_cleanup(StringInputVisitor *v);
+
+Visitor *string_input_get_visitor(StringInputVisitor *v);
+
+#endif
diff --git a/include/qapi/string-output-visitor.h b/include/qapi/string-output-visitor.h
new file mode 100644
index 0000000..ec81e42
--- /dev/null
+++ b/include/qapi/string-output-visitor.h
@@ -0,0 +1,26 @@
+/*
+ * String printing Visitor
+ *
+ * Copyright Red Hat, Inc. 2012
+ *
+ * Author: Paolo Bonzini <pbonzini@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#ifndef STRING_OUTPUT_VISITOR_H
+#define STRING_OUTPUT_VISITOR_H
+
+#include "qapi/visitor.h"
+
+typedef struct StringOutputVisitor StringOutputVisitor;
+
+StringOutputVisitor *string_output_visitor_new(void);
+void string_output_visitor_cleanup(StringOutputVisitor *v);
+
+char *string_output_get_string(StringOutputVisitor *v);
+Visitor *string_output_get_visitor(StringOutputVisitor *v);
+
+#endif
diff --git a/include/qapi/visitor-impl.h b/include/qapi/visitor-impl.h
new file mode 100644
index 0000000..f3fa420
--- /dev/null
+++ b/include/qapi/visitor-impl.h
@@ -0,0 +1,69 @@
+/*
+ * Core Definitions for QAPI Visitor implementations
+ *
+ * Copyright (C) 2012 Red Hat, Inc.
+ *
+ * Author: Paolo Bonizni <pbonzini@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+#ifndef QAPI_VISITOR_IMPL_H
+#define QAPI_VISITOR_IMPL_H
+
+#include "qapi/error.h"
+#include "qapi/visitor.h"
+
+struct Visitor
+{
+    /* Must be set */
+    void (*start_struct)(Visitor *v, void **obj, const char *kind,
+                         const char *name, size_t size, Error **errp);
+    void (*end_struct)(Visitor *v, Error **errp);
+
+    void (*start_implicit_struct)(Visitor *v, void **obj, size_t size,
+                                  Error **errp);
+    void (*end_implicit_struct)(Visitor *v, Error **errp);
+
+    void (*start_list)(Visitor *v, const char *name, Error **errp);
+    GenericList *(*next_list)(Visitor *v, GenericList **list, Error **errp);
+    void (*end_list)(Visitor *v, Error **errp);
+
+    void (*type_enum)(Visitor *v, int *obj, const char *strings[],
+                      const char *kind, const char *name, Error **errp);
+    void (*get_next_type)(Visitor *v, int *kind, const int *qobjects,
+                          const char *name, Error **errp);
+
+    void (*type_int)(Visitor *v, int64_t *obj, const char *name, Error **errp);
+    void (*type_bool)(Visitor *v, bool *obj, const char *name, Error **errp);
+    void (*type_str)(Visitor *v, char **obj, const char *name, Error **errp);
+    void (*type_number)(Visitor *v, double *obj, const char *name,
+                        Error **errp);
+
+    /* May be NULL */
+    void (*start_optional)(Visitor *v, bool *present, const char *name,
+                           Error **errp);
+    void (*end_optional)(Visitor *v, Error **errp);
+
+    void (*start_handle)(Visitor *v, void **obj, const char *kind,
+                         const char *name, Error **errp);
+    void (*end_handle)(Visitor *v, Error **errp);
+    void (*type_uint8)(Visitor *v, uint8_t *obj, const char *name, Error **errp);
+    void (*type_uint16)(Visitor *v, uint16_t *obj, const char *name, Error **errp);
+    void (*type_uint32)(Visitor *v, uint32_t *obj, const char *name, Error **errp);
+    void (*type_uint64)(Visitor *v, uint64_t *obj, const char *name, Error **errp);
+    void (*type_int8)(Visitor *v, int8_t *obj, const char *name, Error **errp);
+    void (*type_int16)(Visitor *v, int16_t *obj, const char *name, Error **errp);
+    void (*type_int32)(Visitor *v, int32_t *obj, const char *name, Error **errp);
+    void (*type_int64)(Visitor *v, int64_t *obj, const char *name, Error **errp);
+    /* visit_type_size() falls back to (*type_uint64)() if type_size is unset */
+    void (*type_size)(Visitor *v, uint64_t *obj, const char *name, Error **errp);
+};
+
+void input_type_enum(Visitor *v, int *obj, const char *strings[],
+                     const char *kind, const char *name, Error **errp);
+void output_type_enum(Visitor *v, int *obj, const char *strings[],
+                      const char *kind, const char *name, Error **errp);
+
+#endif
diff --git a/include/qapi/visitor.h b/include/qapi/visitor.h
new file mode 100644
index 0000000..48a2a2e
--- /dev/null
+++ b/include/qapi/visitor.h
@@ -0,0 +1,64 @@
+/*
+ * Core Definitions for QAPI Visitor Classes
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ *  Anthony Liguori   <aliguori@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+#ifndef QAPI_VISITOR_CORE_H
+#define QAPI_VISITOR_CORE_H
+
+#include "qapi/qmp/qobject.h"
+#include "qapi/error.h"
+#include <stdlib.h>
+
+typedef struct GenericList
+{
+    union {
+        void *value;
+        uint64_t padding;
+    };
+    struct GenericList *next;
+} GenericList;
+
+typedef struct Visitor Visitor;
+
+void visit_start_handle(Visitor *v, void **obj, const char *kind,
+                        const char *name, Error **errp);
+void visit_end_handle(Visitor *v, Error **errp);
+void visit_start_struct(Visitor *v, void **obj, const char *kind,
+                        const char *name, size_t size, Error **errp);
+void visit_end_struct(Visitor *v, Error **errp);
+void visit_start_implicit_struct(Visitor *v, void **obj, size_t size,
+                                 Error **errp);
+void visit_end_implicit_struct(Visitor *v, Error **errp);
+void visit_start_list(Visitor *v, const char *name, Error **errp);
+GenericList *visit_next_list(Visitor *v, GenericList **list, Error **errp);
+void visit_end_list(Visitor *v, Error **errp);
+void visit_start_optional(Visitor *v, bool *present, const char *name,
+                          Error **errp);
+void visit_end_optional(Visitor *v, Error **errp);
+void visit_get_next_type(Visitor *v, int *obj, const int *qtypes,
+                         const char *name, Error **errp);
+void visit_type_enum(Visitor *v, int *obj, const char *strings[],
+                     const char *kind, const char *name, Error **errp);
+void visit_type_int(Visitor *v, int64_t *obj, const char *name, Error **errp);
+void visit_type_uint8(Visitor *v, uint8_t *obj, const char *name, Error **errp);
+void visit_type_uint16(Visitor *v, uint16_t *obj, const char *name, Error **errp);
+void visit_type_uint32(Visitor *v, uint32_t *obj, const char *name, Error **errp);
+void visit_type_uint64(Visitor *v, uint64_t *obj, const char *name, Error **errp);
+void visit_type_int8(Visitor *v, int8_t *obj, const char *name, Error **errp);
+void visit_type_int16(Visitor *v, int16_t *obj, const char *name, Error **errp);
+void visit_type_int32(Visitor *v, int32_t *obj, const char *name, Error **errp);
+void visit_type_int64(Visitor *v, int64_t *obj, const char *name, Error **errp);
+void visit_type_size(Visitor *v, uint64_t *obj, const char *name, Error **errp);
+void visit_type_bool(Visitor *v, bool *obj, const char *name, Error **errp);
+void visit_type_str(Visitor *v, char **obj, const char *name, Error **errp);
+void visit_type_number(Visitor *v, double *obj, const char *name, Error **errp);
+
+#endif