Patchwork [07/15] qapi: add query-version QMP command

login
register
mail settings
Submitter Anthony Liguori
Date March 11, 2011, 11:05 p.m.
Message ID <1299884745-521-8-git-send-email-aliguori@us.ibm.com>
Download mbox | patch
Permalink /patch/86477/
State New
Headers show

Comments

Anthony Liguori - March 11, 2011, 11:05 p.m.
This is used internally by QMP.  It's also a pretty good example of a typical
command conversion.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Blue Swirl - March 12, 2011, 11:19 a.m.
On Sat, Mar 12, 2011 at 1:05 AM, Anthony Liguori <aliguori@us.ibm.com> wrote:
> This is used internally by QMP.  It's also a pretty good example of a typical
> command conversion.
>
> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
>
> diff --git a/Makefile.objs b/Makefile.objs
> index 5dae800..e1a2756 100644
> --- a/Makefile.objs
> +++ b/Makefile.objs
> @@ -103,7 +103,7 @@ common-obj-y += block-migration.o
>  common-obj-y += pflib.o
>  common-obj-y += bitmap.o bitops.o
>  common-obj-y += qmp-marshal-types.o qmp-marshal-types-core.o
> -common-obj-y += qmp-core.o qmp-marshal.o
> +common-obj-y += qmp-core.o qmp-marshal.o qmp.o
>
>  common-obj-$(CONFIG_BRLAPI) += baum.o
>  common-obj-$(CONFIG_POSIX) += migration-exec.o migration-unix.o migration-fd.o
> diff --git a/qmp-schema.json b/qmp-schema.json
> index e69de29..e72bc18 100644
> --- a/qmp-schema.json
> +++ b/qmp-schema.json
> @@ -0,0 +1,90 @@
> +# *-*- Mode: Python -*-*
> +
> +##
> +# QMP Schema
> +#
> +# This file defines the types, commands, and events used by QMP.  It should
> +# fully describe the interface used by QMP.
> +#
> +# This file is designed to be loosely based on JSON although it's technical
> +# executable Python.  While dictionaries are used, they are parsed as
> +# OrderedDicts so that ordering is preserved.
> +#
> +# There are two basic syntaxes used.  The first syntax defines a type and is
> +# represented by a dictionary.  There are three kinds of types that are
> +# supported.
> +#
> +# A complex type is a dictionary containing a single key who's value is a
> +# dictionary.  This corresponds to a struct in C or an Object in JSON.  An
> +# example of a complex type is:
> +#
> +#  { 'type': 'MyType',
> +#    'data' { 'member1': 'str', 'member2': 'int', '*member3': 'str } }
> +#
> +# The use of '*' as a prefix to the name means the member is optional.  Optional
> +# members should always be added to the end of the dictionary to preserve
> +# backwards compatibility.
> +#
> +# An enumeration type is a dictionary containing a single key who's value is a
> +# list of strings.  An example enumeration is:
> +#
> +#  { 'enum': 'MyEnum', 'data': [ 'value1', 'value2', 'value3' ] }
> +#
> +# A signal is similar in form to a complex type except the single key is
> +# entirely upper case instead of CamelCase.  An example signal is:
> +#
> +#  { 'event': 'MY_SIGNAL', 'data': { 'arg1': 'str', 'arg2': 'str' } }
> +#
> +# Generally speaking, complex types and enums should always use CamelCase for
> +# the type names.
> +#
> +# Commands are defined by using a list containing three members.  The first
> +# member is the command name, the second member is a dictionary containing
> +# arguments, and the third member is the return type.
> +#
> +# An example command is:
> +#
> +#  { 'command': 'my-command',
> +#    'data': { 'arg1': 'str', '*arg2': 'str' },
> +#    'returns': 'str' ]
> +#
> +# Command names should be all lower case with words separated by a hyphen.
> +
> +### 0.14.0 commands.  Do not modify. ###
> +
> +##
> +# @VersionInfo:
> +#
> +# A description of QEMU's version.
> +#
> +# @qemu.major:  The major version of QEMU
> +#
> +# @qemu.minor:  The minor version of QEMU
> +#
> +# @qemu.micro:  The micro version of QEMU.  By current convention, a micro
> +#               version of 50 signifies a development branch.  A micro version
> +#               greater than or equal to 90 signifies a release candidate for
> +#               the next minor version.  A micro version of less than 50
> +#               signifies a stable release.
> +#
> +# @package:     QEMU will always set this field to an empty string.  Downstream
> +#               versions of QEMU should set this to a non-empty string.  The
> +#               exact format depends on the downstream however it highly
> +#               recommended that a unique name is used.
> +#
> +# Since: 0.14.0
> +##
> +{ 'type': 'VersionInfo',
> +  'data': {'qemu': {'major': 'int', 'minor': 'int', 'micro': 'int'},
> +           'package': 'str'} }
> +
> +##
> +# @query-version:
> +#
> +# Returns the current version of QEMU.
> +#
> +# Returns:  A @VersionInfo object describing the current version of QEMU.
> +#
> +# Since: 0.14.0
> +##
> +{ 'command': 'query-version', 'returns': 'VersionInfo' }
> diff --git a/qmp.c b/qmp.c
> new file mode 100644
> index 0000000..7b626f5
> --- /dev/null
> +++ b/qmp.c
> @@ -0,0 +1,31 @@
> +/*
> + * QAPI
> + *
> + * Copyright IBM, Corp. 2011
> + *
> + * Authors:
> + *  Anthony Liguori   <aliguori@us.ibm.com>
> + *
> + * This work is licensed under the terms of the GNU LGPL, version 2.  See
> + * the COPYING.LIB file in the top-level directory.
> + */
> +#include "qemu-common.h"
> +#include "qmp-core.h"
> +#include "qmp.h"
> +
> +VersionInfo *qmp_query_version(Error **err)
> +{
> +    VersionInfo *info = qmp_alloc_version_info();
> +    const char *version = QEMU_VERSION;
> +    char *tmp;
> +
> +    info->qemu.major = strtol(version, &tmp, 10);

Since all fields are int64_t, these should use strtoll(), otherwise
they may fail for versions like QEMU 2147483648.0.0. ;-)

> +    tmp++;
> +    info->qemu.minor = strtol(tmp, &tmp, 10);
> +    tmp++;
> +    info->qemu.micro = strtol(tmp, &tmp, 10);
> +    info->package = qemu_strdup(QEMU_PKGVERSION);
> +
> +    return info;
> +}
> +
> --
> 1.7.0.4
>
>
>
Anthony Liguori - March 12, 2011, 3:06 p.m.
On 03/12/2011 05:19 AM, Blue Swirl wrote:
> On Sat, Mar 12, 2011 at 1:05 AM, Anthony Liguori<aliguori@us.ibm.com>  wrote:
>> This is used internally by QMP.  It's also a pretty good example of a typical
>> command conversion.
>>
>> Signed-off-by: Anthony Liguori<aliguori@us.ibm.com>
>>
>> diff --git a/Makefile.objs b/Makefile.objs
>> index 5dae800..e1a2756 100644
>> --- a/Makefile.objs
>> +++ b/Makefile.objs
>> @@ -103,7 +103,7 @@ common-obj-y += block-migration.o
>>   common-obj-y += pflib.o
>>   common-obj-y += bitmap.o bitops.o
>>   common-obj-y += qmp-marshal-types.o qmp-marshal-types-core.o
>> -common-obj-y += qmp-core.o qmp-marshal.o
>> +common-obj-y += qmp-core.o qmp-marshal.o qmp.o
>>
>>   common-obj-$(CONFIG_BRLAPI) += baum.o
>>   common-obj-$(CONFIG_POSIX) += migration-exec.o migration-unix.o migration-fd.o
>> diff --git a/qmp-schema.json b/qmp-schema.json
>> index e69de29..e72bc18 100644
>> --- a/qmp-schema.json
>> +++ b/qmp-schema.json
>> @@ -0,0 +1,90 @@
>> +# *-*- Mode: Python -*-*
>> +
>> +##
>> +# QMP Schema
>> +#
>> +# This file defines the types, commands, and events used by QMP.  It should
>> +# fully describe the interface used by QMP.
>> +#
>> +# This file is designed to be loosely based on JSON although it's technical
>> +# executable Python.  While dictionaries are used, they are parsed as
>> +# OrderedDicts so that ordering is preserved.
>> +#
>> +# There are two basic syntaxes used.  The first syntax defines a type and is
>> +# represented by a dictionary.  There are three kinds of types that are
>> +# supported.
>> +#
>> +# A complex type is a dictionary containing a single key who's value is a
>> +# dictionary.  This corresponds to a struct in C or an Object in JSON.  An
>> +# example of a complex type is:
>> +#
>> +#  { 'type': 'MyType',
>> +#    'data' { 'member1': 'str', 'member2': 'int', '*member3': 'str } }
>> +#
>> +# The use of '*' as a prefix to the name means the member is optional.  Optional
>> +# members should always be added to the end of the dictionary to preserve
>> +# backwards compatibility.
>> +#
>> +# An enumeration type is a dictionary containing a single key who's value is a
>> +# list of strings.  An example enumeration is:
>> +#
>> +#  { 'enum': 'MyEnum', 'data': [ 'value1', 'value2', 'value3' ] }
>> +#
>> +# A signal is similar in form to a complex type except the single key is
>> +# entirely upper case instead of CamelCase.  An example signal is:
>> +#
>> +#  { 'event': 'MY_SIGNAL', 'data': { 'arg1': 'str', 'arg2': 'str' } }
>> +#
>> +# Generally speaking, complex types and enums should always use CamelCase for
>> +# the type names.
>> +#
>> +# Commands are defined by using a list containing three members.  The first
>> +# member is the command name, the second member is a dictionary containing
>> +# arguments, and the third member is the return type.
>> +#
>> +# An example command is:
>> +#
>> +#  { 'command': 'my-command',
>> +#    'data': { 'arg1': 'str', '*arg2': 'str' },
>> +#    'returns': 'str' ]
>> +#
>> +# Command names should be all lower case with words separated by a hyphen.
>> +
>> +### 0.14.0 commands.  Do not modify. ###
>> +
>> +##
>> +# @VersionInfo:
>> +#
>> +# A description of QEMU's version.
>> +#
>> +# @qemu.major:  The major version of QEMU
>> +#
>> +# @qemu.minor:  The minor version of QEMU
>> +#
>> +# @qemu.micro:  The micro version of QEMU.  By current convention, a micro
>> +#               version of 50 signifies a development branch.  A micro version
>> +#               greater than or equal to 90 signifies a release candidate for
>> +#               the next minor version.  A micro version of less than 50
>> +#               signifies a stable release.
>> +#
>> +# @package:     QEMU will always set this field to an empty string.  Downstream
>> +#               versions of QEMU should set this to a non-empty string.  The
>> +#               exact format depends on the downstream however it highly
>> +#               recommended that a unique name is used.
>> +#
>> +# Since: 0.14.0
>> +##
>> +{ 'type': 'VersionInfo',
>> +  'data': {'qemu': {'major': 'int', 'minor': 'int', 'micro': 'int'},
>> +           'package': 'str'} }
>> +
>> +##
>> +# @query-version:
>> +#
>> +# Returns the current version of QEMU.
>> +#
>> +# Returns:  A @VersionInfo object describing the current version of QEMU.
>> +#
>> +# Since: 0.14.0
>> +##
>> +{ 'command': 'query-version', 'returns': 'VersionInfo' }
>> diff --git a/qmp.c b/qmp.c
>> new file mode 100644
>> index 0000000..7b626f5
>> --- /dev/null
>> +++ b/qmp.c
>> @@ -0,0 +1,31 @@
>> +/*
>> + * QAPI
>> + *
>> + * Copyright IBM, Corp. 2011
>> + *
>> + * Authors:
>> + *  Anthony Liguori<aliguori@us.ibm.com>
>> + *
>> + * This work is licensed under the terms of the GNU LGPL, version 2.  See
>> + * the COPYING.LIB file in the top-level directory.
>> + */
>> +#include "qemu-common.h"
>> +#include "qmp-core.h"
>> +#include "qmp.h"
>> +
>> +VersionInfo *qmp_query_version(Error **err)
>> +{
>> +    VersionInfo *info = qmp_alloc_version_info();
>> +    const char *version = QEMU_VERSION;
>> +    char *tmp;
>> +
>> +    info->qemu.major = strtol(version,&tmp, 10);
> Since all fields are int64_t, these should use strtoll(), otherwise
> they may fail for versions like QEMU 2147483648.0.0. ;-)

The fields are int64_t because that's what JSON supports.  I considered 
using more precise types and doing the conversions with range checking 
as part of the marshaling.  That way, we'd still send int64_t over the 
wire, but the QEMU and libqmp interfaces could take u64, u32, s16, or 
whatever.

I think this is probably a good change to make before we get much 
further down this path because it will be much harder once we merge.

The only down side to doing this is that non-smart clients don't get the 
benefit of the type conversions.  I don't know that that's a serious 
problem though.

Regards,

Anthony Liguori

>> +    tmp++;
>> +    info->qemu.minor = strtol(tmp,&tmp, 10);
>> +    tmp++;
>> +    info->qemu.micro = strtol(tmp,&tmp, 10);
>> +    info->package = qemu_strdup(QEMU_PKGVERSION);
>> +
>> +    return info;
>> +}
>> +
>> --
>> 1.7.0.4
>>
>>
>>

Patch

diff --git a/Makefile.objs b/Makefile.objs
index 5dae800..e1a2756 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -103,7 +103,7 @@  common-obj-y += block-migration.o
 common-obj-y += pflib.o
 common-obj-y += bitmap.o bitops.o
 common-obj-y += qmp-marshal-types.o qmp-marshal-types-core.o
-common-obj-y += qmp-core.o qmp-marshal.o
+common-obj-y += qmp-core.o qmp-marshal.o qmp.o
 
 common-obj-$(CONFIG_BRLAPI) += baum.o
 common-obj-$(CONFIG_POSIX) += migration-exec.o migration-unix.o migration-fd.o
diff --git a/qmp-schema.json b/qmp-schema.json
index e69de29..e72bc18 100644
--- a/qmp-schema.json
+++ b/qmp-schema.json
@@ -0,0 +1,90 @@ 
+# *-*- Mode: Python -*-*
+
+##
+# QMP Schema
+#
+# This file defines the types, commands, and events used by QMP.  It should
+# fully describe the interface used by QMP.
+#
+# This file is designed to be loosely based on JSON although it's technical
+# executable Python.  While dictionaries are used, they are parsed as
+# OrderedDicts so that ordering is preserved.
+#
+# There are two basic syntaxes used.  The first syntax defines a type and is
+# represented by a dictionary.  There are three kinds of types that are
+# supported.
+#
+# A complex type is a dictionary containing a single key who's value is a
+# dictionary.  This corresponds to a struct in C or an Object in JSON.  An
+# example of a complex type is:
+#
+#  { 'type': 'MyType',
+#    'data' { 'member1': 'str', 'member2': 'int', '*member3': 'str } }
+#
+# The use of '*' as a prefix to the name means the member is optional.  Optional
+# members should always be added to the end of the dictionary to preserve
+# backwards compatibility.
+#
+# An enumeration type is a dictionary containing a single key who's value is a
+# list of strings.  An example enumeration is:
+#
+#  { 'enum': 'MyEnum', 'data': [ 'value1', 'value2', 'value3' ] }
+#
+# A signal is similar in form to a complex type except the single key is
+# entirely upper case instead of CamelCase.  An example signal is:
+#
+#  { 'event': 'MY_SIGNAL', 'data': { 'arg1': 'str', 'arg2': 'str' } }
+#
+# Generally speaking, complex types and enums should always use CamelCase for
+# the type names.
+#
+# Commands are defined by using a list containing three members.  The first
+# member is the command name, the second member is a dictionary containing
+# arguments, and the third member is the return type.
+#
+# An example command is:
+#
+#  { 'command': 'my-command',
+#    'data': { 'arg1': 'str', '*arg2': 'str' },
+#    'returns': 'str' ]
+#
+# Command names should be all lower case with words separated by a hyphen.
+
+### 0.14.0 commands.  Do not modify. ###
+
+##
+# @VersionInfo:
+#
+# A description of QEMU's version.
+#
+# @qemu.major:  The major version of QEMU
+#
+# @qemu.minor:  The minor version of QEMU
+#
+# @qemu.micro:  The micro version of QEMU.  By current convention, a micro
+#               version of 50 signifies a development branch.  A micro version
+#               greater than or equal to 90 signifies a release candidate for
+#               the next minor version.  A micro version of less than 50
+#               signifies a stable release.
+#
+# @package:     QEMU will always set this field to an empty string.  Downstream
+#               versions of QEMU should set this to a non-empty string.  The
+#               exact format depends on the downstream however it highly
+#               recommended that a unique name is used.
+#
+# Since: 0.14.0
+##
+{ 'type': 'VersionInfo',
+  'data': {'qemu': {'major': 'int', 'minor': 'int', 'micro': 'int'},
+           'package': 'str'} }
+
+##
+# @query-version:
+#
+# Returns the current version of QEMU.
+#
+# Returns:  A @VersionInfo object describing the current version of QEMU.
+#
+# Since: 0.14.0
+##
+{ 'command': 'query-version', 'returns': 'VersionInfo' }
diff --git a/qmp.c b/qmp.c
new file mode 100644
index 0000000..7b626f5
--- /dev/null
+++ b/qmp.c
@@ -0,0 +1,31 @@ 
+/*
+ * QAPI
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ *  Anthony Liguori   <aliguori@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.  See
+ * the COPYING.LIB file in the top-level directory.
+ */
+#include "qemu-common.h"
+#include "qmp-core.h"
+#include "qmp.h"
+
+VersionInfo *qmp_query_version(Error **err)
+{
+    VersionInfo *info = qmp_alloc_version_info();
+    const char *version = QEMU_VERSION;
+    char *tmp;
+
+    info->qemu.major = strtol(version, &tmp, 10);
+    tmp++;
+    info->qemu.minor = strtol(tmp, &tmp, 10);
+    tmp++;
+    info->qemu.micro = strtol(tmp, &tmp, 10);
+    info->package = qemu_strdup(QEMU_PKGVERSION);
+
+    return info;
+}
+