From patchwork Wed Jan 6 22:15:37 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Blake X-Patchwork-Id: 564119 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 5FDCA14030F for ; Thu, 7 Jan 2016 09:16:07 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; secure) header.d=comcast.net header.i=@comcast.net header.b=fvEC8Wd7; dkim-atps=neutral Received: from localhost ([::1]:56243 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aGwNA-0006lZ-Td for incoming@patchwork.ozlabs.org; Wed, 06 Jan 2016 17:16:04 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:55321) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aGwMv-0006U4-Hl for qemu-devel@nongnu.org; Wed, 06 Jan 2016 17:15:50 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aGwMr-0007Qs-G9 for qemu-devel@nongnu.org; Wed, 06 Jan 2016 17:15:49 -0500 Received: from resqmta-po-11v.sys.comcast.net ([96.114.154.170]:36104) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aGwMr-0007Qo-8Z for qemu-devel@nongnu.org; Wed, 06 Jan 2016 17:15:45 -0500 Received: from resomta-po-08v.sys.comcast.net ([96.114.154.232]) by resqmta-po-11v.sys.comcast.net with comcast id 2mFN1s003516pyw01mFkkC; Wed, 06 Jan 2016 22:15:44 +0000 Received: from red.redhat.com ([24.10.254.122]) by resomta-po-08v.sys.comcast.net with comcast id 2mFg1s0012fD5rL01mFjRG; Wed, 06 Jan 2016 22:15:44 +0000 From: Eric Blake To: qemu-devel@nongnu.org Date: Wed, 6 Jan 2016 15:15:37 -0700 Message-Id: <1452118537-23911-1-git-send-email-eblake@redhat.com> X-Mailer: git-send-email 2.4.3 In-Reply-To: <1450717720-9627-23-git-send-email-eblake@redhat.com> References: <1450717720-9627-23-git-send-email-eblake@redhat.com> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=comcast.net; s=q20140121; t=1452118544; bh=4zQZ2ETidd1eQ5AoGcJqHnKMWA9zAGfY2Ri5DS0mtto=; h=Received:Received:From:To:Subject:Date:Message-Id; b=fvEC8Wd7uoT/TBlCB5QYWULtttZiqJWw+3GjQYlL9te5tkTQFh6E8nNWsvYjxpnFf 2s6ICmwXEdUGNFArW2YuDWSaboeGhdjRk1Cxu9CnTnUmSaAEW0BjpPWtYuDAkOifDv HGjfZah8YLUY51/TKAUlPCzqXuig2zHlnD9cM10m4UoAP5O1Lm/nbBR4HTcO5GRa/o s9s2uJljNldcVkdnlpBD9VQ0MtDrRXDVCwrJGS+8TBOq4ecmRVf9th1ye556fW9Eeu GaoYIcD/55P3kmM2AvnLtzow3Q0y9lagJ4J2AevknoKFQuOB4NR3+A6WbhqQtkin2c gzSnn/TnE3wfQ== X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 96.114.154.170 Cc: marcandre.lureau@redhat.com, armbru@redhat.com, Michael Roth Subject: [Qemu-devel] [PATCH v8 22.5/35] qmp: Support explicit null on input visit X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Implement the new type_null() callback for the qmp input visitor. While we don't yet have a use for this in qapi (the generator will need some tweaks first), one usage is already envisioned: when changing blockdev parameters, it would be nice to have a difference between leaving a tuning parameter unchanged (omit that parameter from the struct) and to explicitly reset the parameter to its default without having to know what the default value is (specify the parameter with an explicit null value, which will require us to allow a qapi alternate that chooses between the normal values and an explicit null). At any rate, we can test this without the use of generated qapi by manually using visit_start_struct()/visit_end_struct(). Signed-off-by: Eric Blake --- v9: new patch --- include/qapi/visitor-impl.h | 2 +- qapi/qmp-input-visitor.c | 14 ++++++++++++++ tests/test-qmp-input-visitor.c | 26 ++++++++++++++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/include/qapi/visitor-impl.h b/include/qapi/visitor-impl.h index 8705136..95408a5 100644 --- a/include/qapi/visitor-impl.h +++ b/include/qapi/visitor-impl.h @@ -76,7 +76,7 @@ struct Visitor void (*type_any)(Visitor *v, const char *name, QObject **obj, Error **errp); /* Must be provided to visit explicit null values (right now, only the - * dealloc visitor supports this). */ + * dealloc and qmp-input visitors support this). */ void (*type_null)(Visitor *v, const char *name, Error **errp); /* May be NULL; most useful for input visitors. */ diff --git a/qapi/qmp-input-visitor.c b/qapi/qmp-input-visitor.c index 597652c..ad23bec 100644 --- a/qapi/qmp-input-visitor.c +++ b/qapi/qmp-input-visitor.c @@ -315,6 +315,19 @@ static void qmp_input_type_any(Visitor *v, const char *name, QObject **obj, *obj = qobj; } +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); + + if (qobject_type(qobj) == QTYPE_QNULL) { + return; + } + + error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null", + "null"); +} + static void qmp_input_optional(Visitor *v, const char *name, bool *present) { QmpInputVisitor *qiv = to_qiv(v); @@ -358,6 +371,7 @@ QmpInputVisitor *qmp_input_visitor_new(QObject *obj) v->visitor.type_str = qmp_input_type_str; v->visitor.type_number = qmp_input_type_number; v->visitor.type_any = qmp_input_type_any; + v->visitor.type_null = qmp_input_type_null; v->visitor.optional = qmp_input_optional; v->visitor.get_next_type = qmp_input_get_next_type; diff --git a/tests/test-qmp-input-visitor.c b/tests/test-qmp-input-visitor.c index f6bd408..6489e4a 100644 --- a/tests/test-qmp-input-visitor.c +++ b/tests/test-qmp-input-visitor.c @@ -278,6 +278,30 @@ static void test_visitor_in_any(TestInputVisitorData *data, qobject_decref(res); } +static void test_visitor_in_null(TestInputVisitorData *data, + const void *unused) +{ + Visitor *v; + QObject *null; + + v = visitor_input_test_init(data, "null"); + visit_type_null(v, NULL, &error_abort); + + v = visitor_input_test_init(data, "{ 'a': null }"); + visit_start_struct(v, NULL, NULL, 0, &error_abort); + visit_type_null(v, "a", &error_abort); + visit_end_struct(v, &error_abort); + + /* Check that qnull reference counting is sane: + * 1 for global use, 1 for our qnull() use, and 1 still owned by 'v' + * until it is torn down */ + null = qnull(); + g_assert(null->refcnt == 3); + visitor_input_teardown(data, NULL); + g_assert(null->refcnt == 2); + qobject_decref(null); +} + static void test_visitor_in_union_flat(TestInputVisitorData *data, const void *unused) { @@ -792,6 +816,8 @@ int main(int argc, char **argv) &in_visitor_data, test_visitor_in_list); input_visitor_test_add("/visitor/input/any", &in_visitor_data, test_visitor_in_any); + input_visitor_test_add("/visitor/input/null", + &in_visitor_data, test_visitor_in_null); input_visitor_test_add("/visitor/input/union-flat", &in_visitor_data, test_visitor_in_union_flat); input_visitor_test_add("/visitor/input/alternate",