aboutsummaryrefslogtreecommitdiff
path: root/vl.c
diff options
context:
space:
mode:
authorEric Blake <eblake@redhat.com>2016-01-29 06:48:44 -0700
committerMarkus Armbruster <armbru@redhat.com>2016-02-08 17:29:55 +0100
commit014791b0df927226b794d14696724b9c9c0583d0 (patch)
tree8e066fa253f79824a26789ec0ba51ef52e2e6817 /vl.c
parent9b65859d5e2e43fa89365224c5330e8c72ab760b (diff)
vl: Ensure qapi visitor properly ends struct visit
Guarantee that visit_end_struct() is called if visit_start_struct() succeeded. This matches the behavior of most other uses of visitors, and is a step towards the possibility of a future patch that adds and enforces some tighter semantics to the visitor interface (namely, cleanup of the visitor would no longer have to mop up as many leftovers from an aborted partial visit). The change to code here matches the flow of hmp.c:hmp_object_add(); a later patch will then further simplify the cleanup logic of both places by refactoring visit_end_struct() to not require a second local error object. Signed-off-by: Eric Blake <eblake@redhat.com> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> Message-Id: <1454075341-13658-9-git-send-email-eblake@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
Diffstat (limited to 'vl.c')
-rw-r--r--vl.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/vl.c b/vl.c
index 245b2bad6d..300a609479 100644
--- a/vl.c
+++ b/vl.c
@@ -2819,6 +2819,7 @@ static bool object_create_delayed(const char *type)
static int object_create(void *opaque, QemuOpts *opts, Error **errp)
{
Error *err = NULL;
+ Error *err_end = NULL;
char *type = NULL;
char *id = NULL;
OptsVisitor *ov;
@@ -2841,23 +2842,24 @@ static int object_create(void *opaque, QemuOpts *opts, Error **errp)
goto out;
}
if (!type_predicate(type)) {
+ visit_end_struct(v, NULL);
goto out;
}
qdict_del(pdict, "id");
visit_type_str(v, &id, "id", &err);
if (err) {
- goto out;
+ goto out_end;
}
object_add(type, id, pdict, v, &err);
- if (err) {
- goto out;
- }
- visit_end_struct(v, &err);
- if (err) {
+
+out_end:
+ visit_end_struct(v, &err_end);
+ if (!err && err_end) {
qmp_object_del(id, NULL);
}
+ error_propagate(&err, err_end);
out:
opts_visitor_cleanup(ov);