From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:45081) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UfV6d-0005Tq-PS for qemu-devel@nongnu.org; Thu, 23 May 2013 08:58:59 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UfV6b-0001Bs-Ra for qemu-devel@nongnu.org; Thu, 23 May 2013 08:58:55 -0400 Received: from mx1.redhat.com ([209.132.183.28]:33052) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UfV6b-0001Bn-Il for qemu-devel@nongnu.org; Thu, 23 May 2013 08:58:53 -0400 Message-ID: <519E128A.1070603@redhat.com> Date: Thu, 23 May 2013 06:58:50 -0600 From: Eric Blake MIME-Version: 1.0 References: <20130522134007.GA2051@t430s.nay.redhat.com> In-Reply-To: <20130522134007.GA2051@t430s.nay.redhat.com> Content-Type: multipart/signed; micalg=pgp-sha256; protocol="application/pgp-signature"; boundary="----enig2HVSQQCQENNUXNGMPCQER" Subject: Re: [Qemu-devel] RFC: Full introspection support for QMP List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Amos Kong Cc: aliguori@us.ibm.com, lcapitulino@redhat.com, qemu-devel , Ronen Hod , Markus Armbruster This is an OpenPGP/MIME signed message (RFC 4880 and 3156) ------enig2HVSQQCQENNUXNGMPCQER Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable On 05/22/2013 07:40 AM, Amos Kong wrote: > Hi all, >=20 > We already have query-command-line-options to query details of command-= line > options. As we discussed in the list, we also need full introspection o= f QMP > (command). The qmp-events also need to be dumped, we can define events = in > qai-schema.json. We can also dump QMP errors in future if it's needed. >=20 > Command name: query-qmp-schema > Return: returns the contents of qapi-schema.json in json format. >=20 > Solution to query json content from C code: > qapi-schema.json is processed by qapi python scripts to generate C > files, I found the content is good enough for Libvirt to know the > QMP command schema. We can change qapi scripts to generate a talbe/li= st > to record the raw string, then we can return the raw string in > qmp_query_qmp_schema(). >=20 > By default, return the complete schema in one go. >=20 > And support to query of unknown type in new command. > -> { "execute": "query-qmp-schema" "arguments": { "command": "query-s= tatus" }} > <- { "return" : "data": { "command': "query-status", "returns": "Stat= usInfo" }} If you are planning on returning everything in one shot, then this has to be an array-of-dict return, rather than a single dict return. If filtering is used, the result should be an array-of-one, and I definitely want to have a non-filtered mode that returns everything at on= ce. > -> { "execute": "query-qmp-schema" "arguments": { "type": "StatusInfo= " }} > <- { "return" : "data": { "type": "StatusInfo", "data": {"running": "= bool", > "singlestep": "bool", "status": "RunState"}= } > -> { "execute": "query-qmp-schema" "arguments": { "event": "RX-FILTER= -CHANGE" }} You need a schema for this command :) It looks like you are proposing something like: { 'command': 'query-qmp-schema', 'arguments': { '*command':'str', '*type':'str', '*event':'str' }, 'returns': [ 'SchemaData' ] } and 'SchemaData' needs to be spelled out as what an actual entry in qapi-schema.json must actually look like (goes back to Stefan's complaint on the 'drive-add' thread that we should avoid sending schema-less data over QAPI). Besides, having a schema in place for what all QAPI must look like may force us to be more robust in our additions to QAPI. Hmm, my schema doesn't adequately express that you are probably only allowing a single 'command', 'type', or 'event' filtering to be used at once. We've had some ideas on other threads about providing smarter magic on handling a discriminated union embedded inside a top-level dictionary, rather than nesting type/data members of a nested dictionary; figuring out how to express this may improve ease of use of other aspects of QAPI. In fact, it would be simpler to just say that filtering uses a 'name' argument, and hold ourselves to a design that command names, types, and events never have overlapping namespace, as in:= { 'command': 'query-qmp-schema', 'arguments': { '*name':'str' }, 'returns': [ 'SchemaData' ] } Another issue (or rather, more thoughts on my opaque 'SchemaData' type). QAPI expresses optional elements with markup, as in: { 'command': 'blockdev-snapshot-sync', 'data': { 'device': 'str', 'snapshot-file': 'str', '*format': 'str', '*mode': 'NewImageMode'} } But our argument has always been that if you have to post-process a QAPI argument, you were cramming too much information into a single element. Optional arguments are a case of post-processing - libvirt would have to check if an option name begins with '*' to learn whether an option is optional. If you return qapi-schema.json contents as-is, you are forcing management to post-process. Contrast that with query-command-line-options, where we INTENTIONALLY called out a rather nested layout, but where that layout allows us to give additional details. In other words, rather than replaying qemu-schema.json as-is, I think your C code should munge the text into a format more useful over QAPI. That is, I'd rather see: -> { "execute": "query-qmp-schema", "arguments": { "name": "blockdev-snapshot-sync" }} <- { "return" : "data": [ { "metatype": "command", "name": "blockdev-snapshot-sync", "data": [ { "option": "device", "type": "str" }, { "option": "snapshot-file", "type", "str" }, { "option": "format", "type", "str", "optional": true }, { "option": "mode", "type", "NewImageMode", "optional": true } ] } } and possibly with further extensions that express the default value of an optional argument. Note that this post-processing (turning a free-form dictionary from the .json file into an array of dictionaries that all match a given schema) makes the data a little easier to handle. In fact, with that layer of structuring, I can now define what the schema looks like: { 'type': 'SchemaDataMember', 'data': { 'option': 'str', 'type': 'str', '*optional': 'bool' } } { 'enum': 'SchemaMetatype', 'data': [ 'command', 'type', 'event' ] } { 'type': 'SchemaData', 'data': { 'name': 'str', 'metatype': 'SchemaMetatype', '*returns': 'str', '*data': [ 'SchemaDataMember' ] } } Well, maybe the '*returns' element still needs some thought on how we represent an array return vs. a dictionary return. But I'd definitely favor some structure into the new QMP command, where you build up that structure by actually parsing qapi-schema.json instead of using it as-is. --=20 Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org ------enig2HVSQQCQENNUXNGMPCQER Content-Type: application/pgp-signature; name="signature.asc" Content-Description: OpenPGP digital signature Content-Disposition: attachment; filename="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.13 (GNU/Linux) Comment: Public key at http://people.redhat.com/eblake/eblake.gpg Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/ iQEcBAEBCAAGBQJRnhKKAAoJEKeha0olJ0NqMyUH/j+Idy8yhaMFHm5po72HpkJy 4qHKpZyKbfJpclsW9dfQfmt0krCu2k270QpNSFf3UU7ZO5PN5byO+CVbpa9FQXIS 1JcAkhtEY/qRRHNrytiQfr78vbUVyPgNc0OxJ4Irf6IBcKlIsy3mRu92a3OLbK7+ DVt138/cvi7aPofSEx0iBh67UNtXPCsQzZrsFrpVwhsxsOPqYnNGcpB35/az7A7Q zksLcg1te8FFmOsAFzKGqZyALhx0iaPz+eIpq6C/sBouUfAF99o8HlVuyaEU55XJ hnfXIw4AsChXqyhvzDd3JYkvjdxP/C8jbcGPExODsgiHKlunHqZTim+f9kOwUlw= =Ddl+ -----END PGP SIGNATURE----- ------enig2HVSQQCQENNUXNGMPCQER--