* [Qemu-devel] [PULL 1/9] monitor: Reset HMP mon->rs in CHR_EVENT_OPEN
2014-09-26 19:03 [Qemu-devel] [PULL 0/9] QMP queue Luiz Capitulino
@ 2014-09-26 19:03 ` Luiz Capitulino
2014-09-26 19:04 ` [Qemu-devel] [PULL 2/9] virtio-balloon: fix integer overflow in memory stats feature Luiz Capitulino
` (8 subsequent siblings)
9 siblings, 0 replies; 16+ messages in thread
From: Luiz Capitulino @ 2014-09-26 19:03 UTC (permalink / raw)
To: peter.maydell; +Cc: qemu-devel, anthony
From: Stratos Psomadakis <psomas@grnet.gr>
Commit cdaa86a54 ("Add G_IO_HUP handler for socket chardev") exposed a bug in
the way the HMP monitor handles its command buffer. When a client closes the
connection to the monitor, tcp_chr_read() will detect the G_IO_HUP condition
and call tcp_chr_disconnect() to close the server-side connection too. Due to
the fact that monitor reads 1 byte at a time (for each tcp_chr_read()), the
monitor readline state / buffers might contain junk (i.e. a half-finished
command). Thus, without calling readline_restart() on mon->rs in
CHR_EVENT_OPEN, future HMP commands will fail.
Signed-off-by: Stratos Psomadakis <psomas@grnet.gr>
Signed-off-by: Dimitris Aragiorgis <dimara@grnet.gr>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
monitor.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/monitor.c b/monitor.c
index b96710e..48850af 100644
--- a/monitor.c
+++ b/monitor.c
@@ -5249,6 +5249,7 @@ static void monitor_event(void *opaque, int event)
monitor_printf(mon, "QEMU %s monitor - type 'help' for more "
"information\n", QEMU_VERSION);
if (!mon->mux_out) {
+ readline_restart(mon->rs);
readline_show_prompt(mon->rs);
}
mon->reset_seen = 1;
--
1.9.3
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [Qemu-devel] [PULL 2/9] virtio-balloon: fix integer overflow in memory stats feature
2014-09-26 19:03 [Qemu-devel] [PULL 0/9] QMP queue Luiz Capitulino
2014-09-26 19:03 ` [Qemu-devel] [PULL 1/9] monitor: Reset HMP mon->rs in CHR_EVENT_OPEN Luiz Capitulino
@ 2014-09-26 19:04 ` Luiz Capitulino
2014-09-26 19:04 ` [Qemu-devel] [PULL 3/9] qapi: add visit_start_union and visit_end_union Luiz Capitulino
` (7 subsequent siblings)
9 siblings, 0 replies; 16+ messages in thread
From: Luiz Capitulino @ 2014-09-26 19:04 UTC (permalink / raw)
To: peter.maydell; +Cc: qemu-devel, anthony
When a QMP client changes the polling interval time by setting
the guest-stats-polling-interval property, the interval value
is stored and manipulated as an int64_t variable.
However, the balloon_stats_change_timer() function, which is
used to set the actual timer with the interval value, takes
an int instead, causing an overflow for big interval values.
This commit fix this bug by changing balloon_stats_change_timer()
to take an int64_t and also it limits the polling interval value
to UINT_MAX to avoid other kinds of overflow.
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
---
hw/virtio/virtio-balloon.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c
index 2c30b3d..b5cf7ca 100644
--- a/hw/virtio/virtio-balloon.c
+++ b/hw/virtio/virtio-balloon.c
@@ -87,7 +87,7 @@ static void balloon_stats_destroy_timer(VirtIOBalloon *s)
}
}
-static void balloon_stats_change_timer(VirtIOBalloon *s, int secs)
+static void balloon_stats_change_timer(VirtIOBalloon *s, int64_t secs)
{
timer_mod(s->stats_timer, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + secs * 1000);
}
@@ -170,6 +170,11 @@ static void balloon_stats_set_poll_interval(Object *obj, struct Visitor *v,
return;
}
+ if (value > UINT_MAX) {
+ error_setg(errp, "timer value is too big");
+ return;
+ }
+
if (value == s->stats_poll_interval) {
return;
}
--
1.9.3
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [Qemu-devel] [PULL 3/9] qapi: add visit_start_union and visit_end_union
2014-09-26 19:03 [Qemu-devel] [PULL 0/9] QMP queue Luiz Capitulino
2014-09-26 19:03 ` [Qemu-devel] [PULL 1/9] monitor: Reset HMP mon->rs in CHR_EVENT_OPEN Luiz Capitulino
2014-09-26 19:04 ` [Qemu-devel] [PULL 2/9] virtio-balloon: fix integer overflow in memory stats feature Luiz Capitulino
@ 2014-09-26 19:04 ` Luiz Capitulino
2014-09-26 19:04 ` [Qemu-devel] [PULL 4/9] qapi: dealloc visitor, implement visit_start_union Luiz Capitulino
` (6 subsequent siblings)
9 siblings, 0 replies; 16+ messages in thread
From: Luiz Capitulino @ 2014-09-26 19:04 UTC (permalink / raw)
To: peter.maydell; +Cc: qemu-devel, anthony
From: Michael Roth <mdroth@linux.vnet.ibm.com>
In some cases an input visitor might bail out on filling out a
struct for various reasons, such as missing fields when running
in strict mode. In the case of a QAPI Union type, this may lead
to cases where the .kind field which encodes the union type
is uninitialized. Subsequently, other visitors, such as the
dealloc visitor, may use this .kind value as if it were
initialized, leading to assumptions about the union type which
in this case may lead to segfaults. For example, freeing an
integer value.
However, we can generally rely on the fact that the always-present
.data void * field that we generate for these union types will
always be NULL in cases where .kind is uninitialized (at least,
there shouldn't be a reason where we'd do this purposefully).
So pass this information on to Visitor implementation via these
optional start_union/end_union interfaces so this information
can be used to guard against the situation above. We will make
use of this information in a subsequent patch for the dealloc
visitor.
Cc: qemu-stable@nongnu.org
Reported-by: Fam Zheng <famz@redhat.com>
Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
include/qapi/visitor-impl.h | 2 ++
include/qapi/visitor.h | 2 ++
qapi/qapi-visit-core.c | 15 +++++++++++++++
scripts/qapi-visit.py | 6 ++++++
4 files changed, 25 insertions(+)
diff --git a/include/qapi/visitor-impl.h b/include/qapi/visitor-impl.h
index ecc0183..09bb0fd 100644
--- a/include/qapi/visitor-impl.h
+++ b/include/qapi/visitor-impl.h
@@ -55,6 +55,8 @@ struct Visitor
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);
+ bool (*start_union)(Visitor *v, bool data_present, Error **errp);
+ void (*end_union)(Visitor *v, bool data_present, Error **errp);
};
void input_type_enum(Visitor *v, int *obj, const char *strings[],
diff --git a/include/qapi/visitor.h b/include/qapi/visitor.h
index 4a0178f..5934f59 100644
--- a/include/qapi/visitor.h
+++ b/include/qapi/visitor.h
@@ -58,5 +58,7 @@ 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);
+bool visit_start_union(Visitor *v, bool data_present, Error **errp);
+void visit_end_union(Visitor *v, bool data_present, Error **errp);
#endif
diff --git a/qapi/qapi-visit-core.c b/qapi/qapi-visit-core.c
index 55f8d40..b66b93a 100644
--- a/qapi/qapi-visit-core.c
+++ b/qapi/qapi-visit-core.c
@@ -58,6 +58,21 @@ void visit_end_list(Visitor *v, Error **errp)
v->end_list(v, errp);
}
+bool visit_start_union(Visitor *v, bool data_present, Error **errp)
+{
+ if (v->start_union) {
+ return v->start_union(v, data_present, errp);
+ }
+ return true;
+}
+
+void visit_end_union(Visitor *v, bool data_present, Error **errp)
+{
+ if (v->end_union) {
+ v->end_union(v, data_present, errp);
+ }
+}
+
void visit_optional(Visitor *v, bool *present, const char *name,
Error **errp)
{
diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index df9f7fb..8f845a2 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -358,6 +358,9 @@ void visit_type_%(name)s(Visitor *m, %(name)s **obj, const char *name, Error **e
if (err) {
goto out_obj;
}
+ if (!visit_start_union(m, !!(*obj)->data, &err) || err) {
+ goto out_obj;
+ }
switch ((*obj)->kind) {
''',
disc_type = disc_type,
@@ -386,6 +389,9 @@ void visit_type_%(name)s(Visitor *m, %(name)s **obj, const char *name, Error **e
out_obj:
error_propagate(errp, err);
err = NULL;
+ visit_end_union(m, !!(*obj)->data, &err);
+ error_propagate(errp, err);
+ err = NULL;
}
visit_end_struct(m, &err);
out:
--
1.9.3
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [Qemu-devel] [PULL 4/9] qapi: dealloc visitor, implement visit_start_union
2014-09-26 19:03 [Qemu-devel] [PULL 0/9] QMP queue Luiz Capitulino
` (2 preceding siblings ...)
2014-09-26 19:04 ` [Qemu-devel] [PULL 3/9] qapi: add visit_start_union and visit_end_union Luiz Capitulino
@ 2014-09-26 19:04 ` Luiz Capitulino
2014-09-26 19:04 ` [Qemu-devel] [PULL 5/9] tests: add QMP input visitor test for unions with no discriminator Luiz Capitulino
` (5 subsequent siblings)
9 siblings, 0 replies; 16+ messages in thread
From: Luiz Capitulino @ 2014-09-26 19:04 UTC (permalink / raw)
To: peter.maydell; +Cc: qemu-devel, anthony
From: Michael Roth <mdroth@linux.vnet.ibm.com>
If the .data field of a QAPI Union is NULL, we don't need to free
any of the union fields.
Make use of the new visit_start_union interface to access this
information and instruct the generated code to not visit these
fields when this occurs.
Cc: qemu-stable@nongnu.org
Reported-by: Fam Zheng <famz@redhat.com>
Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
qapi/qapi-dealloc-visitor.c | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/qapi/qapi-dealloc-visitor.c b/qapi/qapi-dealloc-visitor.c
index dc53545..a14a1c7 100644
--- a/qapi/qapi-dealloc-visitor.c
+++ b/qapi/qapi-dealloc-visitor.c
@@ -162,6 +162,31 @@ static void qapi_dealloc_type_enum(Visitor *v, int *obj, const char *strings[],
{
}
+/* If there's no data present, the dealloc visitor has nothing to free.
+ * Thus, indicate to visitor code that the subsequent union fields can
+ * be skipped. This is not an error condition, since the cleanup of the
+ * rest of an object can continue unhindered, so leave errp unset in
+ * these cases.
+ *
+ * NOTE: In cases where we're attempting to deallocate an object that
+ * may have missing fields, the field indicating the union type may
+ * be missing. In such a case, it's possible we don't have enough
+ * information to differentiate data_present == false from a case where
+ * data *is* present but happens to be a scalar with a value of 0.
+ * This is okay, since in the case of the dealloc visitor there's no
+ * work that needs to done in either situation.
+ *
+ * The current inability in QAPI code to more thoroughly verify a union
+ * type in such cases will likely need to be addressed if we wish to
+ * implement this interface for other types of visitors in the future,
+ * however.
+ */
+static bool qapi_dealloc_start_union(Visitor *v, bool data_present,
+ Error **errp)
+{
+ return data_present;
+}
+
Visitor *qapi_dealloc_get_visitor(QapiDeallocVisitor *v)
{
return &v->visitor;
@@ -191,6 +216,7 @@ QapiDeallocVisitor *qapi_dealloc_visitor_new(void)
v->visitor.type_str = qapi_dealloc_type_str;
v->visitor.type_number = qapi_dealloc_type_number;
v->visitor.type_size = qapi_dealloc_type_size;
+ v->visitor.start_union = qapi_dealloc_start_union;
QTAILQ_INIT(&v->stack);
--
1.9.3
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [Qemu-devel] [PULL 5/9] tests: add QMP input visitor test for unions with no discriminator
2014-09-26 19:03 [Qemu-devel] [PULL 0/9] QMP queue Luiz Capitulino
` (3 preceding siblings ...)
2014-09-26 19:04 ` [Qemu-devel] [PULL 4/9] qapi: dealloc visitor, implement visit_start_union Luiz Capitulino
@ 2014-09-26 19:04 ` Luiz Capitulino
2014-09-26 19:04 ` [Qemu-devel] [PULL 6/9] qemu-iotests: Test missing "driver" key for blockdev-add Luiz Capitulino
` (4 subsequent siblings)
9 siblings, 0 replies; 16+ messages in thread
From: Luiz Capitulino @ 2014-09-26 19:04 UTC (permalink / raw)
To: peter.maydell; +Cc: qemu-devel, anthony
From: Michael Roth <mdroth@linux.vnet.ibm.com>
This is more of an exercise of the dealloc visitor, where it may
erroneously use an uninitialized discriminator field as indication
that union fields corresponding to that discriminator field/type are
present, which can lead to attempts to free random chunks of heap
memory.
Cc: qemu-stable@nongnu.org
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
tests/qapi-schema/qapi-schema-test.json | 10 ++++++++++
tests/qapi-schema/qapi-schema-test.out | 3 +++
tests/test-qmp-input-strict.c | 17 +++++++++++++++++
3 files changed, 30 insertions(+)
diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json
index ab4d3d9..d43b5fd 100644
--- a/tests/qapi-schema/qapi-schema-test.json
+++ b/tests/qapi-schema/qapi-schema-test.json
@@ -33,6 +33,9 @@
{ 'type': 'UserDefB',
'data': { 'integer': 'int' } }
+{ 'type': 'UserDefC',
+ 'data': { 'string1': 'str', 'string2': 'str' } }
+
{ 'union': 'UserDefUnion',
'base': 'UserDefZero',
'data': { 'a' : 'UserDefA', 'b' : 'UserDefB' } }
@@ -47,6 +50,13 @@
# FIXME generated struct UserDefFlatUnion has members for direct base
# UserDefOne, but lacks members for indirect base UserDefZero
+# this variant of UserDefFlatUnion defaults to a union that uses fields with
+# allocated types to test corner cases in the cleanup/dealloc visitor
+{ 'union': 'UserDefFlatUnion2',
+ 'base': 'UserDefUnionBase',
+ 'discriminator': 'enum1',
+ 'data': { 'value1' : 'UserDefC', 'value2' : 'UserDefB', 'value3' : 'UserDefA' } }
+
{ 'union': 'UserDefAnonUnion',
'discriminator': {},
'data': { 'uda': 'UserDefA', 's': 'str', 'i': 'int' } }
diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out
index 95e9899..08d7304 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -6,9 +6,11 @@
OrderedDict([('type', 'UserDefNested'), ('data', OrderedDict([('string0', 'str'), ('dict1', OrderedDict([('string1', 'str'), ('dict2', OrderedDict([('userdef1', 'UserDefOne'), ('string2', 'str')])), ('*dict3', OrderedDict([('userdef2', 'UserDefOne'), ('string3', 'str')]))]))]))]),
OrderedDict([('type', 'UserDefA'), ('data', OrderedDict([('boolean', 'bool')]))]),
OrderedDict([('type', 'UserDefB'), ('data', OrderedDict([('integer', 'int')]))]),
+ OrderedDict([('type', 'UserDefC'), ('data', OrderedDict([('string1', 'str'), ('string2', 'str')]))]),
OrderedDict([('union', 'UserDefUnion'), ('base', 'UserDefZero'), ('data', OrderedDict([('a', 'UserDefA'), ('b', 'UserDefB')]))]),
OrderedDict([('type', 'UserDefUnionBase'), ('data', OrderedDict([('string', 'str'), ('enum1', 'EnumOne')]))]),
OrderedDict([('union', 'UserDefFlatUnion'), ('base', 'UserDefUnionBase'), ('discriminator', 'enum1'), ('data', OrderedDict([('value1', 'UserDefA'), ('value2', 'UserDefB'), ('value3', 'UserDefB')]))]),
+ OrderedDict([('union', 'UserDefFlatUnion2'), ('base', 'UserDefUnionBase'), ('discriminator', 'enum1'), ('data', OrderedDict([('value1', 'UserDefC'), ('value2', 'UserDefB'), ('value3', 'UserDefA')]))]),
OrderedDict([('union', 'UserDefAnonUnion'), ('discriminator', OrderedDict()), ('data', OrderedDict([('uda', 'UserDefA'), ('s', 'str'), ('i', 'int')]))]),
OrderedDict([('union', 'UserDefNativeListUnion'), ('data', OrderedDict([('integer', ['int']), ('s8', ['int8']), ('s16', ['int16']), ('s32', ['int32']), ('s64', ['int64']), ('u8', ['uint8']), ('u16', ['uint16']), ('u32', ['uint32']), ('u64', ['uint64']), ('number', ['number']), ('boolean', ['bool']), ('string', ['str'])]))]),
OrderedDict([('command', 'user_def_cmd'), ('data', OrderedDict())]),
@@ -32,6 +34,7 @@
OrderedDict([('type', 'UserDefNested'), ('data', OrderedDict([('string0', 'str'), ('dict1', OrderedDict([('string1', 'str'), ('dict2', OrderedDict([('userdef1', 'UserDefOne'), ('string2', 'str')])), ('*dict3', OrderedDict([('userdef2', 'UserDefOne'), ('string3', 'str')]))]))]))]),
OrderedDict([('type', 'UserDefA'), ('data', OrderedDict([('boolean', 'bool')]))]),
OrderedDict([('type', 'UserDefB'), ('data', OrderedDict([('integer', 'int')]))]),
+ OrderedDict([('type', 'UserDefC'), ('data', OrderedDict([('string1', 'str'), ('string2', 'str')]))]),
OrderedDict([('type', 'UserDefUnionBase'), ('data', OrderedDict([('string', 'str'), ('enum1', 'EnumOne')]))]),
OrderedDict([('type', 'UserDefOptions'), ('data', OrderedDict([('*i64', ['int']), ('*u64', ['uint64']), ('*u16', ['uint16']), ('*i64x', 'int'), ('*u64x', 'uint64')]))]),
OrderedDict([('type', 'EventStructOne'), ('data', OrderedDict([('struct1', 'UserDefOne'), ('string', 'str'), ('*enum2', 'EnumOne')]))])]
diff --git a/tests/test-qmp-input-strict.c b/tests/test-qmp-input-strict.c
index 0f77003..d5360c6 100644
--- a/tests/test-qmp-input-strict.c
+++ b/tests/test-qmp-input-strict.c
@@ -260,6 +260,21 @@ static void test_validate_fail_union_flat(TestInputVisitorData *data,
qapi_free_UserDefFlatUnion(tmp);
}
+static void test_validate_fail_union_flat_no_discrim(TestInputVisitorData *data,
+ const void *unused)
+{
+ UserDefFlatUnion2 *tmp = NULL;
+ Error *err = NULL;
+ Visitor *v;
+
+ /* test situation where discriminator field ('enum1' here) is missing */
+ v = validate_test_init(data, "{ 'string': 'c', 'string1': 'd', 'string2': 'e' }");
+
+ visit_type_UserDefFlatUnion2(v, &tmp, NULL, &err);
+ g_assert(err);
+ qapi_free_UserDefFlatUnion2(tmp);
+}
+
static void test_validate_fail_union_anon(TestInputVisitorData *data,
const void *unused)
{
@@ -310,6 +325,8 @@ int main(int argc, char **argv)
&testdata, test_validate_fail_union);
validate_test_add("/visitor/input-strict/fail/union-flat",
&testdata, test_validate_fail_union_flat);
+ validate_test_add("/visitor/input-strict/fail/union-flat-no-discriminator",
+ &testdata, test_validate_fail_union_flat_no_discrim);
validate_test_add("/visitor/input-strict/fail/union-anon",
&testdata, test_validate_fail_union_anon);
--
1.9.3
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [Qemu-devel] [PULL 6/9] qemu-iotests: Test missing "driver" key for blockdev-add
2014-09-26 19:03 [Qemu-devel] [PULL 0/9] QMP queue Luiz Capitulino
` (4 preceding siblings ...)
2014-09-26 19:04 ` [Qemu-devel] [PULL 5/9] tests: add QMP input visitor test for unions with no discriminator Luiz Capitulino
@ 2014-09-26 19:04 ` Luiz Capitulino
2014-09-26 19:04 ` [Qemu-devel] [PULL 7/9] qemu-socket: Polish errors for connect() and listen() failure Luiz Capitulino
` (3 subsequent siblings)
9 siblings, 0 replies; 16+ messages in thread
From: Luiz Capitulino @ 2014-09-26 19:04 UTC (permalink / raw)
To: peter.maydell; +Cc: qemu-devel, anthony
From: Fam Zheng <famz@redhat.com>
Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
tests/qemu-iotests/087 | 17 +++++++++++++++++
tests/qemu-iotests/087.out | 13 +++++++++++++
2 files changed, 30 insertions(+)
diff --git a/tests/qemu-iotests/087 b/tests/qemu-iotests/087
index 82c56b1..d7454d1 100755
--- a/tests/qemu-iotests/087
+++ b/tests/qemu-iotests/087
@@ -218,6 +218,23 @@ run_qemu <<EOF
{ "execute": "quit" }
EOF
+echo
+echo === Missing driver ===
+echo
+
+_make_test_img -o encryption=on $size
+run_qemu -S <<EOF
+{ "execute": "qmp_capabilities" }
+{ "execute": "blockdev-add",
+ "arguments": {
+ "options": {
+ "id": "disk"
+ }
+ }
+ }
+{ "execute": "quit" }
+EOF
+
# success, all done
echo "*** done"
rm -f $seq.full
diff --git a/tests/qemu-iotests/087.out b/tests/qemu-iotests/087.out
index 7fbee3f..f16bad0 100644
--- a/tests/qemu-iotests/087.out
+++ b/tests/qemu-iotests/087.out
@@ -64,4 +64,17 @@ QMP_VERSION
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "ide1-cd0", "tray-open": true}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "floppy0", "tray-open": true}}
+
+=== Missing driver ===
+
+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"}}
+{"return": {}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN"}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "ide1-cd0", "tray-open": true}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "floppy0", "tray-open": true}}
+
*** done
--
1.9.3
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [Qemu-devel] [PULL 7/9] qemu-socket: Polish errors for connect() and listen() failure
2014-09-26 19:03 [Qemu-devel] [PULL 0/9] QMP queue Luiz Capitulino
` (5 preceding siblings ...)
2014-09-26 19:04 ` [Qemu-devel] [PULL 6/9] qemu-iotests: Test missing "driver" key for blockdev-add Luiz Capitulino
@ 2014-09-26 19:04 ` Luiz Capitulino
2014-09-26 19:04 ` [Qemu-devel] [PULL 8/9] qemu-socket: Eliminate silly QERR_ macros Luiz Capitulino
` (2 subsequent siblings)
9 siblings, 0 replies; 16+ messages in thread
From: Luiz Capitulino @ 2014-09-26 19:04 UTC (permalink / raw)
To: peter.maydell; +Cc: qemu-devel, anthony
From: Markus Armbruster <armbru@redhat.com>
connect() doesn't "connect to socket", it connects a socket to an
address and, if it's of type SOCK_STREAM, initiates a connection.
Scratch "to".
listen() does "set socket to listening mode", but it sounds awkward.
Change to "listen on socket".
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Gonglei <arei.gonglei@huawei.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
include/qapi/qmp/qerror.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/qapi/qmp/qerror.h b/include/qapi/qmp/qerror.h
index 902d1a7..774e75d 100644
--- a/include/qapi/qmp/qerror.h
+++ b/include/qapi/qmp/qerror.h
@@ -155,10 +155,10 @@ void qerror_report_err(Error *err);
ERROR_CLASS_GENERIC_ERROR, "this feature or command is not currently supported"
#define QERR_SOCKET_CONNECT_FAILED \
- ERROR_CLASS_GENERIC_ERROR, "Failed to connect to socket"
+ ERROR_CLASS_GENERIC_ERROR, "Failed to connect socket"
#define QERR_SOCKET_LISTEN_FAILED \
- ERROR_CLASS_GENERIC_ERROR, "Failed to set socket to listening mode"
+ ERROR_CLASS_GENERIC_ERROR, "Failed to listen on socket"
#define QERR_SOCKET_BIND_FAILED \
ERROR_CLASS_GENERIC_ERROR, "Failed to bind socket"
--
1.9.3
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [Qemu-devel] [PULL 8/9] qemu-socket: Eliminate silly QERR_ macros
2014-09-26 19:03 [Qemu-devel] [PULL 0/9] QMP queue Luiz Capitulino
` (6 preceding siblings ...)
2014-09-26 19:04 ` [Qemu-devel] [PULL 7/9] qemu-socket: Polish errors for connect() and listen() failure Luiz Capitulino
@ 2014-09-26 19:04 ` Luiz Capitulino
2014-09-26 19:04 ` [Qemu-devel] [PULL 9/9] Add HMP command "info memory-devices" Luiz Capitulino
2014-09-29 18:27 ` [Qemu-devel] [PULL 0/9] QMP queue Peter Maydell
9 siblings, 0 replies; 16+ messages in thread
From: Luiz Capitulino @ 2014-09-26 19:04 UTC (permalink / raw)
To: peter.maydell; +Cc: qemu-devel, anthony
From: Markus Armbruster <armbru@redhat.com>
The QERR_ macros are leftovers from the days of "rich" error objects.
They're used with error_set() and qerror_report(), and expand into the
first *two* arguments. This trickiness has become pointless. Clean
up.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
include/qapi/qmp/qerror.h | 12 ------------
util/qemu-sockets.c | 26 +++++++++++++-------------
2 files changed, 13 insertions(+), 25 deletions(-)
diff --git a/include/qapi/qmp/qerror.h b/include/qapi/qmp/qerror.h
index 774e75d..0ca6cbd 100644
--- a/include/qapi/qmp/qerror.h
+++ b/include/qapi/qmp/qerror.h
@@ -154,16 +154,4 @@ void qerror_report_err(Error *err);
#define QERR_UNSUPPORTED \
ERROR_CLASS_GENERIC_ERROR, "this feature or command is not currently supported"
-#define QERR_SOCKET_CONNECT_FAILED \
- ERROR_CLASS_GENERIC_ERROR, "Failed to connect socket"
-
-#define QERR_SOCKET_LISTEN_FAILED \
- ERROR_CLASS_GENERIC_ERROR, "Failed to listen on socket"
-
-#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/util/qemu-sockets.c b/util/qemu-sockets.c
index 4a25585..1eef590 100644
--- a/util/qemu-sockets.c
+++ b/util/qemu-sockets.c
@@ -159,7 +159,7 @@ int inet_listen_opts(QemuOpts *opts, int port_offset, Error **errp)
slisten = qemu_socket(e->ai_family, e->ai_socktype, e->ai_protocol);
if (slisten < 0) {
if (!e->ai_next) {
- error_set_errno(errp, errno, QERR_SOCKET_CREATE_FAILED);
+ error_setg_errno(errp, errno, "Failed to create socket");
}
continue;
}
@@ -183,7 +183,7 @@ int inet_listen_opts(QemuOpts *opts, int port_offset, Error **errp)
}
if (p == port_max) {
if (!e->ai_next) {
- error_set_errno(errp, errno, QERR_SOCKET_BIND_FAILED);
+ error_setg_errno(errp, errno, "Failed to bind socket");
}
}
}
@@ -194,7 +194,7 @@ int inet_listen_opts(QemuOpts *opts, int port_offset, Error **errp)
listen:
if (listen(slisten,1) != 0) {
- error_set_errno(errp, errno, QERR_SOCKET_LISTEN_FAILED);
+ error_setg_errno(errp, errno, "Failed to listen on socket");
closesocket(slisten);
freeaddrinfo(res);
return -1;
@@ -281,7 +281,7 @@ static int inet_connect_addr(struct addrinfo *addr, bool *in_progress,
sock = qemu_socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
if (sock < 0) {
- error_set_errno(errp, errno, QERR_SOCKET_CREATE_FAILED);
+ error_setg_errno(errp, errno, "Failed to create socket");
return -1;
}
socket_set_fast_reuse(sock);
@@ -302,7 +302,7 @@ static int inet_connect_addr(struct addrinfo *addr, bool *in_progress,
connect_state);
*in_progress = true;
} else if (rc < 0) {
- error_set_errno(errp, errno, QERR_SOCKET_CONNECT_FAILED);
+ error_setg_errno(errp, errno, "Failed to connect socket");
closesocket(sock);
return -1;
}
@@ -466,20 +466,20 @@ int inet_dgram_opts(QemuOpts *opts, Error **errp)
/* create socket */
sock = qemu_socket(peer->ai_family, peer->ai_socktype, peer->ai_protocol);
if (sock < 0) {
- error_set_errno(errp, errno, QERR_SOCKET_CREATE_FAILED);
+ error_setg_errno(errp, errno, "Failed to create socket");
goto err;
}
socket_set_fast_reuse(sock);
/* bind socket */
if (bind(sock, local->ai_addr, local->ai_addrlen) < 0) {
- error_set_errno(errp, errno, QERR_SOCKET_BIND_FAILED);
+ error_setg_errno(errp, errno, "Failed to bind socket");
goto err;
}
/* connect to peer */
if (connect(sock,peer->ai_addr,peer->ai_addrlen) < 0) {
- error_set_errno(errp, errno, QERR_SOCKET_CONNECT_FAILED);
+ error_setg_errno(errp, errno, "Failed to connect socket");
goto err;
}
@@ -684,7 +684,7 @@ int unix_listen_opts(QemuOpts *opts, Error **errp)
sock = qemu_socket(PF_UNIX, SOCK_STREAM, 0);
if (sock < 0) {
- error_set_errno(errp, errno, QERR_SOCKET_CREATE_FAILED);
+ error_setg_errno(errp, errno, "Failed to create socket");
return -1;
}
@@ -709,11 +709,11 @@ int unix_listen_opts(QemuOpts *opts, Error **errp)
unlink(un.sun_path);
if (bind(sock, (struct sockaddr*) &un, sizeof(un)) < 0) {
- error_set_errno(errp, errno, QERR_SOCKET_BIND_FAILED);
+ error_setg_errno(errp, errno, "Failed to bind socket");
goto err;
}
if (listen(sock, 1) < 0) {
- error_set_errno(errp, errno, QERR_SOCKET_LISTEN_FAILED);
+ error_setg_errno(errp, errno, "Failed to listen on socket");
goto err;
}
@@ -739,7 +739,7 @@ int unix_connect_opts(QemuOpts *opts, Error **errp,
sock = qemu_socket(PF_UNIX, SOCK_STREAM, 0);
if (sock < 0) {
- error_set_errno(errp, errno, QERR_SOCKET_CREATE_FAILED);
+ error_setg_errno(errp, errno, "Failed to create socket");
return -1;
}
if (callback != NULL) {
@@ -774,7 +774,7 @@ int unix_connect_opts(QemuOpts *opts, Error **errp,
}
if (rc < 0) {
- error_set_errno(errp, -rc, QERR_SOCKET_CONNECT_FAILED);
+ error_setg_errno(errp, -rc, "Failed to connect socket");
close(sock);
sock = -1;
}
--
1.9.3
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [Qemu-devel] [PULL 9/9] Add HMP command "info memory-devices"
2014-09-26 19:03 [Qemu-devel] [PULL 0/9] QMP queue Luiz Capitulino
` (7 preceding siblings ...)
2014-09-26 19:04 ` [Qemu-devel] [PULL 8/9] qemu-socket: Eliminate silly QERR_ macros Luiz Capitulino
@ 2014-09-26 19:04 ` Luiz Capitulino
2014-09-29 18:27 ` [Qemu-devel] [PULL 0/9] QMP queue Peter Maydell
9 siblings, 0 replies; 16+ messages in thread
From: Luiz Capitulino @ 2014-09-26 19:04 UTC (permalink / raw)
To: peter.maydell; +Cc: qemu-devel, anthony
From: Zhu Guihua <zhugh.fnst@cn.fujitsu.com>
Provides HMP equivalent of QMP query-memory-devices command.
Signed-off-by: Zhu Guihua <zhugh.fnst@cn.fujitsu.com>
Reviewed-By: Igor Mammedov <imammedo@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
hmp-commands.hx | 2 ++
hmp.c | 38 ++++++++++++++++++++++++++++++++++++++
hmp.h | 1 +
monitor.c | 7 +++++++
4 files changed, 48 insertions(+)
diff --git a/hmp-commands.hx b/hmp-commands.hx
index f859f8d..0b1a4f7 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1778,6 +1778,8 @@ show qdev device model list
show roms
@item info tpm
show the TPM device
+@item info memory-devices
+show the memory devices
@end table
ETEXI
diff --git a/hmp.c b/hmp.c
index 31fb6a1..63d7686 100644
--- a/hmp.c
+++ b/hmp.c
@@ -1720,3 +1720,41 @@ void hmp_info_memdev(Monitor *mon, const QDict *qdict)
qapi_free_MemdevList(memdev_list);
}
+
+void hmp_info_memory_devices(Monitor *mon, const QDict *qdict)
+{
+ Error *err = NULL;
+ MemoryDeviceInfoList *info_list = qmp_query_memory_devices(&err);
+ MemoryDeviceInfoList *info;
+ MemoryDeviceInfo *value;
+ PCDIMMDeviceInfo *di;
+
+ for (info = info_list; info; info = info->next) {
+ value = info->value;
+
+ if (value) {
+ switch (value->kind) {
+ case MEMORY_DEVICE_INFO_KIND_DIMM:
+ di = value->dimm;
+
+ monitor_printf(mon, "Memory device [%s]: \"%s\"\n",
+ MemoryDeviceInfoKind_lookup[value->kind],
+ di->id ? di->id : "");
+ monitor_printf(mon, " addr: 0x%" PRIx64 "\n", di->addr);
+ monitor_printf(mon, " slot: %" PRId64 "\n", di->slot);
+ monitor_printf(mon, " node: %" PRId64 "\n", di->node);
+ monitor_printf(mon, " size: %" PRIu64 "\n", di->size);
+ monitor_printf(mon, " memdev: %s\n", di->memdev);
+ monitor_printf(mon, " hotplugged: %s\n",
+ di->hotplugged ? "true" : "false");
+ monitor_printf(mon, " hotpluggable: %s\n",
+ di->hotpluggable ? "true" : "false");
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ qapi_free_MemoryDeviceInfoList(info_list);
+}
diff --git a/hmp.h b/hmp.h
index 4fd3c4a..4bb5dca 100644
--- a/hmp.h
+++ b/hmp.h
@@ -94,6 +94,7 @@ void hmp_cpu_add(Monitor *mon, const QDict *qdict);
void hmp_object_add(Monitor *mon, const QDict *qdict);
void hmp_object_del(Monitor *mon, const QDict *qdict);
void hmp_info_memdev(Monitor *mon, const QDict *qdict);
+void hmp_info_memory_devices(Monitor *mon, const QDict *qdict);
void object_add_completion(ReadLineState *rs, int nb_args, const char *str);
void object_del_completion(ReadLineState *rs, int nb_args, const char *str);
void device_add_completion(ReadLineState *rs, int nb_args, const char *str);
diff --git a/monitor.c b/monitor.c
index 48850af..2d14f39 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2922,6 +2922,13 @@ static mon_cmd_t info_cmds[] = {
.mhandler.cmd = hmp_info_memdev,
},
{
+ .name = "memory-devices",
+ .args_type = "",
+ .params = "",
+ .help = "show memory devices",
+ .mhandler.cmd = hmp_info_memory_devices,
+ },
+ {
.name = NULL,
},
};
--
1.9.3
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [Qemu-devel] [PULL 0/9] QMP queue
2014-09-26 19:03 [Qemu-devel] [PULL 0/9] QMP queue Luiz Capitulino
` (8 preceding siblings ...)
2014-09-26 19:04 ` [Qemu-devel] [PULL 9/9] Add HMP command "info memory-devices" Luiz Capitulino
@ 2014-09-29 18:27 ` Peter Maydell
9 siblings, 0 replies; 16+ messages in thread
From: Peter Maydell @ 2014-09-29 18:27 UTC (permalink / raw)
To: Luiz Capitulino; +Cc: QEMU Developers, Anthony Liguori
On 26 September 2014 20:03, Luiz Capitulino <lcapitulino@redhat.com> wrote:
> The following changes since commit 81ab11a7a524d12412a59ef49c6b270671e62ea0:
>
> Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging (2014-09-26 15:41:50 +0100)
>
> are available in the git repository at:
>
>
> git://repo.or.cz/qemu/qmp-unstable.git queue/qmp
>
> for you to fetch changes up to a631892f9d6440812af98588e9635f1a2a7260ff:
>
> Add HMP command "info memory-devices" (2014-09-26 13:37:06 -0400)
Applied, thanks.
-- PMM
^ permalink raw reply [flat|nested] 16+ messages in thread