mirror of https://github.com/xemu-project/xemu.git
QAPI patches for 2016-10-07
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJX9+GcAAoJEDhwtADrkYZTJ3oP/3IL9jj1aa3ypLpFEurBVAJb H2Izm64xbfqpAoXcq5TSec2yuo2KMAsGKZpbBdDzlN8z8eh7e8QU4J83VaZvYGo3 0oLSZPTJ3r8Hpeb7MzJ4O7UiwiTj+6BEYSzwXLaoknBJeI/5gQmk1RUXZg1mx9k/ BB1ADgzH/EVW9tzXva2Kd93vK1cTRU9jVADEh2AxPGsMKGA06R7TP2BV1emHso6l 5wuwR8GLNmqbpR3xVtvycv9WlMLumhZlFdnCgjCvizhI9mNSsVMJozNaMs47lZP5 nq7MUsOVJzOhncMmeLA/OliFQJqQG+iECpTAMqt078wbzwprG31Lu7GELXuIP11g MEOoT9KtKAZJRxfYKPfkRmi1rkvD5jlMuMaIlxm1n4EfZ9jk+9IiZ1QEnTWHjf6W x0DP7Dwio9kQDMkmGJ6O3ZdgEo3Y/Ghc2AmG3oIilU3E53R8mBifu3Fttik+M4kd vqNm0WC6S9v/748iTNfbuF97OBcQDrALvvMu12MZnYAcLZ3aXR/xYg5gX8WRhtyP Afy2qrfeZN810WIW9z7KUb0VesMi6g6OHivbaUfZ1XBJt8Omtl08f7bEfhzCBl7X sA3gruSEX8+Ra9F3QxTJO3Br+6V4Qx+AjxeQwxSJGNn58qqQhjJ4y4UTyBiDZwK2 St07IDD15pAXGMqqRCXQ =qmII -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/armbru/tags/pull-qapi-2016-10-07' into staging QAPI patches for 2016-10-07 # gpg: Signature made Fri 07 Oct 2016 18:55:40 BST # gpg: using RSA key 0x3870B400EB918653 # gpg: Good signature from "Markus Armbruster <armbru@redhat.com>" # gpg: aka "Markus Armbruster <armbru@pond.sub.org>" # Primary key fingerprint: 354B C8B3 D7EB 2A6B 6867 4E5F 3870 B400 EB91 8653 * remotes/armbru/tags/pull-qapi-2016-10-07: docs: Belatedly update for move of QMP/* to docs/ docs: Belatedly update for move of qmp-commands.txt qmp: Disable query-cpu-* commands when they're unavailable MAINTAINERS: Pass the QObject staff from Luiz to Markus MAINTAINERS: Pass the HMP staff from Luiz to David qapi: return a 'missing parameter' error qapi: assert list entry has a value qapi: add assert about root value tests/test-qmp-input-strict: Cover missing struct members qapi: Fix crash when 'any' or 'null' parameter is missing qmp: fix object-add assert() without props Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
0cb0155711
|
@ -1178,12 +1178,11 @@ F: qemu-timer.c
|
|||
F: vl.c
|
||||
|
||||
Human Monitor (HMP)
|
||||
M: Luiz Capitulino <lcapitulino@redhat.com>
|
||||
M: Dr. David Alan Gilbert <dgilbert@redhat.com>
|
||||
S: Maintained
|
||||
F: monitor.c
|
||||
F: hmp.c
|
||||
F: hmp-commands.hx
|
||||
T: git git://repo.or.cz/qemu/qmp-unstable.git queue/qmp
|
||||
|
||||
Network device backends
|
||||
M: Jason Wang <jasowang@redhat.com>
|
||||
|
@ -1248,8 +1247,8 @@ F: qapi/*.json
|
|||
T: git git://repo.or.cz/qemu/armbru.git qapi-next
|
||||
|
||||
QObject
|
||||
M: Luiz Capitulino <lcapitulino@redhat.com>
|
||||
S: Maintained
|
||||
M: Markus Armbruster <armbru@redhat.com>
|
||||
S: Supported
|
||||
F: qobject/
|
||||
F: include/qapi/qmp/
|
||||
X: include/qapi/qmp/dispatch.h
|
||||
|
@ -1259,7 +1258,7 @@ F: tests/check-qint.c
|
|||
F: tests/check-qjson.c
|
||||
F: tests/check-qlist.c
|
||||
F: tests/check-qstring.c
|
||||
T: git git://repo.or.cz/qemu/qmp-unstable.git queue/qmp
|
||||
T: git git://repo.or.cz/qemu/armbru.git qapi-next
|
||||
|
||||
QEMU Guest Agent
|
||||
M: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
|
|
|
@ -20,7 +20,7 @@ Also, the following notation is used to denote data flow:
|
|||
-> data issued by the Client
|
||||
<- Server data response
|
||||
|
||||
Please, refer to the QMP specification (QMP/qmp-spec.txt) for detailed
|
||||
Please, refer to the QMP specification (docs/qmp-spec.txt) for detailed
|
||||
information on the Server command and response formats.
|
||||
|
||||
NOTE: This document is temporary and will be replaced soon.
|
||||
|
|
|
@ -7,8 +7,8 @@ This document doesn't discuss QMP protocol level details, nor does it dive
|
|||
into the QAPI framework implementation.
|
||||
|
||||
For an in-depth introduction to the QAPI framework, please refer to
|
||||
docs/qapi-code-gen.txt. For documentation about the QMP protocol, please
|
||||
check the files in QMP/.
|
||||
docs/qapi-code-gen.txt. For documentation about the QMP protocol,
|
||||
start with docs/qmp-intro.txt.
|
||||
|
||||
== Overview ==
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ however it is also possible to save the state of all devices to file,
|
|||
without saving the RAM or the block devices of the VM.
|
||||
|
||||
This operation is called "xen-save-devices-state" (see
|
||||
QMP/qmp-commands.txt)
|
||||
qmp-commands.txt)
|
||||
|
||||
|
||||
The binary format used in the file is the following:
|
||||
|
|
|
@ -986,6 +986,15 @@ static void qmp_unregister_commands_hack(void)
|
|||
#ifndef TARGET_ARM
|
||||
qmp_unregister_command("query-gic-capabilities");
|
||||
#endif
|
||||
#if !defined(TARGET_S390X)
|
||||
qmp_unregister_command("query-cpu-model-expansion");
|
||||
qmp_unregister_command("query-cpu-model-baseline");
|
||||
qmp_unregister_command("query-cpu-model-comparison");
|
||||
#endif
|
||||
#if !defined(TARGET_PPC) && !defined(TARGET_ARM) && !defined(TARGET_I386) \
|
||||
&& !defined(TARGET_S390X)
|
||||
qmp_unregister_command("query-cpu-definitions");
|
||||
#endif
|
||||
}
|
||||
|
||||
static void qmp_init_marshal(void)
|
||||
|
|
|
@ -56,7 +56,7 @@ static QmpInputVisitor *to_qiv(Visitor *v)
|
|||
|
||||
static QObject *qmp_input_get_object(QmpInputVisitor *qiv,
|
||||
const char *name,
|
||||
bool consume)
|
||||
bool consume, Error **errp)
|
||||
{
|
||||
StackObject *tos;
|
||||
QObject *qobj;
|
||||
|
@ -64,6 +64,7 @@ static QObject *qmp_input_get_object(QmpInputVisitor *qiv,
|
|||
|
||||
if (QSLIST_EMPTY(&qiv->stack)) {
|
||||
/* Starting at root, name is ignored. */
|
||||
assert(qiv->root);
|
||||
return qiv->root;
|
||||
}
|
||||
|
||||
|
@ -79,10 +80,14 @@ static QObject *qmp_input_get_object(QmpInputVisitor *qiv,
|
|||
bool removed = g_hash_table_remove(tos->h, name);
|
||||
assert(removed);
|
||||
}
|
||||
if (!ret) {
|
||||
error_setg(errp, QERR_MISSING_PARAMETER, name);
|
||||
}
|
||||
} else {
|
||||
assert(qobject_type(qobj) == QTYPE_QLIST);
|
||||
assert(!name);
|
||||
ret = qlist_entry_obj(tos->entry);
|
||||
assert(ret);
|
||||
if (consume) {
|
||||
tos->entry = qlist_next(tos->entry);
|
||||
}
|
||||
|
@ -163,13 +168,16 @@ static void qmp_input_start_struct(Visitor *v, const char *name, void **obj,
|
|||
size_t size, Error **errp)
|
||||
{
|
||||
QmpInputVisitor *qiv = to_qiv(v);
|
||||
QObject *qobj = qmp_input_get_object(qiv, name, true);
|
||||
QObject *qobj = qmp_input_get_object(qiv, name, true, errp);
|
||||
Error *err = NULL;
|
||||
|
||||
if (obj) {
|
||||
*obj = NULL;
|
||||
}
|
||||
if (!qobj || qobject_type(qobj) != QTYPE_QDICT) {
|
||||
if (!qobj) {
|
||||
return;
|
||||
}
|
||||
if (qobject_type(qobj) != QTYPE_QDICT) {
|
||||
error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
|
||||
"QDict");
|
||||
return;
|
||||
|
@ -191,10 +199,13 @@ static void qmp_input_start_list(Visitor *v, const char *name,
|
|||
GenericList **list, size_t size, Error **errp)
|
||||
{
|
||||
QmpInputVisitor *qiv = to_qiv(v);
|
||||
QObject *qobj = qmp_input_get_object(qiv, name, true);
|
||||
QObject *qobj = qmp_input_get_object(qiv, name, true, errp);
|
||||
const QListEntry *entry;
|
||||
|
||||
if (!qobj || qobject_type(qobj) != QTYPE_QLIST) {
|
||||
if (!qobj) {
|
||||
return;
|
||||
}
|
||||
if (qobject_type(qobj) != QTYPE_QLIST) {
|
||||
if (list) {
|
||||
*list = NULL;
|
||||
}
|
||||
|
@ -232,11 +243,10 @@ static void qmp_input_start_alternate(Visitor *v, const char *name,
|
|||
bool promote_int, Error **errp)
|
||||
{
|
||||
QmpInputVisitor *qiv = to_qiv(v);
|
||||
QObject *qobj = qmp_input_get_object(qiv, name, false);
|
||||
QObject *qobj = qmp_input_get_object(qiv, name, false, errp);
|
||||
|
||||
if (!qobj) {
|
||||
*obj = NULL;
|
||||
error_setg(errp, QERR_MISSING_PARAMETER, name ? name : "null");
|
||||
return;
|
||||
}
|
||||
*obj = g_malloc0(size);
|
||||
|
@ -250,8 +260,13 @@ static void qmp_input_type_int64(Visitor *v, const char *name, int64_t *obj,
|
|||
Error **errp)
|
||||
{
|
||||
QmpInputVisitor *qiv = to_qiv(v);
|
||||
QInt *qint = qobject_to_qint(qmp_input_get_object(qiv, name, true));
|
||||
QObject *qobj = qmp_input_get_object(qiv, name, true, errp);
|
||||
QInt *qint;
|
||||
|
||||
if (!qobj) {
|
||||
return;
|
||||
}
|
||||
qint = qobject_to_qint(qobj);
|
||||
if (!qint) {
|
||||
error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
|
||||
"integer");
|
||||
|
@ -266,8 +281,13 @@ static void qmp_input_type_uint64(Visitor *v, const char *name, uint64_t *obj,
|
|||
{
|
||||
/* FIXME: qobject_to_qint mishandles values over INT64_MAX */
|
||||
QmpInputVisitor *qiv = to_qiv(v);
|
||||
QInt *qint = qobject_to_qint(qmp_input_get_object(qiv, name, true));
|
||||
QObject *qobj = qmp_input_get_object(qiv, name, true, errp);
|
||||
QInt *qint;
|
||||
|
||||
if (!qobj) {
|
||||
return;
|
||||
}
|
||||
qint = qobject_to_qint(qobj);
|
||||
if (!qint) {
|
||||
error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
|
||||
"integer");
|
||||
|
@ -281,8 +301,13 @@ static void qmp_input_type_bool(Visitor *v, const char *name, bool *obj,
|
|||
Error **errp)
|
||||
{
|
||||
QmpInputVisitor *qiv = to_qiv(v);
|
||||
QBool *qbool = qobject_to_qbool(qmp_input_get_object(qiv, name, true));
|
||||
QObject *qobj = qmp_input_get_object(qiv, name, true, errp);
|
||||
QBool *qbool;
|
||||
|
||||
if (!qobj) {
|
||||
return;
|
||||
}
|
||||
qbool = qobject_to_qbool(qobj);
|
||||
if (!qbool) {
|
||||
error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
|
||||
"boolean");
|
||||
|
@ -296,10 +321,15 @@ static void qmp_input_type_str(Visitor *v, const char *name, char **obj,
|
|||
Error **errp)
|
||||
{
|
||||
QmpInputVisitor *qiv = to_qiv(v);
|
||||
QString *qstr = qobject_to_qstring(qmp_input_get_object(qiv, name, true));
|
||||
QObject *qobj = qmp_input_get_object(qiv, name, true, errp);
|
||||
QString *qstr;
|
||||
|
||||
if (!qstr) {
|
||||
*obj = NULL;
|
||||
if (!qobj) {
|
||||
return;
|
||||
}
|
||||
qstr = qobject_to_qstring(qobj);
|
||||
if (!qstr) {
|
||||
error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
|
||||
"string");
|
||||
return;
|
||||
|
@ -312,10 +342,13 @@ static void qmp_input_type_number(Visitor *v, const char *name, double *obj,
|
|||
Error **errp)
|
||||
{
|
||||
QmpInputVisitor *qiv = to_qiv(v);
|
||||
QObject *qobj = qmp_input_get_object(qiv, name, true);
|
||||
QObject *qobj = qmp_input_get_object(qiv, name, true, errp);
|
||||
QInt *qint;
|
||||
QFloat *qfloat;
|
||||
|
||||
if (!qobj) {
|
||||
return;
|
||||
}
|
||||
qint = qobject_to_qint(qobj);
|
||||
if (qint) {
|
||||
*obj = qint_get_int(qobject_to_qint(qobj));
|
||||
|
@ -336,7 +369,12 @@ static void qmp_input_type_any(Visitor *v, const char *name, QObject **obj,
|
|||
Error **errp)
|
||||
{
|
||||
QmpInputVisitor *qiv = to_qiv(v);
|
||||
QObject *qobj = qmp_input_get_object(qiv, name, true);
|
||||
QObject *qobj = qmp_input_get_object(qiv, name, true, errp);
|
||||
|
||||
*obj = NULL;
|
||||
if (!qobj) {
|
||||
return;
|
||||
}
|
||||
|
||||
qobject_incref(qobj);
|
||||
*obj = qobj;
|
||||
|
@ -345,7 +383,11 @@ static void qmp_input_type_any(Visitor *v, const char *name, QObject **obj,
|
|||
static void qmp_input_type_null(Visitor *v, const char *name, Error **errp)
|
||||
{
|
||||
QmpInputVisitor *qiv = to_qiv(v);
|
||||
QObject *qobj = qmp_input_get_object(qiv, name, true);
|
||||
QObject *qobj = qmp_input_get_object(qiv, name, true, errp);
|
||||
|
||||
if (!qobj) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (qobject_type(qobj) != QTYPE_QNULL) {
|
||||
error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
|
||||
|
@ -356,7 +398,7 @@ static void qmp_input_type_null(Visitor *v, const char *name, Error **errp)
|
|||
static void qmp_input_optional(Visitor *v, const char *name, bool *present)
|
||||
{
|
||||
QmpInputVisitor *qiv = to_qiv(v);
|
||||
QObject *qobj = qmp_input_get_object(qiv, name, false);
|
||||
QObject *qobj = qmp_input_get_object(qiv, name, false, NULL);
|
||||
|
||||
if (!qobj) {
|
||||
*present = false;
|
||||
|
@ -384,6 +426,7 @@ Visitor *qmp_input_visitor_new(QObject *obj, bool strict)
|
|||
{
|
||||
QmpInputVisitor *v;
|
||||
|
||||
assert(obj);
|
||||
v = g_malloc0(sizeof(*v));
|
||||
|
||||
v->visitor.type = VISITOR_INPUT;
|
||||
|
|
8
qmp.c
8
qmp.c
|
@ -660,7 +660,7 @@ void qmp_add_client(const char *protocol, const char *fdname,
|
|||
void qmp_object_add(const char *type, const char *id,
|
||||
bool has_props, QObject *props, Error **errp)
|
||||
{
|
||||
const QDict *pdict = NULL;
|
||||
QDict *pdict;
|
||||
Visitor *v;
|
||||
Object *obj;
|
||||
|
||||
|
@ -670,14 +670,18 @@ void qmp_object_add(const char *type, const char *id,
|
|||
error_setg(errp, QERR_INVALID_PARAMETER_TYPE, "props", "dict");
|
||||
return;
|
||||
}
|
||||
QINCREF(pdict);
|
||||
} else {
|
||||
pdict = qdict_new();
|
||||
}
|
||||
|
||||
v = qmp_input_visitor_new(props, true);
|
||||
v = qmp_input_visitor_new(QOBJECT(pdict), true);
|
||||
obj = user_creatable_add_type(type, id, pdict, v, errp);
|
||||
visit_free(v);
|
||||
if (obj) {
|
||||
object_unref(obj);
|
||||
}
|
||||
QDECREF(pdict);
|
||||
}
|
||||
|
||||
void qmp_object_del(const char *id, Error **errp)
|
||||
|
|
|
@ -56,7 +56,7 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 encryption=on
|
|||
Testing: -S
|
||||
QMP_VERSION
|
||||
{"return": {}}
|
||||
{"error": {"class": "GenericError", "desc": "Invalid parameter type for 'driver', expected: string"}}
|
||||
{"error": {"class": "GenericError", "desc": "Parameter 'driver' is missing"}}
|
||||
{"return": {}}
|
||||
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN"}
|
||||
|
||||
|
|
|
@ -193,6 +193,50 @@ static void test_validate_fail_struct_nested(TestInputVisitorData *data,
|
|||
g_assert(!udp);
|
||||
}
|
||||
|
||||
static void test_validate_fail_struct_missing(TestInputVisitorData *data,
|
||||
const void *unused)
|
||||
{
|
||||
Error *err = NULL;
|
||||
Visitor *v;
|
||||
QObject *any;
|
||||
GenericAlternate *alt;
|
||||
bool present;
|
||||
int en;
|
||||
int64_t i64;
|
||||
uint32_t u32;
|
||||
int8_t i8;
|
||||
char *str;
|
||||
double dbl;
|
||||
|
||||
v = validate_test_init(data, "{}");
|
||||
visit_start_struct(v, NULL, NULL, 0, &error_abort);
|
||||
visit_start_struct(v, "struct", NULL, 0, &err);
|
||||
error_free_or_abort(&err);
|
||||
visit_start_list(v, "list", NULL, 0, &err);
|
||||
error_free_or_abort(&err);
|
||||
visit_start_alternate(v, "alternate", &alt, sizeof(*alt), false, &err);
|
||||
error_free_or_abort(&err);
|
||||
visit_optional(v, "optional", &present);
|
||||
g_assert(!present);
|
||||
visit_type_enum(v, "enum", &en, EnumOne_lookup, &err);
|
||||
error_free_or_abort(&err);
|
||||
visit_type_int(v, "i64", &i64, &err);
|
||||
error_free_or_abort(&err);
|
||||
visit_type_uint32(v, "u32", &u32, &err);
|
||||
error_free_or_abort(&err);
|
||||
visit_type_int8(v, "i8", &i8, &err);
|
||||
error_free_or_abort(&err);
|
||||
visit_type_str(v, "i8", &str, &err);
|
||||
error_free_or_abort(&err);
|
||||
visit_type_number(v, "dbl", &dbl, &err);
|
||||
error_free_or_abort(&err);
|
||||
visit_type_any(v, "any", &any, &err);
|
||||
error_free_or_abort(&err);
|
||||
visit_type_null(v, "null", &err);
|
||||
error_free_or_abort(&err);
|
||||
visit_end_struct(v, NULL);
|
||||
}
|
||||
|
||||
static void test_validate_fail_list(TestInputVisitorData *data,
|
||||
const void *unused)
|
||||
{
|
||||
|
@ -316,6 +360,8 @@ int main(int argc, char **argv)
|
|||
&testdata, test_validate_fail_struct);
|
||||
validate_test_add("/visitor/input-strict/fail/struct-nested",
|
||||
&testdata, test_validate_fail_struct_nested);
|
||||
validate_test_add("/visitor/input-strict/fail/struct-missing",
|
||||
&testdata, test_validate_fail_struct_missing);
|
||||
validate_test_add("/visitor/input-strict/fail/list",
|
||||
&testdata, test_validate_fail_list);
|
||||
validate_test_add("/visitor/input-strict/fail/union-flat",
|
||||
|
|
Loading…
Reference in New Issue