From patchwork Wed Nov 30 21:03:40 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anthony Liguori X-Patchwork-Id: 128583 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [140.186.70.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 0E8CA1007D1 for ; Thu, 1 Dec 2011 08:05:59 +1100 (EST) Received: from localhost ([::1]:58406 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RVrLJ-0007Yj-LO for incoming@patchwork.ozlabs.org; Wed, 30 Nov 2011 16:05:25 -0500 Received: from eggs.gnu.org ([140.186.70.92]:35270) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RVrL5-0007Cd-KH for qemu-devel@nongnu.org; Wed, 30 Nov 2011 16:05:15 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1RVrL0-0000dl-M5 for qemu-devel@nongnu.org; Wed, 30 Nov 2011 16:05:08 -0500 Received: from cpe-70-123-132-139.austin.res.rr.com ([70.123.132.139]:37052 helo=localhost6.localdomain6) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RVrKz-0000ag-Ti for qemu-devel@nongnu.org; Wed, 30 Nov 2011 16:05:06 -0500 Received: from localhost6.localdomain6 (localhost.localdomain [127.0.0.1]) by localhost6.localdomain6 (8.14.4/8.14.4/Debian-2ubuntu1) with ESMTP id pAUL4col030138; Wed, 30 Nov 2011 15:04:38 -0600 Received: (from anthony@localhost) by localhost6.localdomain6 (8.14.4/8.14.4/Submit) id pAUL4abt030137; Wed, 30 Nov 2011 15:04:36 -0600 From: Anthony Liguori To: qemu-devel@nongnu.org Date: Wed, 30 Nov 2011 15:03:40 -0600 Message-Id: <1322687028-29714-11-git-send-email-aliguori@us.ibm.com> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1322687028-29714-1-git-send-email-aliguori@us.ibm.com> References: <1322687028-29714-1-git-send-email-aliguori@us.ibm.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 70.123.132.139 Cc: Kevin Wolf , Peter Maydell , Anthony Liguori , Stefan Hajnoczi , Jan Kiszka , Markus Armbruster , Luiz Capitulino Subject: [Qemu-devel] [PATCH 10/18] qom: qom_{get,set} monitor commands 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 This allows clients to read and write device model properties through QMP. QAPI doesn't support Visitor types yet and these commands are special in that they don't work with fixed types. I've added a documentation stub to qapi-schema.json so we can keep consistency there. Signed-off-by: Anthony Liguori --- monitor.h | 4 +++ qapi-schema.json | 59 +++++++++++++++++++++++++++++++++++++++++++++++++ qmp-commands.hx | 12 ++++++++++ qmp.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 140 insertions(+), 0 deletions(-) diff --git a/monitor.h b/monitor.h index e76795f..efc76c7 100644 --- a/monitor.h +++ b/monitor.h @@ -64,4 +64,8 @@ typedef void (MonitorCompletion)(void *opaque, QObject *ret_data); void monitor_set_error(Monitor *mon, QError *qerror); +int qmp_qom_set(Monitor *mon, const QDict *qdict, QObject **ret); + +int qmp_qom_get(Monitor *mon, const QDict *qdict, QObject **ret); + #endif /* !MONITOR_H */ diff --git a/qapi-schema.json b/qapi-schema.json index 276b7c3..df99e94 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -935,3 +935,62 @@ { 'command': 'qom-list', 'data': { 'path': 'str' }, 'returns': [ 'DevicePropertyInfo' ] } + +## +# @qom-get: +# +# This command will get a property from a device model path and return the +# value. +# +# @path: The path within the device model. There are two forms of supported +# paths--absolute and partial paths. +# +# Absolute paths are derived from the root device and can follow child<> +# or link<> properties. Since they can follow link<> properties, they +# can be arbitrarily long. Absolute paths look like absolute filenames +# and are prefixed with a leading slash. +# +# Partial paths are look like relative filenames. They do not begin +# with a prefix. The matching rules for partial paths are subtle but +# designed to make specifying devices easy. At each level of the +# composition tree, the partial path is matched as an absolute path. +# The first match is not returned. At least two matches are searched +# for. A successful result is only returned if only one match is +# founded. If more than one match is found, a flag is return to +# indicate that the match was ambiguous. +# +# @property: The property name to read +# +# Returns: The property value. The type depends on the property type. legacy<> +# properties are returned as #str. child<> and link<> properties are +# returns as #str pathnames. All integer property types (u8, u16, etc) +# are returned as #int. +# +# Since: 1.1 +# +# Notes: This command is experimental and may change syntax in future releases. +## +{ 'command': 'qom-get', + 'data': { 'path': 'str', 'property': 'str' }, + 'returns': 'visitor', + 'gen': 'no' } + +## +# @qom-set: +# +# This command will set a property from a device model path. +# +# @path: see @qom-get for a description of this parameter +# +# @property: the property name to set +# +# @value: a value who's type is appropriate for the property type. See @qom-get +# for a description of type mapping. +# +# Since: 1.1 +# +# Notes: This command is experimental and may change syntax in future releases. +## +{ 'command': 'qom-set', + 'data': { 'path': 'str', 'property': 'str', 'value': 'visitor' }, + 'gen': 'no' } diff --git a/qmp-commands.hx b/qmp-commands.hx index d6ff466..027189a 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -2007,3 +2007,15 @@ EQMP .args_type = "path:s", .mhandler.cmd_new = qmp_marshal_input_qom_list, }, + + { + .name = "qom-set", + .args_type = "path:s,property:s,opts:O", + .mhandler.cmd_new = qmp_qom_set, + }, + + { + .name = "qom-get", + .args_type = "path:s,property:s", + .mhandler.cmd_new = qmp_qom_get, + }, diff --git a/qmp.c b/qmp.c index b9f0572..e917db4 100644 --- a/qmp.c +++ b/qmp.c @@ -17,6 +17,8 @@ #include "kvm.h" #include "arch_init.h" #include "hw/qdev.h" +#include "qapi/qmp-input-visitor.h" +#include "qapi/qmp-output-visitor.h" NameInfo *qmp_query_name(Error **errp) { @@ -146,3 +148,66 @@ DevicePropertyInfoList *qmp_qom_list(const char *path, Error **errp) return props; } + +/* FIXME: teach qapi about how to pass through Visitors */ +int qmp_qom_set(Monitor *mon, const QDict *qdict, QObject **ret) +{ + const char *path = qdict_get_str(qdict, "path"); + const char *property = qdict_get_str(qdict, "property"); + QObject *value = qdict_get(qdict, "value"); + Error *local_err = NULL; + QmpInputVisitor *mi; + DeviceState *dev; + + dev = qdev_resolve_path(path, NULL); + if (!dev) { + error_set(&local_err, QERR_DEVICE_NOT_FOUND, path); + goto out; + } + + mi = qmp_input_visitor_new(value); + qdev_property_set(dev, qmp_input_get_visitor(mi), property, &local_err); + + qmp_input_visitor_cleanup(mi); + +out: + if (local_err) { + qerror_report_err(local_err); + error_free(local_err); + return -1; + } + + return 0; +} + +int qmp_qom_get(Monitor *mon, const QDict *qdict, QObject **ret) +{ + const char *path = qdict_get_str(qdict, "path"); + const char *property = qdict_get_str(qdict, "property"); + Error *local_err = NULL; + QmpOutputVisitor *mo; + DeviceState *dev; + + dev = qdev_resolve_path(path, NULL); + if (!dev) { + error_set(&local_err, QERR_DEVICE_NOT_FOUND, path); + goto out; + } + + mo = qmp_output_visitor_new(); + qdev_property_get(dev, qmp_output_get_visitor(mo), property, &local_err); + if (!local_err) { + *ret = qmp_output_get_qobject(mo); + } + + qmp_output_visitor_cleanup(mo); + +out: + if (local_err) { + qerror_report_err(local_err); + error_free(local_err); + return -1; + } + + return 0; +}