All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 00/19] RFC: Reporting QEMU binary capabilities
@ 2010-06-07 14:42 Daniel P. Berrange
  2010-06-07 14:42 ` [Qemu-devel] [PATCH 01/19] Add support for JSON pretty printing Daniel P. Berrange
                   ` (21 more replies)
  0 siblings, 22 replies; 62+ messages in thread
From: Daniel P. Berrange @ 2010-06-07 14:42 UTC (permalink / raw)
  To: qemu-devel

As everyone here agrees, having management apps parse -help output
to determine the QEMU capabilities is not at all nice, because it
is an ill-defined & fragile data format. Looking more broadly these
same issues apply to all the other command line options that accept
a '?' flag for querying capabilities.

We have a very nice structured data format we could be using for
this: JSON. What's lacking is code to output all this information
in the JSON format. This patch series can thus be summarized as
'JSON for everything'

For reference, here is the full list of information libvirt currently
queries from QEMU:

  * Detection of command line flags (-help parsing)

    -no-kqemu, -no-kvm, -enable-kvm, -no-reboot
    -name, -uuid, -xen-domid, -domid, -drive
    -vga, -std-vga, -pcidevice, -mem-path
    -chardev, -balloon, -device, -rtc, -rtc-td-hack
    -no-hpet, -no-kvm-pit-reinjection, -tdf
    -fsdev -sdl

  * Detection of parameters (-help parsing)

     -drive format=
     -drive boot=
     -drive serial=
     -drive cache=
     -cpu cores=, threads=, sockets=
     -netdev vhost=

  * Detection of parameter values (-help parsing)

     -drive cache=writethrough|writeback|none
       vs
     -drive cache=default|on|off

  * Version number  (-help parsing)

    -netdev  + 0.13.0

    0.9.0  for VNC syntax

    0.10.0 for vnet hdr

  * Parse -M ?  output to get list of machine types + aliases

  * Parse -device pci-assign,? to check for 'configfd' parameter

  * Parse -cpu ?  to get list of named CPU types

  * Parse binary name (qemu-system-XXXX) to guess arch of target


This isn't an 100% exhaustive list of things that we would like
to be able to get access to though. It can likely cover all of
the following:

 * Version

      QEMU major, minor, micro numbers. KVM version. Package
      version

 * Devices

      List of device names. Parameter names. Parameter value
      data types. Allowed strings for enums

 * Arguments

      List of command line arguments. Parameter names. Parameter
      value data types. Allowed strings for enums

 * Machine types

      List of names + aliases
      List of default devices in machine

 * CPU types

      List of names, associated feature flags, all allowed
      feature flags

 * Target info

      Arch name, wordsize

 * Monitor commands

      List of all monitor commands. Parameter names. Parameter
      value data types. Allowed strings for enums

 * Block device backends

      List of all block device backends. Parameter names.
      Parameter value data types. Allowed strings for enums

 * Netdev device backends

      List of all netdev device backends. Parameter names.
      Parameter value data types. Allowed strings for enums

 * Chardev device backends

      List of all chardev device backends. Parameter names.
      Parameter value data types. Allowed strings for enums


This patch series attempts to satisfy as much of this as is
feasible with the current QEMU codebase structure. The series
comprises four stages

 * Some basic infrastructure. Support for JSON pretty printing.
   Introduction of standardized helpers for converting enums
   to/from strings. Introduction of an 'enum' data type for
   QemuOpt to expose a formal list of valid values & simplify
   config handling / parsing. Compile time assertion checking

 * Convert driver, netdev & rtc config options to use the new
   enum data type for all appropriate args

 * Add new QMP monitor commands exposing data for machine
   types, devices, cpu types, arch target, argv, config params,
   and netdev backends.

 * Add a new '-capabilities' command line arg as syntactic
   sugar for the monitor commands that just report on static
   info about the QEMU binary.

The main problem encountered with this patch series is the
split between argv and config parameters. The qemu-config.c
file provides the information is a good data format, allowing
programatic access to the list of parameters for each config
option (eg, the 'cache', 'file', 'aio', etc bits for -drive).
There are some issues with it though

 - It lacks a huge amount of coverage wrt to the full argv
   available, even simple things like the '-m' argument
   don't exist.

 - It is inconsistent in handling parameters. eg it  hands
   off validation of netdev backends to other code, to allow
   for handling of different parameters for tap vs user vs
   socket backends.  For chardev backends though, it directly
   includes a union of all possible parameters.

Ideally the 'query-argv' command would not be required, but
unless those problems with the qemu-config are resolved, it
is the only way to access alot of the information. This is
sub-optimal because although it lets apps easily determine
whether an arg like '-smp' is present, it still leaves them
parsing that args' help string to discover parameters.

This series is lacking a 'query-blockdev' and 'query-chardev'
commands to report on availability of backends for -blockdev
and '-chardev' commands.

Finally the existing 'query-commands' output is lacking any
information about the parameters associated with each command.
This needs to be addressed somehow.

In summary though, IMHO, this patch series provides a good
base for providing information about static QEMU binary
capabilities to applications. It should ensure apps never
again need to go anywhere near -help, -M ?, -cpu ?, -device ?,
-soundhw ? and other such ill defined output formats.

NB, I know this patch series will probably clash horribly
with other patch series recently posted for review, in
particular Jes' cleanup of vl.c   I will rebase as required
if any of those get merged.

This series is currently based on GIT master as of:

  commit fd1dc858370d9a9ac7ea2512812c3a152ee6484b
  Author: Edgar E. Iglesias <edgar.iglesias@gmail.com>
  Date:   Mon Jun 7 11:54:27 2010 +0200

Regards,
Daniel

 Makefile.objs                |    2 
 block.c                      |   32 +-
 block.h                      |   55 ++++
 cpus.c                       |   78 ++++++
 cpus.h                       |    1 
 hw/boards.h                  |    2 
 hw/mc146818rtc.c             |    8 
 hw/qdev.c                    |  148 +++++++++++++
 hw/qdev.h                    |    2 
 monitor.c                    |  167 ++++++++++++++
 monitor.h                    |    5 
 net.c                        |  173 ++++++++++-----
 net.h                        |    2 
 qemu-config.c                |  228 +++++++++++++++++++-
 qemu-config.h                |    2 
 qemu-enum.c                  |   44 +++
 qemu-enum.h                  |   45 ++++
 qemu-option.c                |   35 +++
 qemu-option.h                |   14 +
 qemu-options.hx              |    9 
 qjson.c                      |   55 ++++
 qjson.h                      |    1 
 sysemu.h                     |   43 +++
 target-arm/cpu.h             |    7 
 target-arm/helper.c          |   21 +
 target-cris/cpu.h            |    7 
 target-cris/translate.c      |   22 +
 target-i386/cpu.h            |    7 
 target-i386/cpuid.c          |   79 +++++++
 target-m68k/cpu.h            |    9 
 target-m68k/helper.c         |   23 ++
 target-mips/cpu.h            |    7 
 target-mips/translate.c      |    4 
 target-mips/translate_init.c |   19 +
 target-ppc/cpu.h             |    7 
 target-ppc/translate.c       |    4 
 target-ppc/translate_init.c  |   17 +
 target-sh4/cpu.h             |    8 
 target-sh4/translate.c       |   23 ++
 target-sparc/cpu.h           |    9 
 target-sparc/helper.c        |   60 +++++
 verify.h                     |  164 ++++++++++++++
 vl.c                         |  482 +++++++++++++++++++++++++++++--------------
 43 files changed, 1869 insertions(+), 261 deletions(-)

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [Qemu-devel] [PATCH 01/19] Add support for JSON pretty printing
  2010-06-07 14:42 [Qemu-devel] [PATCH 00/19] RFC: Reporting QEMU binary capabilities Daniel P. Berrange
@ 2010-06-07 14:42 ` Daniel P. Berrange
  2010-06-09 19:51   ` Luiz Capitulino
  2010-06-07 14:42 ` [Qemu-devel] [PATCH 02/19] Add support for compile time assertions Daniel P. Berrange
                   ` (20 subsequent siblings)
  21 siblings, 1 reply; 62+ messages in thread
From: Daniel P. Berrange @ 2010-06-07 14:42 UTC (permalink / raw)
  To: qemu-devel

The monitor does not pretty-print JSON output, so that everything
will be on a single line reply. When JSON docs get large this is
quite unpleasant to read. For the future command line capabilities
query ability, huge JSON docs will be available. This needs the
ability to pretty-print.

This introduces a new API qobject_to_json_pretty() that does
a minimal indentation of list and dict members. As an example,
this makes

  {"QMP": {"version": {"micro": 50, "minor": 12, "package": "", "major": 0}, "capabilities": []}}

Output as

  {
      "QMP": {
          "version": {
              "micro": 50,
              "minor": 12,
              "package": "",
              "major": 0
          },
          "capabilities": [
          ]
      }
  }

NB: this is not turned on for the QMP monitor.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
---
 qjson.c |   55 +++++++++++++++++++++++++++++++++++++++++++++++--------
 qjson.h |    1 +
 2 files changed, 48 insertions(+), 8 deletions(-)

diff --git a/qjson.c b/qjson.c
index 483c667..f402103 100644
--- a/qjson.c
+++ b/qjson.c
@@ -72,43 +72,57 @@ QObject *qobject_from_jsonf(const char *string, ...)
 
 typedef struct ToJsonIterState
 {
+    int indent;
+    int pretty;
     int count;
     QString *str;
 } ToJsonIterState;
 
-static void to_json(const QObject *obj, QString *str);
+static void to_json(const QObject *obj, QString *str, int pretty, int indent);
 
 static void to_json_dict_iter(const char *key, QObject *obj, void *opaque)
 {
     ToJsonIterState *s = opaque;
     QString *qkey;
+    int j;
 
-    if (s->count) {
+    if (s->count)
         qstring_append(s->str, ", ");
+
+    if (s->pretty) {
+        qstring_append(s->str, "\n");
+        for (j = 0 ; j < s->indent ; j++)
+            qstring_append(s->str, "    ");
     }
 
     qkey = qstring_from_str(key);
-    to_json(QOBJECT(qkey), s->str);
+    to_json(QOBJECT(qkey), s->str, s->pretty, s->indent);
     QDECREF(qkey);
 
     qstring_append(s->str, ": ");
-    to_json(obj, s->str);
+    to_json(obj, s->str, s->pretty, s->indent);
     s->count++;
 }
 
 static void to_json_list_iter(QObject *obj, void *opaque)
 {
     ToJsonIterState *s = opaque;
+    int j;
 
-    if (s->count) {
+    if (s->count)
         qstring_append(s->str, ", ");
+
+    if (s->pretty) {
+        qstring_append(s->str, "\n");
+        for (j = 0 ; j < s->indent ; j++)
+            qstring_append(s->str, "    ");
     }
 
-    to_json(obj, s->str);
+    to_json(obj, s->str, s->pretty, s->indent);
     s->count++;
 }
 
-static void to_json(const QObject *obj, QString *str)
+static void to_json(const QObject *obj, QString *str, int pretty, int indent)
 {
     switch (qobject_type(obj)) {
     case QTYPE_QINT: {
@@ -190,8 +204,16 @@ static void to_json(const QObject *obj, QString *str)
 
         s.count = 0;
         s.str = str;
+        s.indent = indent + 1;
+        s.pretty = pretty;
         qstring_append(str, "{");
         qdict_iter(val, to_json_dict_iter, &s);
+        if (pretty) {
+            int j;
+            qstring_append(str, "\n");
+            for (j = 0 ; j < indent ; j++)
+                qstring_append(str, "    ");
+        }
         qstring_append(str, "}");
         break;
     }
@@ -201,8 +223,16 @@ static void to_json(const QObject *obj, QString *str)
 
         s.count = 0;
         s.str = str;
+        s.indent = indent + 1;
+        s.pretty = pretty;
         qstring_append(str, "[");
         qlist_iter(val, (void *)to_json_list_iter, &s);
+        if (pretty) {
+            int j;
+            qstring_append(str, "\n");
+            for (j = 0 ; j < indent ; j++)
+                qstring_append(str, "    ");
+        }
         qstring_append(str, "]");
         break;
     }
@@ -246,7 +276,16 @@ QString *qobject_to_json(const QObject *obj)
 {
     QString *str = qstring_new();
 
-    to_json(obj, str);
+    to_json(obj, str, 0, 0);
+
+    return str;
+}
+
+QString *qobject_to_json_pretty(const QObject *obj)
+{
+    QString *str = qstring_new();
+
+    to_json(obj, str, 1, 0);
 
     return str;
 }
diff --git a/qjson.h b/qjson.h
index 7afec2e..cd60e0b 100644
--- a/qjson.h
+++ b/qjson.h
@@ -24,5 +24,6 @@ QObject *qobject_from_jsonf(const char *string, ...)
 QObject *qobject_from_jsonv(const char *string, va_list *ap);
 
 QString *qobject_to_json(const QObject *obj);
+QString *qobject_to_json_pretty(const QObject *obj);
 
 #endif /* QJSON_H */
-- 
1.6.6.1

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [Qemu-devel] [PATCH 02/19] Add support for compile time assertions
  2010-06-07 14:42 [Qemu-devel] [PATCH 00/19] RFC: Reporting QEMU binary capabilities Daniel P. Berrange
  2010-06-07 14:42 ` [Qemu-devel] [PATCH 01/19] Add support for JSON pretty printing Daniel P. Berrange
@ 2010-06-07 14:42 ` Daniel P. Berrange
  2010-06-07 15:35   ` [Qemu-devel] " Paolo Bonzini
  2010-06-07 14:42 ` [Qemu-devel] [PATCH 03/19] Add enum handlers for easy & efficient string <-> int conversion Daniel P. Berrange
                   ` (19 subsequent siblings)
  21 siblings, 1 reply; 62+ messages in thread
From: Daniel P. Berrange @ 2010-06-07 14:42 UTC (permalink / raw)
  To: qemu-devel

The verify.h header, taken from GNULIB, provides macros for
doing compile time assertions.

There are two main variants

For use in global namespace (eg header files, or global decls)

  verify(CONDITION)

For use in code blocks

  verify_true(CONDITION)

Example usage, consider if there was an enumeration of
netdev client types, with a last element MAX_NET_CLIENTS.
Consider then wanting to declare a static array with info
about each netdev client type.

This can do a compile time assertion that every type in
the enumeration is represented in the array.

  verify(ARRAY_SIZE(net_client_types) == MAX_NET_CLIENTS)

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
---
 verify.h |  164 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 164 insertions(+), 0 deletions(-)
 create mode 100644 verify.h

diff --git a/verify.h b/verify.h
new file mode 100644
index 0000000..c18a746
--- /dev/null
+++ b/verify.h
@@ -0,0 +1,164 @@
+/* -*- buffer-read-only: t -*- vi: set ro: */
+/* Compile-time assert-like macros.
+
+   Copyright (C) 2005-2006, 2009-2010 Free Software Foundation, Inc.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU Lesser General Public License as published by
+   the Free Software Foundation; either version 2.1 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/* Written by Paul Eggert, Bruno Haible, and Jim Meyering.  */
+
+#ifndef VERIFY_H
+# define VERIFY_H 1
+
+/* Each of these macros verifies that its argument R is nonzero.  To
+   be portable, R should be an integer constant expression.  Unlike
+   assert (R), there is no run-time overhead.
+
+   There are two macros, since no single macro can be used in all
+   contexts in C.  verify_true (R) is for scalar contexts, including
+   integer constant expression contexts.  verify (R) is for declaration
+   contexts, e.g., the top level.
+
+   Symbols ending in "__" are private to this header.
+
+   The code below uses several ideas.
+
+   * The first step is ((R) ? 1 : -1).  Given an expression R, of
+     integral or boolean or floating-point type, this yields an
+     expression of integral type, whose value is later verified to be
+     constant and nonnegative.
+
+   * Next this expression W is wrapped in a type
+     struct verify_type__ { unsigned int verify_error_if_negative_size__: W; }.
+     If W is negative, this yields a compile-time error.  No compiler can
+     deal with a bit-field of negative size.
+
+     One might think that an array size check would have the same
+     effect, that is, that the type struct { unsigned int dummy[W]; }
+     would work as well.  However, inside a function, some compilers
+     (such as C++ compilers and GNU C) allow local parameters and
+     variables inside array size expressions.  With these compilers,
+     an array size check would not properly diagnose this misuse of
+     the verify macro:
+
+       void function (int n) { verify (n < 0); }
+
+   * For the verify macro, the struct verify_type__ will need to
+     somehow be embedded into a declaration.  To be portable, this
+     declaration must declare an object, a constant, a function, or a
+     typedef name.  If the declared entity uses the type directly,
+     such as in
+
+       struct dummy {...};
+       typedef struct {...} dummy;
+       extern struct {...} *dummy;
+       extern void dummy (struct {...} *);
+       extern struct {...} *dummy (void);
+
+     two uses of the verify macro would yield colliding declarations
+     if the entity names are not disambiguated.  A workaround is to
+     attach the current line number to the entity name:
+
+       #define _GL_CONCAT0(x, y) x##y
+       #define _GL_CONCAT(x, y) _GL_CONCAT0 (x, y)
+       extern struct {...} * _GL_CONCAT (dummy, __LINE__);
+
+     But this has the problem that two invocations of verify from
+     within the same macro would collide, since the __LINE__ value
+     would be the same for both invocations.  (The GCC __COUNTER__
+     macro solves this problem, but is not portable.)
+
+     A solution is to use the sizeof operator.  It yields a number,
+     getting rid of the identity of the type.  Declarations like
+
+       extern int dummy [sizeof (struct {...})];
+       extern void dummy (int [sizeof (struct {...})]);
+       extern int (*dummy (void)) [sizeof (struct {...})];
+
+     can be repeated.
+
+   * Should the implementation use a named struct or an unnamed struct?
+     Which of the following alternatives can be used?
+
+       extern int dummy [sizeof (struct {...})];
+       extern int dummy [sizeof (struct verify_type__ {...})];
+       extern void dummy (int [sizeof (struct {...})]);
+       extern void dummy (int [sizeof (struct verify_type__ {...})]);
+       extern int (*dummy (void)) [sizeof (struct {...})];
+       extern int (*dummy (void)) [sizeof (struct verify_type__ {...})];
+
+     In the second and sixth case, the struct type is exported to the
+     outer scope; two such declarations therefore collide.  GCC warns
+     about the first, third, and fourth cases.  So the only remaining
+     possibility is the fifth case:
+
+       extern int (*dummy (void)) [sizeof (struct {...})];
+
+   * GCC warns about duplicate declarations of the dummy function if
+     -Wredundant_decls is used.  GCC 4.3 and later have a builtin
+     __COUNTER__ macro that can let us generate unique identifiers for
+     each dummy function, to suppress this warning.
+
+   * This implementation exploits the fact that GCC does not warn about
+     the last declaration mentioned above.  If a future version of GCC
+     introduces a warning for this, the problem could be worked around
+     by using code specialized to GCC, just as __COUNTER__ is already
+     being used if available.
+
+       #if 4 <= __GNUC__
+       # define verify(R) [another version to keep GCC happy]
+       #endif
+
+   * In C++, any struct definition inside sizeof is invalid.
+     Use a template type to work around the problem.  */
+
+/* Concatenate two preprocessor tokens.  */
+# define _GL_CONCAT(x, y) _GL_CONCAT0 (x, y)
+# define _GL_CONCAT0(x, y) x##y
+
+/* _GL_COUNTER is an integer, preferably one that changes each time we
+   use it.  Use __COUNTER__ if it works, falling back on __LINE__
+   otherwise.  __LINE__ isn't perfect, but it's better than a
+   constant.  */
+# if defined __COUNTER__ && __COUNTER__ != __COUNTER__
+#  define _GL_COUNTER __COUNTER__
+# else
+#  define _GL_COUNTER __LINE__
+# endif
+
+/* Generate a symbol with the given prefix, making it unique if
+   possible.  */
+# define _GL_GENSYM(prefix) _GL_CONCAT (prefix, _GL_COUNTER)
+
+/* Verify requirement R at compile-time, as an integer constant expression.
+   Return 1.  */
+
+# ifdef __cplusplus
+template <int w>
+  struct verify_type__ { unsigned int verify_error_if_negative_size__: w; };
+#  define verify_true(R) \
+     (!!sizeof (verify_type__<(R) ? 1 : -1>))
+# else
+#  define verify_true(R) \
+     (!!sizeof \
+      (struct { unsigned int verify_error_if_negative_size__: (R) ? 1 : -1; }))
+# endif
+
+/* Verify requirement R at compile-time, as a declaration without a
+   trailing ';'.  */
+
+# define verify(R) \
+    extern int (* _GL_GENSYM (verify_function) (void)) [verify_true (R)]
+
+#endif
-- 
1.6.6.1

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [Qemu-devel] [PATCH 03/19] Add enum handlers for easy & efficient string <-> int conversion
  2010-06-07 14:42 [Qemu-devel] [PATCH 00/19] RFC: Reporting QEMU binary capabilities Daniel P. Berrange
  2010-06-07 14:42 ` [Qemu-devel] [PATCH 01/19] Add support for JSON pretty printing Daniel P. Berrange
  2010-06-07 14:42 ` [Qemu-devel] [PATCH 02/19] Add support for compile time assertions Daniel P. Berrange
@ 2010-06-07 14:42 ` Daniel P. Berrange
  2010-06-09 19:52   ` Luiz Capitulino
  2010-06-26  6:52   ` Markus Armbruster
  2010-06-07 14:42 ` [Qemu-devel] [PATCH 04/19] Add support for a option parameter as an enum Daniel P. Berrange
                   ` (18 subsequent siblings)
  21 siblings, 2 replies; 62+ messages in thread
From: Daniel P. Berrange @ 2010-06-07 14:42 UTC (permalink / raw)
  To: qemu-devel

There is quite alot of code using an enumeration of possible
values, which also needs todo conversions to/from a string
representation of enum values. These string <-> int conversions
have been repeated in an adhoc manner throughout the code.

This makes it hard to report on the list of valid strings,
eg in help output, or todo proper validation in the qemu
config/option parsing routines.

This addresses the first problem by introducing a standard
set of routines for performing string <-> int conversions
for enums. There are two restrictions on using these helpers,
the first enum value must be 0, and there must be a sentinal
in the enum to provide the max value.

For each enumeration, three functions will be made available

 - string to int convertor:

   int XXXX_from_string(const char *value);

   Returns -1 if the value was not an allowed string for the
   enumeration. Returns >= 0 for a valid value

 - int to string convertor

   const char * XXXX_to_string(int value);

   Returns NULL if the value was not a member of the
   enumeration. Returns a non-NULL sstring for valid value

 - string list generator

   char * XXXX_to_string_list(void);

   Returns a malloc'd string containing all valid values,
   separated by commas. Caller must free the string.

The general usage pattern is as follows.

In the header file (eg qemu-option.h):

  enum QemuOptType {
    QEMU_OPT_STRING = 0,  /* no parsing (use string as-is)                        */
    QEMU_OPT_BOOL,        /* on/off                                               */
    QEMU_OPT_NUMBER,      /* simple number                                        */
    QEMU_OPT_SIZE,        /* size, accepts (K)ilo, (M)ega, (G)iga, (T)era postfix */

    QEMU_OPT_LAST
  };
  QEMU_ENUM_DECL(qemu_opt_type);

This declares the function prototypes for the 3 methods
outlined above.

In the corresponding source file (eg qemu-option.c):

  QEMU_ENUM_IMPL(qemu_opt_type,
                 QEMU_OPT_LAST,
                 "string", "bool", "number", "size");

This provides the implementation of the 3 methods. If there
are greater/fewer strings provided than the number of values
in the  enumeration, this generates a compile time assertion
failure that looks like

  qemu-option.c:35: error: negative width in bit-field ‘verify_error_if_negative_size__’

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
---
 Makefile.objs |    2 +-
 qemu-enum.c   |   44 ++++++++++++++++++++++++++++++++++++++++++++
 qemu-enum.h   |   45 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 90 insertions(+), 1 deletions(-)
 create mode 100644 qemu-enum.c
 create mode 100644 qemu-enum.h

diff --git a/Makefile.objs b/Makefile.objs
index 9796dcb..0ba9966 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -8,7 +8,7 @@ qobject-obj-y += qerror.o
 # block-obj-y is code used by both qemu system emulation and qemu-img
 
 block-obj-y = cutils.o cache-utils.o qemu-malloc.o qemu-option.o module.o
-block-obj-y += nbd.o block.o aio.o aes.o osdep.o qemu-config.o
+block-obj-y += nbd.o block.o aio.o aes.o osdep.o qemu-config.o qemu-enum.o
 block-obj-$(CONFIG_POSIX) += posix-aio-compat.o
 block-obj-$(CONFIG_LINUX_AIO) += linux-aio.o
 
diff --git a/qemu-enum.c b/qemu-enum.c
new file mode 100644
index 0000000..9bb33ac
--- /dev/null
+++ b/qemu-enum.c
@@ -0,0 +1,44 @@
+#include "qemu-enum.h"
+
+int qemu_enum_from_string(const char *const*types,
+			  unsigned int ntypes,
+			  const char *type)
+{
+    unsigned int i;
+    if (!type)
+        return -1;
+
+    for (i = 0 ; i < ntypes ; i++)
+        if (strcmp(types[i], type) == 0)
+            return i;
+
+    return -1;
+}
+
+const char *qemu_enum_to_string(const char *const*types,
+				unsigned int ntypes,
+				int type)
+{
+    if (type < 0 || type >= ntypes)
+        return NULL;
+
+    return types[type];
+}
+
+char *qemu_enum_to_string_list(const char *const*types,
+			       unsigned int ntypes)
+{
+    size_t len = 0;
+    char *ret;
+    int i;
+    for (i = 0 ; i < ntypes ; i++)
+	len += strlen(types[i]) + 2;
+    ret = qemu_malloc(len);
+    *ret = '\0';
+    for (i = 0 ; i < ntypes ; i++) {
+	if (i > 0)
+	    strcat(ret, ", ");
+	strcat(ret, types[i]);
+    }
+    return ret;
+}
diff --git a/qemu-enum.h b/qemu-enum.h
new file mode 100644
index 0000000..ff47798
--- /dev/null
+++ b/qemu-enum.h
@@ -0,0 +1,45 @@
+#ifndef QEMU_ENUM_H
+#define QEMU_ENUM_H
+
+#include "qemu-common.h"
+#include "verify.h"
+
+
+int qemu_enum_from_string(const char *const*types,
+			  unsigned int ntypes,
+			  const char *type);
+
+const char *qemu_enum_to_string(const char *const*types,
+				unsigned int ntypes,
+				int type);
+
+char *qemu_enum_to_string_list(const char *const*types,
+			       unsigned int ntypes);
+
+#define QEMU_ENUM_IMPL(name, lastVal, ...)				\
+    static const char *const name ## _string_list[] = { __VA_ARGS__ };	\
+    char *name ## _to_string_list(void) {				\
+        return qemu_enum_to_string_list(name ## _string_list,		\
+					ARRAY_SIZE(name ## _string_list)); \
+    }                                                                   \
+    const char *name ## _to_string(int type) {				\
+        return qemu_enum_to_string(name ## _string_list,		\
+				   ARRAY_SIZE(name ## _string_list),	\
+				   type);				\
+    }                                                                   \
+    int name ## _from_string(const char *type) {			\
+        return qemu_enum_from_string(name ## _string_list,		\
+				     ARRAY_SIZE(name ## _string_list),	\
+				     type);				\
+    }									\
+    extern int (* name ## Verify (void))				\
+        [verify_true (ARRAY_SIZE(name ## _string_list) == lastVal)]
+
+# define QEMU_ENUM_DECL(name)				\
+    const char *name ## _to_string(int type);		\
+    char *name ## _to_string_list(void);		\
+    int name ## _from_string(const char*type)
+
+
+
+#endif /* QEMU_ENUM_H */
-- 
1.6.6.1

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [Qemu-devel] [PATCH 04/19] Add support for a option parameter as an enum
  2010-06-07 14:42 [Qemu-devel] [PATCH 00/19] RFC: Reporting QEMU binary capabilities Daniel P. Berrange
                   ` (2 preceding siblings ...)
  2010-06-07 14:42 ` [Qemu-devel] [PATCH 03/19] Add enum handlers for easy & efficient string <-> int conversion Daniel P. Berrange
@ 2010-06-07 14:42 ` Daniel P. Berrange
  2010-06-26  6:59   ` Markus Armbruster
  2010-06-07 14:42 ` [Qemu-devel] [PATCH 05/19] Ensure that QEMU exits if drive_add parsing fails Daniel P. Berrange
                   ` (17 subsequent siblings)
  21 siblings, 1 reply; 62+ messages in thread
From: Daniel P. Berrange @ 2010-06-07 14:42 UTC (permalink / raw)
  To: qemu-devel

This adds a new option parameter QEMU_OPT_ENUM. The user
provides the value in its string representation. The parser
validates this and converts it to integer representation
for internal use. If the user supplies an invalid value
it will report the precise allowed list of values.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
---
 qemu-option.c |   31 +++++++++++++++++++++++++++++++
 qemu-option.h |   10 ++++++++++
 2 files changed, 41 insertions(+), 0 deletions(-)

diff --git a/qemu-option.c b/qemu-option.c
index acd74f9..bb9cc43 100644
--- a/qemu-option.c
+++ b/qemu-option.c
@@ -238,6 +238,24 @@ static int parse_option_size(const char *name, const char *value, uint64_t *ret)
     return 0;
 }
 
+static int parse_option_enum(const char *name, const char *value, int *ret, const QemuOptDesc *desc)
+{
+    if (!value) {
+        qerror_report(QERR_INVALID_PARAMETER_VALUE, name, "a enumerated string");
+        return -1;
+    }
+
+    *ret = (desc->validate.optEnum.from_string)(value);
+    if (*ret < 0) {
+        char *valid = (desc->validate.optEnum.to_string_list)();
+        qerror_report(QERR_INVALID_PARAMETER_VALUE, name, valid);
+        qemu_free(valid);
+        return -1;
+    }
+    return 0;
+}
+
+
 /*
  * Sets the value of a parameter in a given option list. The parsing of the
  * value depends on the type of option:
@@ -516,6 +534,7 @@ struct QemuOpt {
     union {
         int      boolean;
         uint64_t uint;
+        int      enumVal;
     } value;
 
     QemuOpts     *opts;
@@ -578,6 +597,16 @@ uint64_t qemu_opt_get_size(QemuOpts *opts, const char *name, uint64_t defval)
     return opt->value.uint;
 }
 
+int qemu_opt_get_enum(QemuOpts *opts, const char *name, int defval)
+{
+    QemuOpt *opt = qemu_opt_find(opts, name);
+
+    if (opt == NULL)
+        return defval;
+    assert(opt->desc && opt->desc->type == QEMU_OPT_ENUM);
+    return opt->value.enumVal;
+}
+
 static int qemu_opt_parse(QemuOpt *opt)
 {
     if (opt->desc == NULL)
@@ -592,6 +621,8 @@ static int qemu_opt_parse(QemuOpt *opt)
         return parse_option_number(opt->name, opt->str, &opt->value.uint);
     case QEMU_OPT_SIZE:
         return parse_option_size(opt->name, opt->str, &opt->value.uint);
+    case QEMU_OPT_ENUM:
+        return parse_option_enum(opt->name, opt->str, &opt->value.enumVal, opt->desc);
     default:
         abort();
     }
diff --git a/qemu-option.h b/qemu-option.h
index 4823219..3540a9b 100644
--- a/qemu-option.h
+++ b/qemu-option.h
@@ -89,12 +89,21 @@ enum QemuOptType {
     QEMU_OPT_BOOL,        /* on/off                                               */
     QEMU_OPT_NUMBER,      /* simple number                                        */
     QEMU_OPT_SIZE,        /* size, accepts (K)ilo, (M)ega, (G)iga, (T)era postfix */
+    QEMU_OPT_ENUM,        /* int, from user string validated against an enum      */
 };
 
 typedef struct QemuOptDesc {
     const char *name;
     enum QemuOptType type;
     const char *help;
+    union {
+        struct {
+            int (*from_string)(const char *);
+            const char *(*to_string)(int);
+            char *(*to_string_list)(void);
+            int last;
+        } optEnum;
+    } validate;
 } QemuOptDesc;
 
 struct QemuOptsList {
@@ -108,6 +117,7 @@ const char *qemu_opt_get(QemuOpts *opts, const char *name);
 int qemu_opt_get_bool(QemuOpts *opts, const char *name, int defval);
 uint64_t qemu_opt_get_number(QemuOpts *opts, const char *name, uint64_t defval);
 uint64_t qemu_opt_get_size(QemuOpts *opts, const char *name, uint64_t defval);
+int qemu_opt_get_enum(QemuOpts *opts, const char *name, int defval);
 int qemu_opt_set(QemuOpts *opts, const char *name, const char *value);
 typedef int (*qemu_opt_loopfunc)(const char *name, const char *value, void *opaque);
 int qemu_opt_foreach(QemuOpts *opts, qemu_opt_loopfunc func, void *opaque,
-- 
1.6.6.1

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [Qemu-devel] [PATCH 05/19] Ensure that QEMU exits if drive_add parsing fails
  2010-06-07 14:42 [Qemu-devel] [PATCH 00/19] RFC: Reporting QEMU binary capabilities Daniel P. Berrange
                   ` (3 preceding siblings ...)
  2010-06-07 14:42 ` [Qemu-devel] [PATCH 04/19] Add support for a option parameter as an enum Daniel P. Berrange
@ 2010-06-07 14:42 ` Daniel P. Berrange
  2010-06-26  7:04   ` Markus Armbruster
  2010-06-07 14:42 ` [Qemu-devel] [PATCH 06/19] Convert drive options to use enumeration data type Daniel P. Berrange
                   ` (16 subsequent siblings)
  21 siblings, 1 reply; 62+ messages in thread
From: Daniel P. Berrange @ 2010-06-07 14:42 UTC (permalink / raw)
  To: qemu-devel

The drive_add() method returns NULL if it failed to parse the
parameter values for any reason. All callers must check this
and exit if failure occurred. Annotate the method so that the
compiler validates this.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
---
 vl.c |   38 ++++++++++++++++++++++++++------------
 1 files changed, 26 insertions(+), 12 deletions(-)

diff --git a/vl.c b/vl.c
index 7121cd0..3d08a44 100644
--- a/vl.c
+++ b/vl.c
@@ -654,6 +654,7 @@ static int bt_parse(const char *opt)
 #define MTD_ALIAS "if=mtd"
 #define SD_ALIAS "index=0,if=sd"
 
+QEMU_WARN_UNUSED_RESULT
 QemuOpts *drive_add(const char *file, const char *fmt, ...)
 {
     va_list ap;
@@ -2682,7 +2683,8 @@ int main(int argc, char **argv, char **envp)
         if (optind >= argc)
             break;
         if (argv[optind][0] != '-') {
-	    hda_opts = drive_add(argv[optind++], HD_ALIAS, 0);
+	    if (!(hda_opts = drive_add(argv[optind++], HD_ALIAS, 0)))
+		exit(1);
         } else {
             const QEMUOption *popt;
 
@@ -2731,14 +2733,18 @@ int main(int argc, char **argv, char **envp)
                                  ",trans=lba" :
                              translation == BIOS_ATA_TRANSLATION_NONE ?
                                  ",trans=none" : "");
-                 break;
+		if (!hda_opts)
+		    exit(1);
+		break;
             case QEMU_OPTION_hdb:
             case QEMU_OPTION_hdc:
             case QEMU_OPTION_hdd:
-                drive_add(optarg, HD_ALIAS, popt->index - QEMU_OPTION_hda);
+                if (!drive_add(optarg, HD_ALIAS, popt->index - QEMU_OPTION_hda))
+		    exit(1);
                 break;
             case QEMU_OPTION_drive:
-                drive_add(NULL, "%s", optarg);
+                if (!drive_add(NULL, "%s", optarg))
+		    exit(1);
 	        break;
             case QEMU_OPTION_set:
                 if (qemu_set_option(optarg) != 0)
@@ -2749,13 +2755,16 @@ int main(int argc, char **argv, char **envp)
                     exit(1);
 	        break;
             case QEMU_OPTION_mtdblock:
-                drive_add(optarg, MTD_ALIAS);
+                if (!drive_add(optarg, MTD_ALIAS))
+		    exit(1);
                 break;
             case QEMU_OPTION_sd:
-                drive_add(optarg, SD_ALIAS);
+                if (!drive_add(optarg, SD_ALIAS))
+		    exit(1);
                 break;
             case QEMU_OPTION_pflash:
-                drive_add(optarg, PFLASH_ALIAS);
+                if (!drive_add(optarg, PFLASH_ALIAS))
+		    exit(1);
                 break;
             case QEMU_OPTION_snapshot:
                 snapshot = 1;
@@ -2834,7 +2843,8 @@ int main(int argc, char **argv, char **envp)
                 kernel_cmdline = optarg;
                 break;
             case QEMU_OPTION_cdrom:
-                drive_add(optarg, CDROM_ALIAS);
+                if (!drive_add(optarg, CDROM_ALIAS))
+		    exit(1);
                 break;
             case QEMU_OPTION_boot:
                 {
@@ -2887,7 +2897,8 @@ int main(int argc, char **argv, char **envp)
                 break;
             case QEMU_OPTION_fda:
             case QEMU_OPTION_fdb:
-                drive_add(optarg, FD_ALIAS, popt->index - QEMU_OPTION_fda);
+                if (!drive_add(optarg, FD_ALIAS, popt->index - QEMU_OPTION_fda))
+		    exit(1);
                 break;
             case QEMU_OPTION_no_fd_bootchk:
                 fd_bootchk = 0;
@@ -3625,17 +3636,20 @@ int main(int argc, char **argv, char **envp)
 
     if (default_cdrom) {
         /* we always create the cdrom drive, even if no disk is there */
-        drive_add(NULL, CDROM_ALIAS);
+        if (!drive_add(NULL, CDROM_ALIAS))
+	    exit(1);
     }
 
     if (default_floppy) {
         /* we always create at least one floppy */
-        drive_add(NULL, FD_ALIAS, 0);
+        if (!drive_add(NULL, FD_ALIAS, 0))
+	    exit(1);
     }
 
     if (default_sdcard) {
         /* we always create one sd slot, even if no card is in it */
-        drive_add(NULL, SD_ALIAS);
+        if (!drive_add(NULL, SD_ALIAS))
+	    exit(1);
     }
 
     /* open the virtual block devices */
-- 
1.6.6.1

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [Qemu-devel] [PATCH 06/19] Convert drive options to use enumeration data type
  2010-06-07 14:42 [Qemu-devel] [PATCH 00/19] RFC: Reporting QEMU binary capabilities Daniel P. Berrange
                   ` (4 preceding siblings ...)
  2010-06-07 14:42 ` [Qemu-devel] [PATCH 05/19] Ensure that QEMU exits if drive_add parsing fails Daniel P. Berrange
@ 2010-06-07 14:42 ` Daniel P. Berrange
  2010-06-09 19:52   ` Luiz Capitulino
  2010-06-26  7:07   ` Markus Armbruster
  2010-06-07 14:42 ` [Qemu-devel] [PATCH 07/19] Convert netdev client types to use an enumeration Daniel P. Berrange
                   ` (15 subsequent siblings)
  21 siblings, 2 replies; 62+ messages in thread
From: Daniel P. Berrange @ 2010-06-07 14:42 UTC (permalink / raw)
  To: qemu-devel

This converts the drive options if, trans, media, cache, aio,
rerror and werror to use the QEMU_OPT_ENUM datatype. This
standardizes the string parsing and error reporting

  $ qemu  -drive file=foo,werror=stop3
  qemu: -drive file=foo,if=mtd,werror=stop3: Parameter 'werror' expects report, ignore, enospc, stop

  $ qemu  -readconfig bar.cfg
  qemu:bar.cfg:6: Parameter 'werror' expects report, ignore, enospc, stop
  read config bar.cfg: Invalid argument

* block.c: Implementations for all enumerations
* block.h, sysemu.h: Declare enumerations
* qemu-config.c: Convert if, trans, media, cache, aio,
  rerror and werror to use the QEMU_OPT_ENUM
* vl.c: Remove handcrafted string -> int conversions in drive_init

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
---
 block.c       |   32 +++++++-----
 block.h       |   55 +++++++++++++++++---
 hw/qdev.c     |    2 +-
 qemu-config.c |   73 +++++++++++++++++++++++---
 sysemu.h      |   23 +++++++--
 vl.c          |  162 ++++++++++++++++-----------------------------------------
 6 files changed, 197 insertions(+), 150 deletions(-)

diff --git a/block.c b/block.c
index 39724c1..7ca55e2 100644
--- a/block.c
+++ b/block.c
@@ -27,6 +27,7 @@
 #include "block_int.h"
 #include "module.h"
 #include "qemu-objects.h"
+#include "sysemu.h"
 
 #ifdef CONFIG_BSD
 #include <sys/types.h>
@@ -42,6 +43,22 @@
 #include <windows.h>
 #endif
 
+QEMU_ENUM_IMPL(bdrv_type, BDRV_TYPE_LAST,
+               "hd", "cdrom", "floppy");
+QEMU_ENUM_IMPL(bdrv_bios_ata_translation, BIOS_ATA_TRANSLATION_LAST,
+               "auto", "none", "lba", "large", "rechs");
+QEMU_ENUM_IMPL(bdrv_cache, BDRV_CACHE_LAST,
+               "none", "off", "writeback", "writethrough", "unsafe");
+QEMU_ENUM_IMPL(bdrv_if_type, IF_LAST,
+               "none", "ide", "scsi", "floppy", "pflash",
+               "mtd", "sd", "virtio", "xen");
+QEMU_ENUM_IMPL(bdrv_if_error_action, BLOCK_ERR_LAST,
+               "report", "ignore", "enospc", "stop");
+QEMU_ENUM_IMPL(bdrv_media, BDRV_MEDIA_LAST,
+               "disk", "cdrom");
+QEMU_ENUM_IMPL(bdrv_aio, BDRV_AIO_LAST,
+               "native", "threads");
+
 static BlockDriverAIOCB *bdrv_aio_readv_em(BlockDriverState *bs,
         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
         BlockDriverCompletionFunc *cb, void *opaque);
@@ -1454,19 +1471,8 @@ void bdrv_info(Monitor *mon, QObject **ret_data)
 
     QTAILQ_FOREACH(bs, &bdrv_states, list) {
         QObject *bs_obj;
-        const char *type = "unknown";
-
-        switch(bs->type) {
-        case BDRV_TYPE_HD:
-            type = "hd";
-            break;
-        case BDRV_TYPE_CDROM:
-            type = "cdrom";
-            break;
-        case BDRV_TYPE_FLOPPY:
-            type = "floppy";
-            break;
-        }
+        const char *type = bdrv_type_to_string(bs->type);
+        assert(type != NULL);
 
         bs_obj = qobject_from_jsonf("{ 'device': %s, 'type': %s, "
                                     "'removable': %i, 'locked': %i }",
diff --git a/block.h b/block.h
index 756670d..11a029b 100644
--- a/block.h
+++ b/block.h
@@ -4,6 +4,7 @@
 #include "qemu-aio.h"
 #include "qemu-common.h"
 #include "qemu-option.h"
+#include "qemu-enum.h"
 #include "qobject.h"
 
 /* block.c */
@@ -128,14 +129,52 @@ int bdrv_has_zero_init(BlockDriverState *bs);
 int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
 	int *pnum);
 
-#define BDRV_TYPE_HD     0
-#define BDRV_TYPE_CDROM  1
-#define BDRV_TYPE_FLOPPY 2
-#define BIOS_ATA_TRANSLATION_AUTO   0
-#define BIOS_ATA_TRANSLATION_NONE   1
-#define BIOS_ATA_TRANSLATION_LBA    2
-#define BIOS_ATA_TRANSLATION_LARGE  3
-#define BIOS_ATA_TRANSLATION_RECHS  4
+enum {
+    BDRV_TYPE_HD,
+    BDRV_TYPE_CDROM,
+    BDRV_TYPE_FLOPPY,
+
+    BDRV_TYPE_LAST
+};
+QEMU_ENUM_DECL(bdrv_type);
+
+enum {
+    BIOS_ATA_TRANSLATION_AUTO,
+    BIOS_ATA_TRANSLATION_NONE,
+    BIOS_ATA_TRANSLATION_LBA,
+    BIOS_ATA_TRANSLATION_LARGE,
+    BIOS_ATA_TRANSLATION_RECHS,
+
+    BIOS_ATA_TRANSLATION_LAST
+};
+QEMU_ENUM_DECL(bdrv_bios_ata_translation);
+
+enum {
+    BDRV_CACHE_NONE,
+    BDRV_CACHE_OFF,
+    BDRV_CACHE_WRITEBACK,
+    BDRV_CACHE_WRITETHROUGH,
+    BDRV_CACHE_UNSAFE,
+
+    BDRV_CACHE_LAST
+};
+QEMU_ENUM_DECL(bdrv_cache);
+
+enum {
+    BDRV_MEDIA_DISK,
+    BDRV_MEDIA_CDROM,
+
+    BDRV_MEDIA_LAST
+};
+QEMU_ENUM_DECL(bdrv_media);
+
+enum {
+    BDRV_AIO_NATIVE,
+    BDRV_AIO_THREADS,
+
+    BDRV_AIO_LAST
+};
+QEMU_ENUM_DECL(bdrv_aio);
 
 void bdrv_set_geometry_hint(BlockDriverState *bs,
                             int cyls, int heads, int secs);
diff --git a/hw/qdev.c b/hw/qdev.c
index aa2ce01..1186dfa 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -414,7 +414,7 @@ void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd)
     }
 }
 
-static int next_block_unit[IF_COUNT];
+static int next_block_unit[IF_LAST];
 
 /* Get a block device.  This should only be used for single-drive devices
    (e.g. SD/Floppy/MTD).  Multi-disk devices (scsi/ide) should use the
diff --git a/qemu-config.c b/qemu-config.c
index 5a4e61b..f656e6b 100644
--- a/qemu-config.c
+++ b/qemu-config.c
@@ -4,6 +4,7 @@
 #include "qemu-config.h"
 #include "sysemu.h"
 #include "hw/qdev.h"
+#include "block.h"
 
 QemuOptsList qemu_drive_opts = {
     .name = "drive",
@@ -19,8 +20,16 @@ QemuOptsList qemu_drive_opts = {
             .help = "unit number (i.e. lun for scsi)",
         },{
             .name = "if",
-            .type = QEMU_OPT_STRING,
+            .type = QEMU_OPT_ENUM,
             .help = "interface (ide, scsi, sd, mtd, floppy, pflash, virtio)",
+            .validate = {
+                .optEnum = {
+                    .to_string = bdrv_if_type_to_string,
+                    .to_string_list = bdrv_if_type_to_string_list,
+                    .from_string = bdrv_if_type_from_string,
+                    .last = IF_LAST
+                }
+            },
         },{
             .name = "index",
             .type = QEMU_OPT_NUMBER,
@@ -38,12 +47,28 @@ QemuOptsList qemu_drive_opts = {
             .help = "number of sectors (ide disk geometry)",
         },{
             .name = "trans",
-            .type = QEMU_OPT_STRING,
+            .type = QEMU_OPT_ENUM,
             .help = "chs translation (auto, lba. none)",
+            .validate = {
+                .optEnum = {
+                    .to_string = bdrv_bios_ata_translation_to_string,
+                    .to_string_list = bdrv_bios_ata_translation_to_string_list,
+                    .from_string = bdrv_bios_ata_translation_from_string,
+                    .last = BIOS_ATA_TRANSLATION_LAST,
+                }
+            }
         },{
             .name = "media",
-            .type = QEMU_OPT_STRING,
+            .type = QEMU_OPT_ENUM,
             .help = "media type (disk, cdrom)",
+            .validate = {
+                .optEnum = {
+                    .to_string = bdrv_media_to_string,
+                    .to_string_list = bdrv_media_to_string_list,
+                    .from_string = bdrv_media_from_string,
+                    .last = BDRV_MEDIA_LAST,
+                }
+            }
         },{
             .name = "snapshot",
             .type = QEMU_OPT_BOOL,
@@ -53,25 +78,57 @@ QemuOptsList qemu_drive_opts = {
             .help = "disk image",
         },{
             .name = "cache",
-            .type = QEMU_OPT_STRING,
+            .type = QEMU_OPT_ENUM,
             .help = "host cache usage (none, writeback, writethrough, unsafe)",
+            .validate = {
+                .optEnum = {
+                    .to_string = bdrv_cache_to_string,
+                    .to_string_list = bdrv_cache_to_string_list,
+                    .from_string = bdrv_cache_from_string,
+                    .last = BDRV_CACHE_LAST
+                },
+            },
         },{
             .name = "aio",
-            .type = QEMU_OPT_STRING,
+            .type = QEMU_OPT_ENUM,
             .help = "host AIO implementation (threads, native)",
+            .validate = {
+                .optEnum = {
+                    .to_string = bdrv_aio_to_string,
+                    .to_string_list = bdrv_aio_to_string_list,
+                    .from_string = bdrv_aio_from_string,
+                    .last = BDRV_CACHE_LAST
+                },
+            },
         },{
             .name = "format",
-            .type = QEMU_OPT_STRING,
+            .type = QEMU_OPT_STRING, /* Be nice as an enum, but the data is too dynamic */
             .help = "disk format (raw, qcow2, ...)",
         },{
             .name = "serial",
             .type = QEMU_OPT_STRING,
         },{
             .name = "rerror",
-            .type = QEMU_OPT_STRING,
+            .type = QEMU_OPT_ENUM,
+            .validate = {
+                .optEnum = {
+                    .to_string = bdrv_if_error_action_to_string,
+                    .to_string_list = bdrv_if_error_action_to_string_list,
+                    .from_string = bdrv_if_error_action_from_string,
+                    .last = BLOCK_ERR_LAST,
+                },
+            },
         },{
             .name = "werror",
-            .type = QEMU_OPT_STRING,
+            .type = QEMU_OPT_ENUM,
+            .validate = {
+                .optEnum = {
+                    .to_string = bdrv_if_error_action_to_string,
+                    .to_string_list = bdrv_if_error_action_to_string_list,
+                    .from_string = bdrv_if_error_action_from_string,
+                    .last = BLOCK_ERR_LAST,
+                },
+            },
         },{
             .name = "addr",
             .type = QEMU_OPT_STRING,
diff --git a/sysemu.h b/sysemu.h
index 879446a..f0c5eb8 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -6,6 +6,7 @@
 #include "qemu-option.h"
 #include "qemu-queue.h"
 #include "qemu-timer.h"
+#include "qemu-enum.h"
 
 #ifdef _WIN32
 #include <windows.h>
@@ -149,14 +150,28 @@ extern unsigned int nb_prom_envs;
 
 typedef enum {
     IF_NONE,
-    IF_IDE, IF_SCSI, IF_FLOPPY, IF_PFLASH, IF_MTD, IF_SD, IF_VIRTIO, IF_XEN,
-    IF_COUNT
+    IF_IDE,
+    IF_SCSI,
+    IF_FLOPPY,
+    IF_PFLASH,
+    IF_MTD,
+    IF_SD,
+    IF_VIRTIO,
+    IF_XEN,
+
+    IF_LAST
 } BlockInterfaceType;
+QEMU_ENUM_DECL(bdrv_if_type);
 
 typedef enum {
-    BLOCK_ERR_REPORT, BLOCK_ERR_IGNORE, BLOCK_ERR_STOP_ENOSPC,
-    BLOCK_ERR_STOP_ANY
+    BLOCK_ERR_REPORT,
+    BLOCK_ERR_IGNORE,
+    BLOCK_ERR_STOP_ENOSPC,
+    BLOCK_ERR_STOP_ANY,
+
+    BLOCK_ERR_LAST
 } BlockInterfaceErrorAction;
+QEMU_ENUM_DECL(bdrv_if_error_action);
 
 #define BLOCK_SERIAL_STRLEN 20
 
diff --git a/vl.c b/vl.c
index 3d08a44..16491c4 100644
--- a/vl.c
+++ b/vl.c
@@ -754,23 +754,6 @@ void drive_uninit(DriveInfo *dinfo)
     qemu_free(dinfo);
 }
 
-static int parse_block_error_action(const char *buf, int is_read)
-{
-    if (!strcmp(buf, "ignore")) {
-        return BLOCK_ERR_IGNORE;
-    } else if (!is_read && !strcmp(buf, "enospc")) {
-        return BLOCK_ERR_STOP_ENOSPC;
-    } else if (!strcmp(buf, "stop")) {
-        return BLOCK_ERR_STOP_ANY;
-    } else if (!strcmp(buf, "report")) {
-        return BLOCK_ERR_REPORT;
-    } else {
-        fprintf(stderr, "qemu: '%s' invalid %s error action\n",
-            buf, is_read ? "read" : "write");
-        return -1;
-    }
-}
-
 DriveInfo *drive_init(QemuOpts *opts, void *opaque,
                       int *fatal_error)
 {
@@ -780,7 +763,7 @@ DriveInfo *drive_init(QemuOpts *opts, void *opaque,
     const char *serial;
     const char *mediastr = "";
     BlockInterfaceType type;
-    enum { MEDIA_DISK, MEDIA_CDROM } media;
+    int media;
     int bus_id, unit_id;
     int cyls, heads, secs, translation;
     BlockDriver *drv = NULL;
@@ -796,8 +779,6 @@ DriveInfo *drive_init(QemuOpts *opts, void *opaque,
 
     *fatal_error = 1;
 
-    translation = BIOS_ATA_TRANSLATION_AUTO;
-
     if (machine && machine->use_scsi) {
         type = IF_SCSI;
         max_devs = MAX_SCSI_DEVS;
@@ -807,7 +788,6 @@ DriveInfo *drive_init(QemuOpts *opts, void *opaque,
         max_devs = MAX_IDE_DEVS;
         pstrcpy(devname, sizeof(devname), "ide");
     }
-    media = MEDIA_DISK;
 
     /* extract parameters */
     bus_id  = qemu_opt_get_number(opts, "bus", 0);
@@ -824,40 +804,15 @@ DriveInfo *drive_init(QemuOpts *opts, void *opaque,
     file = qemu_opt_get(opts, "file");
     serial = qemu_opt_get(opts, "serial");
 
-    if ((buf = qemu_opt_get(opts, "if")) != NULL) {
+    type = qemu_opt_get_enum(opts, "if", IF_IDE);
+    if (type == IF_IDE)
+	max_devs = MAX_IDE_DEVS;
+    else if (type == IF_SCSI)
+	max_devs = MAX_SCSI_DEVS;
+    else
+	max_devs = 0;
+    if ((buf = qemu_opt_get(opts, "if")))
         pstrcpy(devname, sizeof(devname), buf);
-        if (!strcmp(buf, "ide")) {
-	    type = IF_IDE;
-            max_devs = MAX_IDE_DEVS;
-        } else if (!strcmp(buf, "scsi")) {
-	    type = IF_SCSI;
-            max_devs = MAX_SCSI_DEVS;
-        } else if (!strcmp(buf, "floppy")) {
-	    type = IF_FLOPPY;
-            max_devs = 0;
-        } else if (!strcmp(buf, "pflash")) {
-	    type = IF_PFLASH;
-            max_devs = 0;
-	} else if (!strcmp(buf, "mtd")) {
-	    type = IF_MTD;
-            max_devs = 0;
-	} else if (!strcmp(buf, "sd")) {
-	    type = IF_SD;
-            max_devs = 0;
-        } else if (!strcmp(buf, "virtio")) {
-            type = IF_VIRTIO;
-            max_devs = 0;
-	} else if (!strcmp(buf, "xen")) {
-	    type = IF_XEN;
-            max_devs = 0;
-	} else if (!strcmp(buf, "none")) {
-	    type = IF_NONE;
-            max_devs = 0;
-	} else {
-            fprintf(stderr, "qemu: unsupported bus type '%s'\n", buf);
-            return NULL;
-	}
-    }
 
     if (cyls || heads || secs) {
         if (cyls < 1 || (type == IF_IDE && cyls > 16383)) {
@@ -874,67 +829,52 @@ DriveInfo *drive_init(QemuOpts *opts, void *opaque,
 	}
     }
 
-    if ((buf = qemu_opt_get(opts, "trans")) != NULL) {
+    translation = qemu_opt_get_enum(opts, "trans", BIOS_ATA_TRANSLATION_AUTO);
+    if (translation != BIOS_ATA_TRANSLATION_AUTO) {
         if (!cyls) {
             fprintf(stderr,
                     "qemu: '%s' trans must be used with cyls,heads and secs\n",
                     buf);
             return NULL;
         }
-        if (!strcmp(buf, "none"))
-            translation = BIOS_ATA_TRANSLATION_NONE;
-        else if (!strcmp(buf, "lba"))
-            translation = BIOS_ATA_TRANSLATION_LBA;
-        else if (!strcmp(buf, "auto"))
-            translation = BIOS_ATA_TRANSLATION_AUTO;
-	else {
-            fprintf(stderr, "qemu: '%s' invalid translation type\n", buf);
-	    return NULL;
-	}
     }
 
-    if ((buf = qemu_opt_get(opts, "media")) != NULL) {
-        if (!strcmp(buf, "disk")) {
-	    media = MEDIA_DISK;
-	} else if (!strcmp(buf, "cdrom")) {
-            if (cyls || secs || heads) {
-                fprintf(stderr,
-                        "qemu: '%s' invalid physical CHS format\n", buf);
-	        return NULL;
-            }
-	    media = MEDIA_CDROM;
-	} else {
-	    fprintf(stderr, "qemu: '%s' invalid media\n", buf);
+    media = qemu_opt_get_enum(opts, "media", BDRV_MEDIA_DISK);
+
+    if (media == BDRV_MEDIA_CDROM) {
+	if (cyls || secs || heads) {
+	    fprintf(stderr,
+		    "qemu: '%s' invalid physical CHS format\n", buf);
 	    return NULL;
 	}
     }
 
     if ((buf = qemu_opt_get(opts, "cache")) != NULL) {
-        if (!strcmp(buf, "off") || !strcmp(buf, "none")) {
-            bdrv_flags |= BDRV_O_NOCACHE;
-        } else if (!strcmp(buf, "writeback")) {
-            bdrv_flags |= BDRV_O_CACHE_WB;
-        } else if (!strcmp(buf, "unsafe")) {
-            bdrv_flags |= BDRV_O_CACHE_WB;
-            bdrv_flags |= BDRV_O_NO_FLUSH;
-        } else if (!strcmp(buf, "writethrough")) {
-            /* this is the default */
-        } else {
+        int mode = bdrv_cache_from_string(buf);
+        int flags[] = {
+            BDRV_O_NOCACHE,                 /* none */
+            BDRV_O_NOCACHE,                 /* off */
+            BDRV_O_CACHE_WB,                /* writeback */
+            0,                              /* writethrough */
+            BDRV_O_CACHE_WB|BDRV_O_NO_FLUSH /* unsafe */
+        };
+        verify_true(ARRAY_SIZE(flags) == BDRV_CACHE_LAST);
+        if (mode < 0) {
            fprintf(stderr, "qemu: invalid cache option\n");
            return NULL;
         }
+        bdrv_flags |= flags[mode];
     }
 
 #ifdef CONFIG_LINUX_AIO
     if ((buf = qemu_opt_get(opts, "aio")) != NULL) {
-        if (!strcmp(buf, "native")) {
-            bdrv_flags |= BDRV_O_NATIVE_AIO;
-        } else if (!strcmp(buf, "threads")) {
-            /* this is the default */
-        } else {
+        int aio = bdrv_aio_from_string(buf);
+        if (aio < 0) {
            fprintf(stderr, "qemu: invalid aio option\n");
            return NULL;
         }
+        if (aio == BDRV_AIO_NATIVE)
+            bdrv_flags |= BDRV_O_NATIVE_AIO;
     }
 #endif
 
@@ -952,28 +892,18 @@ DriveInfo *drive_init(QemuOpts *opts, void *opaque,
         }
     }
 
-    on_write_error = BLOCK_ERR_STOP_ENOSPC;
-    if ((buf = qemu_opt_get(opts, "werror")) != NULL) {
+    on_write_error = qemu_opt_get_enum(opts, "werror", BLOCK_ERR_STOP_ENOSPC);
+    if (on_write_error != BLOCK_ERR_STOP_ENOSPC) {
         if (type != IF_IDE && type != IF_SCSI && type != IF_VIRTIO && type != IF_NONE) {
-            fprintf(stderr, "werror is no supported by this format\n");
-            return NULL;
-        }
-
-        on_write_error = parse_block_error_action(buf, 0);
-        if (on_write_error < 0) {
+            fprintf(stderr, "werror is not supported by this format\n");
             return NULL;
         }
     }
 
-    on_read_error = BLOCK_ERR_REPORT;
-    if ((buf = qemu_opt_get(opts, "rerror")) != NULL) {
+    on_read_error = qemu_opt_get_enum(opts, "rerror", BLOCK_ERR_REPORT);
+    if (on_read_error != BLOCK_ERR_REPORT) {
         if (type != IF_IDE && type != IF_VIRTIO && type != IF_NONE) {
-            fprintf(stderr, "rerror is no supported by this format\n");
-            return NULL;
-        }
-
-        on_read_error = parse_block_error_action(buf, 1);
-        if (on_read_error < 0) {
+            fprintf(stderr, "rerror is not supported by this format\n");
             return NULL;
         }
     }
@@ -1044,7 +974,7 @@ DriveInfo *drive_init(QemuOpts *opts, void *opaque,
         /* no id supplied -> create one */
         dinfo->id = qemu_mallocz(32);
         if (type == IF_IDE || type == IF_SCSI)
-            mediastr = (media == MEDIA_CDROM) ? "-cd" : "-hd";
+            mediastr = (media == BDRV_MEDIA_CDROM) ? "-cd" : "-hd";
         if (max_devs)
             snprintf(dinfo->id, 32, "%s%i%s%i",
                      devname, bus_id, mediastr, unit_id);
@@ -1070,16 +1000,16 @@ DriveInfo *drive_init(QemuOpts *opts, void *opaque,
     case IF_XEN:
     case IF_NONE:
         switch(media) {
-	case MEDIA_DISK:
+        case BDRV_MEDIA_DISK:
             if (cyls != 0) {
                 bdrv_set_geometry_hint(dinfo->bdrv, cyls, heads, secs);
                 bdrv_set_translation_hint(dinfo->bdrv, translation);
             }
-	    break;
-	case MEDIA_CDROM:
+            break;
+        case BDRV_MEDIA_CDROM:
             bdrv_set_type_hint(dinfo->bdrv, BDRV_TYPE_CDROM);
-	    break;
-	}
+            break;
+        }
         break;
     case IF_SD:
         /* FIXME: This isn't really a floppy, but it's a reasonable
@@ -1098,7 +1028,7 @@ DriveInfo *drive_init(QemuOpts *opts, void *opaque,
         if (devaddr)
             qemu_opt_set(opts, "addr", devaddr);
         break;
-    case IF_COUNT:
+    default:
         abort();
     }
     if (!file) {
@@ -1111,7 +1041,7 @@ DriveInfo *drive_init(QemuOpts *opts, void *opaque,
         bdrv_flags |= (BDRV_O_SNAPSHOT|BDRV_O_CACHE_WB|BDRV_O_NO_FLUSH);
     }
 
-    if (media == MEDIA_CDROM) {
+    if (media == BDRV_MEDIA_CDROM) {
         /* CDROM is fine for any interface, don't check.  */
         ro = 1;
     } else if (ro == 1) {
-- 
1.6.6.1

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [Qemu-devel] [PATCH 07/19] Convert netdev client types to use an enumeration
  2010-06-07 14:42 [Qemu-devel] [PATCH 00/19] RFC: Reporting QEMU binary capabilities Daniel P. Berrange
                   ` (5 preceding siblings ...)
  2010-06-07 14:42 ` [Qemu-devel] [PATCH 06/19] Convert drive options to use enumeration data type Daniel P. Berrange
@ 2010-06-07 14:42 ` Daniel P. Berrange
  2010-06-07 15:09   ` Anthony Liguori
  2010-06-07 14:42 ` [Qemu-devel] [PATCH 08/19] Convert RTC to use enumerations for configuration parameters Daniel P. Berrange
                   ` (14 subsequent siblings)
  21 siblings, 1 reply; 62+ messages in thread
From: Daniel P. Berrange @ 2010-06-07 14:42 UTC (permalink / raw)
  To: qemu-devel

Declare an enumeration for all netdev client types, values
matching indexes in the net_client_types array. Use the
enum helpers for the string <-> int conversion of client types.

Before:

  $ qemu -net type=foo,sfs
  qemu: -net type=foo,sfs: Parameter 'type' expects a network client type

After:

  $ qemu -net type=foo,sfs
  qemu: -net type=foo,sfs: Parameter 'type' expects none, nic, user, tap, socket, dump

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
---
 net.c |  124 ++++++++++++++++++++++++++++++++++++++--------------------------
 1 files changed, 74 insertions(+), 50 deletions(-)

diff --git a/net.c b/net.c
index efa8b3d..5349001 100644
--- a/net.c
+++ b/net.c
@@ -42,6 +42,36 @@ static QTAILQ_HEAD(, VLANClientState) non_vlan_clients;
 
 int default_net = 1;
 
+enum {
+    NET_CLIENT_NONE,
+    NET_CLIENT_NIC,
+#ifdef CONFIG_SLIRP
+    NET_CLIENT_USER,
+#endif
+    NET_CLIENT_TAP,
+    NET_CLIENT_SOCKET,
+#ifdef CONFIG_VDE
+    NET_CLIENT_VDE,
+#endif
+    NET_CLIENT_DUMP,
+
+    NET_CLIENT_LAST
+};
+
+QEMU_ENUM_DECL(qemu_net_type);
+QEMU_ENUM_IMPL(qemu_net_type, NET_CLIENT_LAST,
+	       "none",
+	       "nic",
+#ifdef CONFIG_SLIRP
+	       "user",
+#endif
+	       "tap",
+	       "socket",
+#ifdef CONFIG_VDE
+	       "vde",
+#endif
+	       "dump");
+
 /***********************************************************/
 /* network device redirectors */
 
@@ -844,18 +874,15 @@ typedef int (*net_client_init_func)(QemuOpts *opts,
 #define NET_MAX_DESC 20
 
 static const struct {
-    const char *type;
     net_client_init_func init;
     QemuOptDesc desc[NET_MAX_DESC];
 } net_client_types[] = {
-    {
-        .type = "none",
+    { /* NET_CLIENT_NONE */
         .desc = {
             NET_COMMON_PARAMS_DESC,
             { /* end of list */ }
         },
-    }, {
-        .type = "nic",
+    }, { /* NET_CLIENT_NIC */
         .init = net_init_nic,
         .desc = {
             NET_COMMON_PARAMS_DESC,
@@ -884,8 +911,7 @@ static const struct {
             { /* end of list */ }
         },
 #ifdef CONFIG_SLIRP
-    }, {
-        .type = "user",
+    }, { /* NET_CLIENT_USER */
         .init = net_init_slirp,
         .desc = {
             NET_COMMON_PARAMS_DESC,
@@ -945,8 +971,7 @@ static const struct {
             { /* end of list */ }
         },
 #endif
-    }, {
-        .type = "tap",
+    }, { /* NET_CLIENT_TAP */
         .init = net_init_tap,
         .desc = {
             NET_COMMON_PARAMS_DESC,
@@ -988,8 +1013,7 @@ static const struct {
 #endif /* _WIN32 */
             { /* end of list */ }
         },
-    }, {
-        .type = "socket",
+    }, { /* NET_CLIENT_SOCKET */
         .init = net_init_socket,
         .desc = {
             NET_COMMON_PARAMS_DESC,
@@ -1013,8 +1037,7 @@ static const struct {
             { /* end of list */ }
         },
 #ifdef CONFIG_VDE
-    }, {
-        .type = "vde",
+    }, { /* NET_CLIENT_VDE */
         .init = net_init_vde,
         .desc = {
             NET_COMMON_PARAMS_DESC,
@@ -1038,8 +1061,7 @@ static const struct {
             { /* end of list */ }
         },
 #endif
-    }, {
-        .type = "dump",
+    }, { /* NET_CLIENT_DUMP */
         .init = net_init_dump,
         .desc = {
             NET_COMMON_PARAMS_DESC,
@@ -1055,30 +1077,41 @@ static const struct {
             { /* end of list */ }
         },
     },
-    { /* end of list */ }
 };
+verify(ARRAY_SIZE(net_client_types) == NET_CLIENT_LAST);
 
 int net_client_init(Monitor *mon, QemuOpts *opts, int is_netdev)
 {
     const char *name;
-    const char *type;
-    int i;
+    const char *typestr;
+    VLANState *vlan = NULL;
+    int type;
 
-    type = qemu_opt_get(opts, "type");
-    if (!type) {
+    typestr = qemu_opt_get(opts, "type");
+    if (!typestr) {
         qerror_report(QERR_MISSING_PARAMETER, "type");
         return -1;
     }
+    type = qemu_net_type_from_string(typestr);
+
+    if (type < 0) {
+	char *valid = qemu_net_type_to_string_list();
+	qerror_report(QERR_INVALID_PARAMETER_VALUE, "type",
+		      valid);
+	qemu_free(valid);
+	return -1;
+    }
 
     if (is_netdev) {
-        if (strcmp(type, "tap") != 0 &&
+	if (type < 0 ||
+	    (type != NET_CLIENT_TAP &&
 #ifdef CONFIG_SLIRP
-            strcmp(type, "user") != 0 &&
+	     type != NET_CLIENT_USER &&
 #endif
 #ifdef CONFIG_VDE
-            strcmp(type, "vde") != 0 &&
+	     type != NET_CLIENT_VDE &&
 #endif
-            strcmp(type, "socket") != 0) {
+	     type != NET_CLIENT_SOCKET)) {
             qerror_report(QERR_INVALID_PARAMETER_VALUE, "type",
                           "a netdev backend type");
             return -1;
@@ -1103,35 +1136,26 @@ int net_client_init(Monitor *mon, QemuOpts *opts, int is_netdev)
         name = qemu_opt_get(opts, "name");
     }
 
-    for (i = 0; net_client_types[i].type != NULL; i++) {
-        if (!strcmp(net_client_types[i].type, type)) {
-            VLANState *vlan = NULL;
-
-            if (qemu_opts_validate(opts, &net_client_types[i].desc[0]) == -1) {
-                return -1;
-            }
-
-            /* Do not add to a vlan if it's a -netdev or a nic with a
-             * netdev= parameter. */
-            if (!(is_netdev ||
-                  (strcmp(type, "nic") == 0 && qemu_opt_get(opts, "netdev")))) {
-                vlan = qemu_find_vlan(qemu_opt_get_number(opts, "vlan", 0), 1);
-            }
+    if (qemu_opts_validate(opts, &net_client_types[type].desc[0]) == -1) {
+	return -1;
+    }
 
-            if (net_client_types[i].init) {
-                if (net_client_types[i].init(opts, mon, name, vlan) < 0) {
-                    /* TODO push error reporting into init() methods */
-                    qerror_report(QERR_DEVICE_INIT_FAILED, type);
-                    return -1;
-                }
-            }
-            return 0;
-        }
+    /* Do not add to a vlan if it's a -netdev or a nic with a
+     * netdev= parameter. */
+    if (!(is_netdev ||
+	  (type == NET_CLIENT_NIC && qemu_opt_get(opts, "netdev")))) {
+	vlan = qemu_find_vlan(qemu_opt_get_number(opts, "vlan", 0), 1);
     }
 
-    qerror_report(QERR_INVALID_PARAMETER_VALUE, "type",
-                  "a network client type");
-    return -1;
+    if (net_client_types[type].init) {
+	if (net_client_types[type].init(opts, mon, name, vlan) < 0) {
+	    /* TODO push error reporting into init() methods */
+	    qerror_report(QERR_DEVICE_INIT_FAILED,
+			  qemu_net_type_to_string(type));
+	    return -1;
+	}
+    }
+    return 0;
 }
 
 static int net_host_check_device(const char *device)
-- 
1.6.6.1

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [Qemu-devel] [PATCH 08/19] Convert RTC to use enumerations for configuration parameters
  2010-06-07 14:42 [Qemu-devel] [PATCH 00/19] RFC: Reporting QEMU binary capabilities Daniel P. Berrange
                   ` (6 preceding siblings ...)
  2010-06-07 14:42 ` [Qemu-devel] [PATCH 07/19] Convert netdev client types to use an enumeration Daniel P. Berrange
@ 2010-06-07 14:42 ` Daniel P. Berrange
  2010-06-09 19:54   ` Luiz Capitulino
  2010-06-07 14:42 ` [Qemu-devel] [PATCH 09/19] Change 'query-version' to output broken down version string Daniel P. Berrange
                   ` (13 subsequent siblings)
  21 siblings, 1 reply; 62+ messages in thread
From: Daniel P. Berrange @ 2010-06-07 14:42 UTC (permalink / raw)
  To: qemu-devel

Convert the rtc clock and driftfix parameters to use enums for
configuration. This ensures strict validation at time of config
parsing.

Also fixes a bug in qemu-config.c where 'driftfix' was never
enabled because this is a target independant compliation unit,
thus cannot include config-target.h and thus never has the
TARGET_I386 symbol defined.

Ideally the 'base' parameter would be an enum too, but this
value is overloaded to also accept a pretty-printed start
date.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
---
 hw/mc146818rtc.c |    8 ++++----
 qemu-config.c    |   27 +++++++++++++++++++++++----
 sysemu.h         |   20 +++++++++++++++++++-
 vl.c             |   34 ++++++++++------------------------
 4 files changed, 56 insertions(+), 33 deletions(-)

diff --git a/hw/mc146818rtc.c b/hw/mc146818rtc.c
index c3e6a70..cbb072c 100644
--- a/hw/mc146818rtc.c
+++ b/hw/mc146818rtc.c
@@ -202,7 +202,7 @@ static void rtc_periodic_timer(void *opaque)
     if (s->cmos_data[RTC_REG_B] & REG_B_PIE) {
         s->cmos_data[RTC_REG_C] |= 0xc0;
 #ifdef TARGET_I386
-        if(rtc_td_hack) {
+        if(rtc_driftfix == QEMU_RTC_DRIFTFIX_SLEW) {
             if (s->irq_reinject_on_ack_count >= RTC_REINJECT_ON_ACK_COUNT)
                 s->irq_reinject_on_ack_count = 0;		
             apic_reset_irq_delivered();
@@ -552,7 +552,7 @@ static int rtc_post_load(void *opaque, int version_id)
     RTCState *s = opaque;
 
     if (version_id >= 2) {
-        if (rtc_td_hack) {
+        if (rtc_driftfix == QEMU_RTC_DRIFTFIX_SLEW) {
             rtc_coalesced_timer_update(s);
         }
     }
@@ -597,7 +597,7 @@ static void rtc_reset(void *opaque)
     qemu_irq_lower(s->irq);
 
 #ifdef TARGET_I386
-    if (rtc_td_hack)
+    if (rtc_driftfix == QEMU_RTC_DRIFTFIX_SLEW)
 	    s->irq_coalesced = 0;
 #endif
 }
@@ -619,7 +619,7 @@ static int rtc_initfn(ISADevice *dev)
 
     s->periodic_timer = qemu_new_timer(rtc_clock, rtc_periodic_timer, s);
 #ifdef TARGET_I386
-    if (rtc_td_hack)
+    if (rtc_driftfix == QEMU_RTC_DRIFTFIX_SLEW)
         s->coalesced_timer =
             qemu_new_timer(rtc_clock, rtc_coalesced_timer, s);
 #endif
diff --git a/qemu-config.c b/qemu-config.c
index f656e6b..75cddc1 100644
--- a/qemu-config.c
+++ b/qemu-config.c
@@ -288,6 +288,11 @@ QemuOptsList qemu_net_opts = {
     },
 };
 
+QEMU_ENUM_IMPL(qemu_rtc_clock, QEMU_RTC_CLOCK_LAST,
+	       "host", "guest");
+QEMU_ENUM_IMPL(qemu_rtc_driftfix, QEMU_RTC_DRIFTFIX_LAST,
+	       "none", "slew");
+
 QemuOptsList qemu_rtc_opts = {
     .name = "rtc",
     .head = QTAILQ_HEAD_INITIALIZER(qemu_rtc_opts.head),
@@ -297,12 +302,26 @@ QemuOptsList qemu_rtc_opts = {
             .type = QEMU_OPT_STRING,
         },{
             .name = "clock",
-            .type = QEMU_OPT_STRING,
-#ifdef TARGET_I386
+            .type = QEMU_OPT_ENUM,
+            .validate = {
+                .optEnum = {
+                    .to_string = qemu_rtc_clock_to_string,
+                    .to_string_list = qemu_rtc_clock_to_string_list,
+                    .from_string = qemu_rtc_clock_from_string,
+                    .last = QEMU_RTC_CLOCK_LAST,
+                },
+            },
         },{
             .name = "driftfix",
-            .type = QEMU_OPT_STRING,
-#endif
+            .type = QEMU_OPT_ENUM,
+            .validate = {
+                .optEnum = {
+                    .to_string = qemu_rtc_driftfix_to_string,
+                    .to_string_list = qemu_rtc_driftfix_to_string_list,
+                    .from_string = qemu_rtc_driftfix_from_string,
+                    .last = QEMU_RTC_DRIFTFIX_LAST,
+                },
+            },
         },
         { /* end if list */ }
     },
diff --git a/sysemu.h b/sysemu.h
index f0c5eb8..4d39566 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -120,7 +120,6 @@ extern uint8_t irq0override;
 extern DisplayType display_type;
 extern const char *keyboard_layout;
 extern int win2k_install_hack;
-extern int rtc_td_hack;
 extern int alt_grab;
 extern int ctrl_grab;
 extern int usb_enabled;
@@ -133,7 +132,26 @@ extern int no_shutdown;
 extern int semihosting_enabled;
 extern int old_param;
 extern int boot_menu;
+
 extern QEMUClock *rtc_clock;
+extern int rtc_driftfix;
+
+enum {
+    QEMU_RTC_CLOCK_HOST,
+    QEMU_RTC_CLOCK_GUEST,
+
+    QEMU_RTC_CLOCK_LAST
+};
+QEMU_ENUM_DECL(qemu_rtc_clock);
+
+enum {
+    QEMU_RTC_DRIFTFIX_NONE,
+    QEMU_RTC_DRIFTFIX_SLEW,
+
+    QEMU_RTC_DRIFTFIX_LAST
+};
+QEMU_ENUM_DECL(qemu_rtc_driftfix);
+
 
 #define MAX_NODES 64
 extern int nb_numa_nodes;
diff --git a/vl.c b/vl.c
index 16491c4..0b38d62 100644
--- a/vl.c
+++ b/vl.c
@@ -201,7 +201,7 @@ CharDriverState *serial_hds[MAX_SERIAL_PORTS];
 CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
 CharDriverState *virtcon_hds[MAX_VIRTIO_CONSOLES];
 int win2k_install_hack = 0;
-int rtc_td_hack = 0;
+int rtc_driftfix = QEMU_RTC_DRIFTFIX_NONE;
 int usb_enabled = 0;
 int singlestep = 0;
 int smp_cpus = 1;
@@ -418,6 +418,9 @@ static void configure_rtc_date_offset(const char *startdate, int legacy)
 static void configure_rtc(QemuOpts *opts)
 {
     const char *value;
+    QEMUClock *clocks[] = { host_clock, vm_clock };
+    verify_true(ARRAY_SIZE(clocks) == QEMU_RTC_CLOCK_LAST);
+    int clock;
 
     value = qemu_opt_get(opts, "base");
     if (value) {
@@ -429,28 +432,11 @@ static void configure_rtc(QemuOpts *opts)
             configure_rtc_date_offset(value, 0);
         }
     }
-    value = qemu_opt_get(opts, "clock");
-    if (value) {
-        if (!strcmp(value, "host")) {
-            rtc_clock = host_clock;
-        } else if (!strcmp(value, "vm")) {
-            rtc_clock = vm_clock;
-        } else {
-            fprintf(stderr, "qemu: invalid option value '%s'\n", value);
-            exit(1);
-        }
-    }
-    value = qemu_opt_get(opts, "driftfix");
-    if (value) {
-        if (!strcmp(value, "slew")) {
-            rtc_td_hack = 1;
-        } else if (!strcmp(value, "none")) {
-            rtc_td_hack = 0;
-        } else {
-            fprintf(stderr, "qemu: invalid option value '%s'\n", value);
-            exit(1);
-        }
-    }
+
+    clock = qemu_opt_get_enum(opts, "clock", QEMU_RTC_CLOCK_HOST);
+    rtc_clock = clocks[clock];
+
+    rtc_driftfix = qemu_opt_get_enum(opts, "driftfix", QEMU_RTC_DRIFTFIX_NONE);
 }
 
 /***********************************************************/
@@ -3149,7 +3135,7 @@ int main(int argc, char **argv, char **envp)
                 win2k_install_hack = 1;
                 break;
             case QEMU_OPTION_rtc_td_hack:
-                rtc_td_hack = 1;
+                rtc_driftfix = QEMU_RTC_DRIFTFIX_SLEW;
                 break;
             case QEMU_OPTION_acpitable:
                 do_acpitable_option(optarg);
-- 
1.6.6.1

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [Qemu-devel] [PATCH 09/19] Change 'query-version' to output broken down version string
  2010-06-07 14:42 [Qemu-devel] [PATCH 00/19] RFC: Reporting QEMU binary capabilities Daniel P. Berrange
                   ` (7 preceding siblings ...)
  2010-06-07 14:42 ` [Qemu-devel] [PATCH 08/19] Convert RTC to use enumerations for configuration parameters Daniel P. Berrange
@ 2010-06-07 14:42 ` Daniel P. Berrange
  2010-06-07 15:11   ` Anthony Liguori
  2010-06-07 14:42 ` [Qemu-devel] [PATCH 10/19] Add a query-machines command to QMP Daniel P. Berrange
                   ` (12 subsequent siblings)
  21 siblings, 1 reply; 62+ messages in thread
From: Daniel P. Berrange @ 2010-06-07 14:42 UTC (permalink / raw)
  To: qemu-devel

A previous discussion brought up the fact that clients should
not have to parse version string from QMP, it should be given
to them pre-split.

Change query-version output format from:

  { "qemu": "0.11.50", "package": "" }

to:

  { qemu: { "major": 0, "minor": 11, "micro": 5 }, "package": "" }

The major, minor & micro keys are all integer values. package is
an arbitrary string whose format is defined by the OS package
maintainer.

There is no need to preserve the existing string format of the 'qemu'
key, since QMP is not yet declared stable.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
---
 monitor.c |   47 +++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 43 insertions(+), 4 deletions(-)

diff --git a/monitor.c b/monitor.c
index 15b53b9..f0406e8 100644
--- a/monitor.c
+++ b/monitor.c
@@ -670,17 +670,56 @@ help:
 static void do_info_version_print(Monitor *mon, const QObject *data)
 {
     QDict *qdict;
+    QDict *qemu;
 
     qdict = qobject_to_qdict(data);
+    qemu = qdict_get_qdict(qdict, "qemu");
 
-    monitor_printf(mon, "%s%s\n", qdict_get_str(qdict, "qemu"),
-                                  qdict_get_str(qdict, "package"));
+    monitor_printf(mon, "%" PRId64 ".%" PRId64 ".%" PRId64 "%s\n",
+		   qdict_get_int(qemu, "major"),
+		   qdict_get_int(qemu, "minor"),
+		   qdict_get_int(qemu, "micro"),
+		   qdict_get_str(qdict, "package"));
 }
 
+
+/**
+ * do_info_version(): Show QEMU version
+ *
+ * Return a QDict with the following information:
+ *
+ * - "qemu": QEMU upstream version
+ * - "package": QEMU packager's version
+ *
+ * The 'qemu' key value is a QDict containing three
+ * integer values
+ *
+ * - "major": QEMU's major version
+ * - "minor": QEMU's minor version
+ * - "micro": QEMU's micro version
+ *
+ * The 'package' key value is a string in an format
+ * defined by the OS distributor to reflect their
+ * packaging of QEMU.
+ *
+ * Example:
+ *
+ * { qemu: { "major": 0, "minor": 11, "micro": 5 }, "package": "" }
+ */
 static void do_info_version(Monitor *mon, QObject **ret_data)
 {
-    *ret_data = qobject_from_jsonf("{ 'qemu': %s, 'package': %s }",
-                                   QEMU_VERSION, QEMU_PKGVERSION);
+    const char *version = QEMU_VERSION;
+    int major = 0, minor = 0, micro = 0;
+    char *tmp;
+
+    major = strtol(version, &tmp, 10);
+    tmp++;
+    minor = strtol(tmp, &tmp, 10);
+    tmp++;
+    micro = strtol(tmp, &tmp, 10);
+
+    *ret_data = qobject_from_jsonf("{ 'qemu': { 'major': %d, 'minor': %d, 'micro': %d }, 'package': %s }",
+                                   major, minor, micro, QEMU_PKGVERSION);
 }
 
 static void do_info_name_print(Monitor *mon, const QObject *data)
-- 
1.6.6.1

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [Qemu-devel] [PATCH 10/19] Add a query-machines command to QMP
  2010-06-07 14:42 [Qemu-devel] [PATCH 00/19] RFC: Reporting QEMU binary capabilities Daniel P. Berrange
                   ` (8 preceding siblings ...)
  2010-06-07 14:42 ` [Qemu-devel] [PATCH 09/19] Change 'query-version' to output broken down version string Daniel P. Berrange
@ 2010-06-07 14:42 ` Daniel P. Berrange
  2010-06-07 15:13   ` Anthony Liguori
  2010-06-07 14:42 ` [Qemu-devel] [PATCH 11/19] Add a query-devices " Daniel P. Berrange
                   ` (11 subsequent siblings)
  21 siblings, 1 reply; 62+ messages in thread
From: Daniel P. Berrange @ 2010-06-07 14:42 UTC (permalink / raw)
  To: qemu-devel

Add a new QMP monitor command 'query-machines' to discover what
machines are defined in the QEMU binary. This is an easily
parsable replacement for 'qemu -M ?'

    [
        {
            "name": "pc-0.13",
            "description": "Standard PC",
            "default": 0
        },
        {
            "name": "pc",
            "description": "Standard PC",
            "canonical": "pc-0.13",
            "default": 1
        },
        {
            "name": "pc-0.12",
            "description": "Standard PC",
            "default": 0
        },
        ....
    ]

No legacy readline monitor output is provided.

In the future it would be desirable for each machine's QDict to
also include details of any qdev devices that are included by
default in the machine type.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
---
 hw/boards.h |    1 +
 monitor.c   |    9 +++++++
 vl.c        |   70 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 80 insertions(+), 0 deletions(-)

diff --git a/hw/boards.h b/hw/boards.h
index 6f0f0d7..2f6003d 100644
--- a/hw/boards.h
+++ b/hw/boards.h
@@ -32,6 +32,7 @@ typedef struct QEMUMachine {
 } QEMUMachine;
 
 int qemu_register_machine(QEMUMachine *m);
+void do_info_machines(Monitor *mon, QObject **data);
 
 extern QEMUMachine *current_machine;
 
diff --git a/monitor.c b/monitor.c
index f0406e8..b6aa2b4 100644
--- a/monitor.c
+++ b/monitor.c
@@ -55,6 +55,7 @@
 #include "json-streamer.h"
 #include "json-parser.h"
 #include "osdep.h"
+#include "hw/boards.h"
 
 //#define DEBUG
 //#define DEBUG_COMPLETION
@@ -2449,6 +2450,14 @@ static const mon_cmd_t info_cmds[] = {
         .mhandler.info_new = do_info_version,
     },
     {
+        .name       = "machines",
+        .args_type  = "",
+        .params     = "",
+        .help       = "show the machine boards",
+        .user_print = monitor_user_noop,
+        .mhandler.info_new = do_info_machines,
+    },
+    {
         .name       = "commands",
         .args_type  = "",
         .params     = "",
diff --git a/vl.c b/vl.c
index 0b38d62..8043fac 100644
--- a/vl.c
+++ b/vl.c
@@ -1537,6 +1537,76 @@ static QEMUMachine *find_default_machine(void)
     return NULL;
 }
 
+
+/**
+ * do_info_machines(): Show machine boards
+ *
+ * Returns a QList object listing all machine boards
+ * available with this QEMU target. Each element in
+ * the list is a QDict object containing the following
+ * keys
+ *
+ *  - "name": short name for the machine board
+ *  - "description": long description of the board
+ *  - "alias": name of an alias
+ *
+ * Example:
+ *
+ *  [
+ *     {
+ *       "name": "pc-0.13",
+ *        "description": "Standard PC",
+ *        "default": 0
+ *     },
+ *     {
+ *       "name": "pc",
+ *       "description": "Standard PC",
+ *       "canonical": "pc-0.13",
+ *       "default": 1
+ *     },
+ *     {
+ *       "name": "pc-0.12",
+ *       "description": "Standard PC",
+ *       "default": 0
+ *     },
+ *     ....
+ *  ]
+ *
+ */
+/* XXX probably better in a hw/boards.c file, but 'first_machine'
+ * and all accessors are defined in this file already
+ */
+void do_info_machines(Monitor *mon, QObject **data)
+{
+    QList *machines = qlist_new();
+    QEMUMachine *m;
+
+    for (m = first_machine; m != NULL; m = m->next) {
+        QObject *entry;
+
+	entry = qobject_from_jsonf("{ 'name': %s, 'description': %s, 'default': %d}",
+				   m->name, m->desc,
+				   !m->alias && m->is_default ? 1 : 0);
+
+	qlist_append_obj(machines, entry);
+
+	if (m->alias) {
+	    QObject *alias;
+
+	    alias = qobject_from_jsonf("{ 'name': %s, 'description': %s, 'default': %d, 'canonical': %s}",
+				       m->alias, m->desc,
+				       m->is_default ? 1 : 0, m->name);
+
+	    qlist_append_obj(machines, alias);
+	}
+
+	/* XXX list the default devices for each machine type here too ? */
+    }
+
+    *data = QOBJECT(machines);
+}
+
+
 /***********************************************************/
 /* main execution loop */
 
-- 
1.6.6.1

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [Qemu-devel] [PATCH 11/19] Add a query-devices command to QMP
  2010-06-07 14:42 [Qemu-devel] [PATCH 00/19] RFC: Reporting QEMU binary capabilities Daniel P. Berrange
                   ` (9 preceding siblings ...)
  2010-06-07 14:42 ` [Qemu-devel] [PATCH 10/19] Add a query-machines command to QMP Daniel P. Berrange
@ 2010-06-07 14:42 ` Daniel P. Berrange
  2010-06-07 15:14   ` Anthony Liguori
  2010-06-07 14:42 ` [Qemu-devel] [PATCH 12/19] Add a query-cputypes " Daniel P. Berrange
                   ` (10 subsequent siblings)
  21 siblings, 1 reply; 62+ messages in thread
From: Daniel P. Berrange @ 2010-06-07 14:42 UTC (permalink / raw)
  To: qemu-devel

Adds a command to QMP called 'query-devices' to allow for discovery
of all devices known to the QEMU binary. THis is inteded to replace
use of the '-device ?' and '-device devtype,?' command line args

The data format is designed to allow easy extension to support more
data:

    [
        {
            "name": "virtio-9p-pci",
            "creatable": true,
            "bus": "PCI",
            "props": [
                {
                    "name": "indirect_desc",
                    "type": "bit",
                    "info": "on/off"
                },
                {
                    "name": "mount_tag",
                    "type": "string",
                    "info": "string"
                },
                {
                    "name": "fsdev",
                    "type": "string",
                    "info": "string"
                }
            ]
        },
        {
            "name": "virtio-balloon-pci",
            "creatable": true,
            "bus": "PCI",
            "props": [
                {
                    "name": "indirect_desc",
                    "type": "bit",
                    "info": "on/off"
                }
            ]
        },
        ...
    ]

No legacy readline monitor output is provided.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
---
 hw/qdev.c |  146 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 hw/qdev.h |    2 +
 monitor.c |    8 +++
 3 files changed, 156 insertions(+), 0 deletions(-)

diff --git a/hw/qdev.c b/hw/qdev.c
index 1186dfa..0a10c3c 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -29,6 +29,7 @@
 #include "qdev.h"
 #include "sysemu.h"
 #include "monitor.h"
+#include "qjson.h"
 
 static int qdev_hotplug = 0;
 
@@ -810,3 +811,148 @@ int do_device_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
     }
     return qdev_unplug(dev);
 }
+
+static const char *qdev_property_type_to_string(int type) {
+    switch (type) {
+    case PROP_TYPE_UNSPEC:
+	return "unknown";
+    case PROP_TYPE_UINT8:
+	return "uint8";
+    case PROP_TYPE_UINT16:
+	return "uint16";
+    case PROP_TYPE_UINT32:
+	return "uint32";
+    case PROP_TYPE_INT32:
+	return "int32";
+    case PROP_TYPE_UINT64:
+	return "uint64";
+    case PROP_TYPE_TADDR:
+	return "taddr";
+    case PROP_TYPE_MACADDR:
+	return "macaddr";
+    case PROP_TYPE_DRIVE:
+	return "drive";
+    case PROP_TYPE_CHR:
+	return "chr";
+    case PROP_TYPE_STRING:
+	return "string";
+    case PROP_TYPE_NETDEV:
+	return "netdev";
+    case PROP_TYPE_VLAN:
+	return "vlan";
+    case PROP_TYPE_PTR:
+	return "pointer";
+    case PROP_TYPE_BIT:
+	return "bit";
+    }
+    return NULL;
+}
+
+
+/*
+ * Describe capabilities of all devices registered with qdev
+ *
+ * The returned output is a QList, each element is a QDict
+ * describing a single device type. The valid keys for the
+ * device dictionary are
+ *
+ *  - "name": the short name of the device
+ *  - "bus": the name of the bus type for the device
+ *  - "alias": an alias by which the device is also known (optional)
+ *  - "description": a long description the device (optional)
+ *  - "props": a list of device properties
+ *  - "creatable": whether this device can be created on command line
+ *
+ * The 'props' list is a QList, with each element being a
+ * QDict describing a single property of the device. The
+ * valid property keys are
+ *
+ *  - "name": the short name of the property
+ *  - "info": short description of the property
+ *  - "type": the data type of the property value
+ *
+ * An example:
+ *
+ *   [
+ *       {
+ *           "name": "virtio-9p-pci",
+ *           "creatable": true,
+ *           "bus": "PCI",
+ *           "props": [
+ *               {
+ *                   "name": "indirect_desc",
+ *                   "type": "bit",
+ *                   "info": "on/off"
+ *               },
+ *               {
+ *                   "name": "mount_tag",
+ *                   "type": "string",
+ *                   "info": "string"
+ *               },
+ *               {
+ *                   "name": "fsdev",
+ *                   "type": "string",
+ *                   "info": "string"
+ *               }
+ *           ]
+ *       },
+ *       {
+ *           "name": "virtio-balloon-pci",
+ *           "creatable": true,
+ *           "bus": "PCI",
+ *           "props": [
+ *               {
+ *                   "name": "indirect_desc",
+ *                   "type": "bit",
+ *                   "info": "on/off"
+ *               }
+ *           ]
+ *       },
+ *       ....
+ *   ]
+ */
+void do_info_devices(Monitor *mon, QObject **data)
+{
+    DeviceInfo *info;
+    QList *devs = qlist_new();
+
+    for (info = device_info_list; info != NULL; info = info->next) {
+	QObject *dev;
+	QList *props = qlist_new();
+	Property *prop;
+
+	for (prop = info->props; prop && prop->name; prop++) {
+	    QObject *entry;
+	    /*
+	     * TODO Properties without a parser are just for dirty hacks.
+	     * qdev_prop_ptr is the only such PropertyInfo.  It's marked
+	     * for removal.  This conditional should be removed along with
+	     * it.
+	     */
+	    if (!prop->info->parse) {
+		continue;           /* no way to set it, don't show */
+	    }
+
+	    const char *type = qdev_property_type_to_string(prop->info->type);
+
+	    entry = qobject_from_jsonf("{ 'name': %s, 'info': %s, 'type': %s }",
+				       prop->name, prop->info->name, type);
+
+	    qlist_append_obj(props, entry);
+	}
+
+	dev = qobject_from_jsonf("{ 'name': %s, 'bus': %s, 'props': %p, 'creatable': %i }",
+				 info->name,
+				 info->bus_info->name,
+				 props,
+				 info->no_user ? 0 : 1);
+	if (info->alias)
+	    qdict_put_obj((QDict*)dev, "alias", QOBJECT(qstring_from_str(info->alias)));
+	if (info->desc)
+	    qdict_put_obj((QDict*)dev, "description", QOBJECT(qstring_from_str(info->desc)));
+
+	qlist_append_obj(devs, dev);
+    }
+
+    *data = QOBJECT(devs);
+}
diff --git a/hw/qdev.h b/hw/qdev.h
index a44060e..fe6f981 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -280,6 +280,8 @@ void qdev_prop_set_defaults(DeviceState *dev, Property *props);
 void qdev_prop_register_global_list(GlobalProperty *props);
 void qdev_prop_set_globals(DeviceState *dev);
 
+void do_info_devices(Monitor *mon, QObject **data);
+
 /* This is a nasty hack to allow passing a NULL bus to qdev_create.  */
 extern struct BusInfo system_bus_info;
 
diff --git a/monitor.c b/monitor.c
index b6aa2b4..13f70a0 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2458,6 +2458,14 @@ static const mon_cmd_t info_cmds[] = {
         .mhandler.info_new = do_info_machines,
     },
     {
+        .name       = "devices",
+        .args_type  = "",
+        .params     = "",
+        .help       = "show the registered QDev devices",
+        .user_print = monitor_user_noop,
+        .mhandler.info_new = do_info_devices,
+    },
+    {
         .name       = "commands",
         .args_type  = "",
         .params     = "",
-- 
1.6.6.1

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [Qemu-devel] [PATCH 12/19] Add a query-cputypes command to QMP
  2010-06-07 14:42 [Qemu-devel] [PATCH 00/19] RFC: Reporting QEMU binary capabilities Daniel P. Berrange
                   ` (10 preceding siblings ...)
  2010-06-07 14:42 ` [Qemu-devel] [PATCH 11/19] Add a query-devices " Daniel P. Berrange
@ 2010-06-07 14:42 ` Daniel P. Berrange
  2010-06-26  7:18   ` Markus Armbruster
  2010-06-07 14:42 ` [Qemu-devel] [PATCH 13/19] Add a query-target " Daniel P. Berrange
                   ` (9 subsequent siblings)
  21 siblings, 1 reply; 62+ messages in thread
From: Daniel P. Berrange @ 2010-06-07 14:42 UTC (permalink / raw)
  To: qemu-devel

This adds a new QMP command called 'query-cputypes' to allow
for discovery of CPU types known to the QEMU binary. This is
intended to relpace the need to parse '-cpu ?', '-cpu ?model'
and '-cpu ?dump'

Most targets have a simple structure listing just the CPU
model names (and optionally a 'description'), with room for
future expansion of extra attributes against each model

  {
      "cputypes": {
          "models": [
              {
                  "name": "arm926"
              },
              {
                  "name": "arm946"
              },
              {
                  "name": "arm1026"
              },
              ....
          ]
      }
  }

The sparc and x86 targets have extra architecture specific
metatadata. These are in keys 'x86info' and 'sparcinfo'
against each CPU model dict. These keys are repeated at the
top level to give data about all allowed feature names

A trimmed example:

{
    "cputypes": {
        "models": [
            {
                "name": "n270",
                "description": "Intel(R) Atom(TM) CPU N270   @ 1.60GHz",
                "x86info": {
                    "xlevel": 2147483658,
                    "family": 6,
                    "vendor": "",
                    "level": 5,
                    "model": 28,
                    "stepping": 2,
                    "features": {
                        "ext_edx": [
                            "lahf_lm"
                        ],
                        "edx": [
                            "pbe",
                            "tm",
                            "ht",
                            "ss",
                            "sse2",
                            ...
                        ]
                    }
                }
            }
        ],
        "x86info": {
            "features": {
                "ext_edx": [
                    21,
                    20,
                    "nodeid_msr",
                    "cvt16",
                    17,
                    "fma4",
                    15,
                    14,
                    "wdt",
                    ....
                ]
            }
        }
    }
}

No mapping to the legacy readline monitor is provided

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
---
 cpus.c                       |   78 +++++++++++++++++++++++++++++++++++++++++
 cpus.h                       |    1 +
 monitor.c                    |    9 +++++
 target-arm/cpu.h             |    7 ++++
 target-arm/helper.c          |   21 +++++++++++
 target-cris/cpu.h            |    7 ++++
 target-cris/translate.c      |   22 ++++++++++++
 target-i386/cpu.h            |    7 ++++
 target-i386/cpuid.c          |   79 ++++++++++++++++++++++++++++++++++++++++++
 target-m68k/cpu.h            |    9 +++++
 target-m68k/helper.c         |   23 ++++++++++++
 target-mips/cpu.h            |    7 ++++
 target-mips/translate.c      |    4 ++
 target-mips/translate_init.c |   19 ++++++++++
 target-ppc/cpu.h             |    7 ++++
 target-ppc/translate.c       |    4 ++
 target-ppc/translate_init.c  |   17 +++++++++
 target-sh4/cpu.h             |    8 ++++
 target-sh4/translate.c       |   23 ++++++++++++
 target-sparc/cpu.h           |    9 +++++
 target-sparc/helper.c        |   60 ++++++++++++++++++++++++++++++++
 21 files changed, 421 insertions(+), 0 deletions(-)

diff --git a/cpus.c b/cpus.c
index 8341f6c..0943f36 100644
--- a/cpus.c
+++ b/cpus.c
@@ -30,6 +30,7 @@
 #include "gdbstub.h"
 #include "dma.h"
 #include "kvm.h"
+#include "qjson.h"
 
 #include "cpus.h"
 
@@ -862,3 +863,80 @@ void list_cpus(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
     cpu_list(f, cpu_fprintf); /* deprecated */
 #endif
 }
+
+
+/**
+ * do_info_cpu_types()
+ *
+ * Return information about the CPU types known to this target
+ *
+ * The returned data is a QDict containing one mandatory key:
+ *
+ * - models: a QList of CPU models
+ *
+ * Each CPU model is a QDict containing the following keys
+ *
+ * - name: a short name for the CPU
+ * - description: a long verbose name for the CPU (optional)
+ *
+ *        {
+ *             "models": [
+ *                 {
+ *                     "name": "arm926"
+ *                 },
+ *                 {
+ *                     "name": "arm946"
+ *                 },
+ *                 {
+ *                     "name": "arm1026"
+ *                 },
+ *                 ....
+ *             ]
+ *         }
+ *
+ * Each CPU model can optionally contain architecture
+ * specific data. By convention this is provided in
+ * a key '${ARCH}info', eg i386 and x86_64 targets
+ * provide info about the CPU feature flags, and other
+ * attributes. A single CPU model entry for x86 will
+ * look like
+ *
+ *  {
+ *     "name": "n270",
+ *     "description": "Intel(R) Atom(TM) CPU N270   @ 1.60GHz",
+ *     "x86info": {
+ *         "xlevel": 2147483658,
+ *         "family": 6,
+ *         "vendor": "",
+ *         "level": 5,
+ *         "model": 28,
+ *         "stepping": 2,
+ *         "features": {
+ *             "ext_edx": [
+ *                 "lahf_lm"
+ *             ],
+ *             "edx": [
+ *                 "pbe",
+ *                 "tm",
+ *                 "ht",
+ *                 "ss",
+ *                 "sse2",
+ *                 ...
+ *             ]
+ *         }
+ *     }
+ *  }
+ *
+ * The architecture specific key can also be repeated at
+ * the top level QDict. For example to list the complete
+ * set of allowed features
+ */
+
+void do_info_cpu_types(Monitor *mon, QObject **data)
+{
+#if defined(arch_info_cpu_types)
+    arch_info_cpu_types(data);
+#else
+    *data = qobject_from_jsonf("{ 'models': [] }");
+#endif
+}
diff --git a/cpus.h b/cpus.h
index 774150a..5137866 100644
--- a/cpus.h
+++ b/cpus.h
@@ -18,5 +18,6 @@ void set_numa_modes(void);
 void set_cpu_log(const char *optarg);
 void list_cpus(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
                const char *optarg);
+void do_info_cpu_types(Monitor *mon, QObject **data);
 
 #endif
diff --git a/monitor.c b/monitor.c
index 13f70a0..2c4fb3f 100644
--- a/monitor.c
+++ b/monitor.c
@@ -46,6 +46,7 @@
 #include "migration.h"
 #include "kvm.h"
 #include "acl.h"
+#include "cpus.h"
 #include "qint.h"
 #include "qfloat.h"
 #include "qlist.h"
@@ -2466,6 +2467,14 @@ static const mon_cmd_t info_cmds[] = {
         .mhandler.info_new = do_info_devices,
     },
     {
+        .name       = "cputypes",
+        .args_type  = "",
+        .params     = "",
+        .help       = "show the registered CPU models",
+        .user_print = monitor_user_noop,
+        .mhandler.info_new = do_info_cpu_types,
+    },
+    {
         .name       = "commands",
         .args_type  = "",
         .params     = "",
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index f3d138d..3f884b7 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -28,6 +28,9 @@
 #include "cpu-defs.h"
 
 #include "softfloat.h"
+#ifdef CONFIG_SOFTMMU
+#include "qobject.h"
+#endif
 
 #define TARGET_HAS_ICE 1
 
@@ -354,6 +357,10 @@ static inline int arm_feature(CPUARMState *env, int feature)
 }
 
 void arm_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
+#ifdef CONFIG_SOFTMMU
+void arm_info_cpu_types(QObject **data);
+#define arch_info_cpu_types arm_info_cpu_types
+#endif
 
 /* Interface between CPU and Interrupt controller.  */
 void armv7m_nvic_set_pending(void *opaque, int irq);
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 63e5dc7..bba1530 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -8,6 +8,10 @@
 #include "helpers.h"
 #include "qemu-common.h"
 #include "host-utils.h"
+#ifdef CONFIG_SOFTMMU
+#include "qjson.h"
+#include "qlist.h"
+#endif
 #if !defined(CONFIG_USER_ONLY)
 #include "hw/loader.h"
 #endif
@@ -358,6 +362,23 @@ void arm_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
     }
 }
 
+#ifdef CONFIG_SOFTMMU
+void arch_info_cpu_types(QObject **data)
+{
+    QList *models = qlist_new();
+    int i;
+
+    for (i = 0; arm_cpu_names[i].name; i++) {
+	QObject *model = qobject_from_jsonf("{ 'name': %s }",
+					    arm_cpu_names[i].name);
+
+	qlist_append_obj(models, model);
+    }
+
+    *data = qobject_from_jsonf("{ 'models': %p }", models);
+}
+#endif
+
 /* return 0 if not found */
 static uint32_t cpu_arm_find_by_name(const char *name)
 {
diff --git a/target-cris/cpu.h b/target-cris/cpu.h
index 063a240..b30c10e 100644
--- a/target-cris/cpu.h
+++ b/target-cris/cpu.h
@@ -25,6 +25,9 @@
 #define CPUState struct CPUCRISState
 
 #include "cpu-defs.h"
+#ifdef CONFIG_SOFTMMU
+#include "qobject.h"
+#endif
 
 #define TARGET_HAS_ICE 1
 
@@ -267,5 +270,9 @@ static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
 
 #define cpu_list cris_cpu_list
 void cris_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
+#ifdef CONFIG_SOFTMMU
+void cris_info_cpu_types(QObject **data);
+#define arch_info_cpu_types cris_info_cpu_types
+#endif
 
 #endif
diff --git a/target-cris/translate.c b/target-cris/translate.c
index 6c1d9e0..0c326af 100644
--- a/target-cris/translate.c
+++ b/target-cris/translate.c
@@ -37,6 +37,10 @@
 #include "mmu.h"
 #include "crisv32-decode.h"
 #include "qemu-common.h"
+#ifdef CONFIG_SOFTMMU
+#include "qlist.h"
+#include "qjson.h"
+#endif
 
 #define GEN_HELPER 1
 #include "helper.h"
@@ -3468,6 +3472,24 @@ void cris_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
     }
 }
 
+#ifdef CONFIG_SOFTMMU
+void arch_info_cpu_types(QObject **data)
+{
+    QList *models = qlist_new();
+    int i;
+
+    for (i = 0; i < ARRAY_SIZE(cris_cores) ; i++) {
+	QObject *model = qobject_from_jsonf("{ 'name': %s }",
+					    cris_cores[i].name);
+
+	qlist_append_obj(models, model);
+    }
+
+    *data = qobject_from_jsonf("{ 'models': %p }", models);
+}
+#endif
+
+
 static uint32_t vr_by_name(const char *name)
 {
     unsigned int i;
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 548ab80..1fa96b8 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -20,6 +20,9 @@
 #define CPU_I386_H
 
 #include "config.h"
+#ifdef CONFIG_SOFTMMU
+#include "qobject.h"
+#endif
 
 #ifdef TARGET_X86_64
 #define TARGET_LONG_BITS 64
@@ -725,6 +728,10 @@ int cpu_x86_exec(CPUX86State *s);
 void cpu_x86_close(CPUX86State *s);
 void x86_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
                    const char *optarg);
+#ifdef CONFIG_SOFTMMU
+void x86_info_cpu_types(QObject **data);
+#define arch_info_cpu_types x86_info_cpu_types
+#endif
 void x86_cpudef_setup(void);
 
 int cpu_get_pic_interrupt(CPUX86State *s);
diff --git a/target-i386/cpuid.c b/target-i386/cpuid.c
index 7a11215..278f650 100644
--- a/target-i386/cpuid.c
+++ b/target-i386/cpuid.c
@@ -26,6 +26,12 @@
 
 #include "qemu-option.h"
 #include "qemu-config.h"
+#ifdef CONFIG_SOFTMMU
+#include "qstring.h"
+#include "qjson.h"
+#include "qint.h"
+#include "qdict.h"
+#endif
 
 /* feature flags taken from "Intel Processor Identification and the CPUID
  * Instruction" and AMD's "CPUID Specification".  In cases of disagreement
@@ -784,6 +790,79 @@ void x86_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
     }
 }
 
+
+#ifdef CONFIG_SOFTMMU
+static void qemu_caps_cpu_feature(QDict *features, const char *type,
+				  uint32_t fbits,
+				  const char **featureset)
+{
+    QList *set = qlist_new();
+    const char **p = &featureset[31];
+    char bit;
+
+    for (bit = 31; fbits ; --p, fbits &= ~(1 << bit), --bit) {
+        if (fbits & 1 << bit) {
+	    if (*p) {
+		qlist_append_obj(set, QOBJECT(qstring_from_str(*p)));
+	    } else {
+		qlist_append_obj(set, QOBJECT(qint_from_int(bit)));
+	    }
+	}
+    }
+    qdict_put_obj(features, type, QOBJECT(set));
+}
+
+void arch_info_cpu_types(QObject **data)
+{
+    QList *models = qlist_new();
+    QDict *allfeatures = qdict_new();
+    x86_def_t *def;
+    char buf[256];
+
+    for (def = x86_defs; def; def = def->next) {
+	QObject *model;
+	QObject *x86info;
+	QDict *features = qdict_new();
+
+	memcpy(buf, &def->vendor1, sizeof (def->vendor1));
+	memcpy(buf + 4, &def->vendor2, sizeof (def->vendor2));
+	memcpy(buf + 8, &def->vendor3, sizeof (def->vendor3));
+	buf[12] = '\0';
+
+	qemu_caps_cpu_feature(features, "edx", def->features, feature_name);
+	qemu_caps_cpu_feature(features, "ecx", def->ext_features, ext_feature_name);
+	qemu_caps_cpu_feature(features, "ext_ecx", def->ext2_features, ext2_feature_name);
+	qemu_caps_cpu_feature(features, "ext_edx", def->ext3_features, ext3_feature_name);
+
+	x86info = qobject_from_jsonf("{ 'family': %d, 'model': %d, 'stepping': %d,"
+				     " 'level': %d, 'xlevel': %" PRId64 ", 'vendor': %s, 'features': %p }",
+				     def->family, def->model, def->stepping,
+				     def->level, (int64_t)def->xlevel, buf, features);
+
+	model = qobject_from_jsonf("{ 'name': %s, 'description': %s, 'x86info': %p }",
+				   def->name, def->model_id, x86info);
+
+	qlist_append_obj(models, model);
+    }
+    if (kvm_enabled()) {
+	/* XXX: fill in model + x86info fields based on host */
+	QObject *model = qobject_from_jsonf("{ 'name': %s }",
+					    "host");
+
+	qlist_append_obj(models, model);
+    }
+
+    qemu_caps_cpu_feature(allfeatures, "edx", ~0, feature_name);
+    qemu_caps_cpu_feature(allfeatures, "ecx", ~0, ext_feature_name);
+    qemu_caps_cpu_feature(allfeatures, "ext_ecx", ~0, ext2_feature_name);
+    qemu_caps_cpu_feature(allfeatures, "ext_edx", ~0, ext3_feature_name);
+
+    *data = qobject_from_jsonf("{ 'models': %p, 'x86info': { 'features': %p } }",
+			       models, allfeatures);
+}
+#endif
+
+
 int cpu_x86_register (CPUX86State *env, const char *cpu_model)
 {
     x86_def_t def1, *def = &def1;
diff --git a/target-m68k/cpu.h b/target-m68k/cpu.h
index b2f37ec..ac5f6bd 100644
--- a/target-m68k/cpu.h
+++ b/target-m68k/cpu.h
@@ -28,6 +28,10 @@
 
 #include "softfloat.h"
 
+#ifdef CONFIG_SOFTMMU
+#include "qobject.h"
+#endif
+
 #define MAX_QREGS 32
 
 #define TARGET_HAS_ICE 1
@@ -200,6 +204,11 @@ static inline int m68k_feature(CPUM68KState *env, int feature)
 
 void m68k_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
 
+#ifdef CONFIG_SOFTMMU
+void m68k_info_cpu_types(QObject **data);
+#define arch_info_cpu_types m68k_info_cpu_types
+#endif
+
 void register_m68k_insns (CPUM68KState *env);
 
 #ifdef CONFIG_USER_ONLY
diff --git a/target-m68k/helper.c b/target-m68k/helper.c
index b4ebb14..9de6722 100644
--- a/target-m68k/helper.c
+++ b/target-m68k/helper.c
@@ -26,6 +26,10 @@
 #include "exec-all.h"
 #include "qemu-common.h"
 #include "gdbstub.h"
+#ifdef CONFIG_SOFTMMU
+#include "qlist.h"
+#include "qjson.h"
+#endif
 
 #include "helpers.h"
 
@@ -62,6 +66,25 @@ void m68k_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
     }
 }
 
+
+#ifdef CONFIG_SOFTMMU
+void arch_info_cpu_types(QObject **data)
+{
+    QList *models = qlist_new();
+    int i;
+
+    for (i = 0; m68k_cpu_defs[i].name; i++) {
+	QObject *model = qobject_from_jsonf("{ 'name': %s }",
+					    m68k_cpu_defs[i].name);
+
+	qlist_append_obj(models, model);
+    }
+
+    *data = qobject_from_jsonf("{ 'models': %p }", models);
+}
+#endif
+
+
 static int fpu_gdb_get_reg(CPUState *env, uint8_t *mem_buf, int n)
 {
     if (n < 8) {
diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index 7285636..02bcadb 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -11,6 +11,9 @@
 #include "mips-defs.h"
 #include "cpu-defs.h"
 #include "softfloat.h"
+#ifdef CONFIG_SOFTMMU
+#include "qobject.h"
+#endif
 
 // uint_fast8_t and uint_fast16_t not in <sys/int_types.h>
 // XXX: move that elsewhere
@@ -496,6 +499,10 @@ void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
 #endif
 
 void mips_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
+#ifdef CONFIG_SOFTMMU
+void mips_info_cpu_types(QObject **data);
+#define arch_info_cpu_types mips_info_cpu_types
+#endif
 
 #define cpu_init cpu_mips_init
 #define cpu_exec cpu_mips_exec
diff --git a/target-mips/translate.c b/target-mips/translate.c
index c95ecb1..0d9fd80 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -35,6 +35,10 @@
 #include "helper.h"
 #define GEN_HELPER 1
 #include "helper.h"
+#ifdef CONFIG_SOFTMMU
+#include "qlist.h"
+#include "qjson.h"
+#endif
 
 //#define MIPS_DEBUG_DISAS
 //#define MIPS_DEBUG_SIGN_EXTENSIONS
diff --git a/target-mips/translate_init.c b/target-mips/translate_init.c
index b79ed56..72ee283 100644
--- a/target-mips/translate_init.c
+++ b/target-mips/translate_init.c
@@ -479,6 +479,25 @@ void mips_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
     }
 }
 
+
+#ifdef CONFIG_SOFTMMU
+void arch_info_cpu_types(QObject **data)
+{
+    QList *models = qlist_new();
+    int i;
+
+    for (i = 0; i < ARRAY_SIZE(mips_defs); i++) {
+	QObject *model = qobject_from_jsonf("{ 'name': %s }",
+					    mips_defs[i].name);
+
+	qlist_append_obj(models, model);
+    }
+
+    *data = qobject_from_jsonf("{ 'models': %p }", models);
+}
+#endif
+
+
 #ifndef CONFIG_USER_ONLY
 static void no_mmu_init (CPUMIPSState *env, const mips_def_t *def)
 {
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 2ad4486..69e0686 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -21,6 +21,9 @@
 
 #include "config.h"
 #include <inttypes.h>
+#ifdef CONFIG_SOFTMMU
+#include "qobject.h"
+#endif
 
 //#define PPC_EMULATE_32BITS_HYPV
 
@@ -758,6 +761,10 @@ void ppc_store_sr (CPUPPCState *env, int srnum, target_ulong value);
 void ppc_store_msr (CPUPPCState *env, target_ulong value);
 
 void ppc_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
+#ifdef CONFIG_SOFTMMU
+void ppc_info_cpu_types(QObject **data);
+#define arch_info_cpu_types ppc_info_cpu_types
+#endif
 
 const ppc_def_t *cpu_ppc_find_by_name (const char *name);
 int cpu_ppc_register_internal (CPUPPCState *env, const ppc_def_t *def);
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 66e1c0d..8e6c9e3 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -28,6 +28,10 @@
 #include "tcg-op.h"
 #include "qemu-common.h"
 #include "host-utils.h"
+#ifdef CONFIG_SOFTMMU
+#include "qlist.h"
+#include "qjson.h"
+#endif
 
 #include "helper.h"
 #define GEN_HELPER 1
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index e8eadf4..4b4097a 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -9764,3 +9764,20 @@ void ppc_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
                        ppc_defs[i].name, ppc_defs[i].pvr);
     }
 }
+
+#ifdef CONFIG_SOFTMMU
+void arch_info_cpu_types(QObject **data)
+{
+    QList *models = qlist_new();
+    int i;
+
+    for (i = 0; i < ARRAY_SIZE(ppc_defs); i++) {
+	QObject *model = qobject_from_jsonf("{ 'name': %s }",
+					    ppc_defs[i].name);
+
+	qlist_append_obj(models, model);
+    }
+
+    *data = qobject_from_jsonf("{ 'models': %p }", models);
+}
+#endif
diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h
index f8b1680..a0a6ed5 100644
--- a/target-sh4/cpu.h
+++ b/target-sh4/cpu.h
@@ -20,6 +20,9 @@
 #define _CPU_SH4_H
 
 #include "config.h"
+#ifdef CONFIG_SOFTMMU
+#include "qobject.h"
+#endif
 
 #define TARGET_LONG_BITS 32
 #define TARGET_HAS_ICE 1
@@ -169,6 +172,11 @@ int cpu_sh4_handle_mmu_fault(CPUSH4State * env, target_ulong address, int rw,
 void do_interrupt(CPUSH4State * env);
 
 void sh4_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
+#ifdef CONFIG_SOFTMMU
+void sh4_info_cpu_types(QObject **data);
+#define arch_info_cpu_types sh4_info_cpu_types
+#endif
+
 #if !defined(CONFIG_USER_ONLY)
 void cpu_sh4_invalidate_tlb(CPUSH4State *s);
 void cpu_sh4_write_mmaped_utlb_addr(CPUSH4State *s, target_phys_addr_t addr,
diff --git a/target-sh4/translate.c b/target-sh4/translate.c
index d0d6c00..7d94ad2 100644
--- a/target-sh4/translate.c
+++ b/target-sh4/translate.c
@@ -31,6 +31,10 @@
 #include "disas.h"
 #include "tcg-op.h"
 #include "qemu-common.h"
+#ifdef CONFIG_SOFTMMU
+#include "qlist.h"
+#include "qjson.h"
+#endif
 
 #include "helper.h"
 #define GEN_HELPER 1
@@ -265,6 +269,25 @@ void sh4_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
 	(*cpu_fprintf)(f, "%s\n", sh4_defs[i].name);
 }
 
+
+#ifdef CONFIG_SOFTMMU
+void arch_info_cpu_types(QObject **data)
+{
+    QList *models = qlist_new();
+    int i;
+
+    for (i = 0; i < ARRAY_SIZE(sh4_defs); i++) {
+	QObject *model = qobject_from_jsonf("{ 'name': %s }",
+					    sh4_defs[i].name);
+
+	qlist_append_obj(models, model);
+    }
+
+    *data = qobject_from_jsonf("{ 'models': %p }", models);
+}
+#endif
+
+
 static void cpu_sh4_register(CPUSH4State *env, const sh4_def_t *def)
 {
     env->pvr = def->pvr;
diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
index 8f0484b..7b433ed 100644
--- a/target-sparc/cpu.h
+++ b/target-sparc/cpu.h
@@ -27,6 +27,10 @@
 
 #include "softfloat.h"
 
+#ifdef CONFIG_SOFTMMU
+#include "qobject.h"
+#endif
+
 #define TARGET_HAS_ICE 1
 
 #if !defined(TARGET_SPARC64)
@@ -444,6 +448,11 @@ CPUSPARCState *cpu_sparc_init(const char *cpu_model);
 void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu);
 void sparc_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt,
                                                  ...));
+#ifdef CONFIG_SOFTMMU
+void sparc_info_cpu_types(QObject **data);
+#define arch_info_cpu_types sparc_info_cpu_types
+#endif
+
 void cpu_lock(void);
 void cpu_unlock(void);
 int cpu_sparc_handle_mmu_fault(CPUSPARCState *env1, target_ulong address, int rw,
diff --git a/target-sparc/helper.c b/target-sparc/helper.c
index aa1fd63..15b4cc2 100644
--- a/target-sparc/helper.c
+++ b/target-sparc/helper.c
@@ -26,6 +26,11 @@
 #include "cpu.h"
 #include "exec-all.h"
 #include "qemu-common.h"
+#ifdef CONFIG_SOFTMMU
+#include "qlist.h"
+#include "qdict.h"
+#include "qjson.h"
+#endif
 
 //#define DEBUG_MMU
 //#define DEBUG_FEATURES
@@ -1479,6 +1484,61 @@ void sparc_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
                    "fpu_version mmu_version nwindows\n");
 }
 
+
+#ifdef CONFIG_SOFTMMU
+static void cpu_type_feature_info(QDict *info,
+				  const char *name,
+				  uint32_t bits)
+{
+    QList *features = qlist_new();
+    unsigned int i;
+
+    qdict_put_obj(info, name, QOBJECT(features));
+
+    for (i = 0; i < ARRAY_SIZE(feature_name); i++) {
+        if (feature_name[i] && (bits & (1 << i))) {
+	    qlist_append_obj(features, QOBJECT(qstring_from_str(feature_name[i])));
+        }
+    }
+}
+
+void arch_info_cpu_types(QObject **data)
+{
+    QList *models = qlist_new();
+    QDict *allsparcinfo = qdict_new();
+    int i;
+
+    for (i = 0; i < ARRAY_SIZE(sparc_defs); i++) {
+	QObject *model;
+	QDict *sparcinfo = qdict_new();
+
+	cpu_type_feature_info(sparcinfo, "features",
+			      sparc_defs[i].features);
+
+	model = qobject_from_jsonf("{ 'name': %s, 'sparcinfo': %p, "
+				   " 'iu_version': %" PRId64 ", "
+				   " 'fpu_version': %" PRId64 ", "
+				   " 'mmu_version': %" PRId64 ", "
+				   " 'nwindows': %d }",
+				   sparc_defs[i].name, sparcinfo,
+				   (uint64_t)sparc_defs[i].iu_version,
+				   (uint64_t)sparc_defs[i].fpu_version,
+				   (uint64_t)sparc_defs[i].mmu_version,
+				   sparc_defs[i].nwindows);
+
+	qlist_append_obj(models, model);
+    }
+
+    cpu_type_feature_info(allsparcinfo, "features",
+			  ~0);
+    cpu_type_feature_info(allsparcinfo, "deffeatures",
+			  CPU_DEFAULT_FEATURES);
+
+    *data = qobject_from_jsonf("{ 'models': %p, 'sparcinfo': %p }",
+			       models, allsparcinfo);
+}
+#endif
+
 static void cpu_print_cc(FILE *f,
                          int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
                          uint32_t cc)
-- 
1.6.6.1

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [Qemu-devel] [PATCH 13/19] Add a query-target command to QMP
  2010-06-07 14:42 [Qemu-devel] [PATCH 00/19] RFC: Reporting QEMU binary capabilities Daniel P. Berrange
                   ` (11 preceding siblings ...)
  2010-06-07 14:42 ` [Qemu-devel] [PATCH 12/19] Add a query-cputypes " Daniel P. Berrange
@ 2010-06-07 14:42 ` Daniel P. Berrange
  2010-06-07 15:43   ` [Qemu-devel] " Paolo Bonzini
  2010-06-07 14:42 ` [Qemu-devel] [PATCH 14/19] Add a query-argv " Daniel P. Berrange
                   ` (8 subsequent siblings)
  21 siblings, 1 reply; 62+ messages in thread
From: Daniel P. Berrange @ 2010-06-07 14:42 UTC (permalink / raw)
  To: qemu-devel

Add a command to QMP to provide information about the QEMU binary
target being emulated.  This replaces the need to guess the architecture
and wordsize based on the 'qemu-system-XXXX' suffix. It also declares
what CPU execution engines are available in the binary (tcg, kvm, xen,
etc)

The data format looks like this

    {
        "arch": "i386",
        "wordsize": 32,
        "engines": [
            {
                "name": "tcg"
            },
            {
                "name": "kvm"
            },
            {
                "name": "xen"
            }
        ]
    }

There is no support for the legacy readline monitor

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
---
 hw/boards.h |    1 +
 monitor.c   |   61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 62 insertions(+), 0 deletions(-)

diff --git a/hw/boards.h b/hw/boards.h
index 2f6003d..d335da2 100644
--- a/hw/boards.h
+++ b/hw/boards.h
@@ -33,6 +33,7 @@ typedef struct QEMUMachine {
 
 int qemu_register_machine(QEMUMachine *m);
 void do_info_machines(Monitor *mon, QObject **data);
+void do_info_target(Monitor *mon, QObject **data);
 
 extern QEMUMachine *current_machine;
 
diff --git a/monitor.c b/monitor.c
index 2c4fb3f..d55b27b 100644
--- a/monitor.c
+++ b/monitor.c
@@ -978,6 +978,59 @@ static void do_info_cpu_stats(Monitor *mon)
 }
 #endif
 
+
+/**
+ * do_info_target()
+ *
+ * Provide basic information about the binary target.
+ * The QDict contains the keys
+ *
+ *  - 'arch': the name of the architecture
+ *  - 'wordsize': the wordsize of the architecture
+ *  - 'engines': a QList showing the modes of CPU execution (tcg, kvm, xen, etc)
+ *
+ * Each entry in the 'engines' QList is a QDict containing
+ * a single key
+ *
+ *  - 'name': name of the CPU execution engine
+ *
+ * Example:
+ *
+ * {
+ *   "arch": "i386",
+ *   "wordsize": 32,
+ *   "engines": [
+ *     {
+ *       "name": "tcg"
+ *     },
+ *     {
+ *       "name": "kvm"
+ *     },
+ *     {
+ *       "name": "xen"
+ *     }
+ *   ]
+ * }
+ * 
+ */
+void do_info_target(Monitor *mon, QObject **data)
+{
+    QList *engines = qlist_new();
+
+    qlist_append_obj(engines, qobject_from_jsonf("{ 'name': 'tcg' }"));
+#ifdef CONFIG_KVM
+    qlist_append_obj(engines, qobject_from_jsonf("{ 'name': 'kvm' }"));
+#endif
+#ifdef CONFIG_XEN
+    qlist_append_obj(engines, qobject_from_jsonf("{ 'name': 'xen' }"));
+#endif
+
+    /* XXX 'engines' isn't a very good name */
+    *data = qobject_from_jsonf("{ 'arch': %s, 'wordsize': %d, 'engines': %p }",
+			       TARGET_ARCH, TARGET_PHYS_ADDR_BITS, engines);
+}
+
+
 /**
  * do_quit(): Quit QEMU execution
  */
@@ -2475,6 +2528,14 @@ static const mon_cmd_t info_cmds[] = {
         .mhandler.info_new = do_info_cpu_types,
     },
     {
+        .name       = "target",
+        .args_type  = "",
+        .params     = "",
+        .help       = "show the target arch capabilities",
+        .user_print = monitor_user_noop,
+        .mhandler.info_new = do_info_target,
+    },
+    {
         .name       = "commands",
         .args_type  = "",
         .params     = "",
-- 
1.6.6.1

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [Qemu-devel] [PATCH 14/19] Add a query-argv command to QMP
  2010-06-07 14:42 [Qemu-devel] [PATCH 00/19] RFC: Reporting QEMU binary capabilities Daniel P. Berrange
                   ` (12 preceding siblings ...)
  2010-06-07 14:42 ` [Qemu-devel] [PATCH 13/19] Add a query-target " Daniel P. Berrange
@ 2010-06-07 14:42 ` Daniel P. Berrange
  2010-06-07 15:01   ` Anthony Liguori
  2010-06-07 14:42 ` [Qemu-devel] [PATCH 15/19] Expand query-argv to include help string Daniel P. Berrange
                   ` (7 subsequent siblings)
  21 siblings, 1 reply; 62+ messages in thread
From: Daniel P. Berrange @ 2010-06-07 14:42 UTC (permalink / raw)
  To: qemu-devel

Add a new QMP command called 'query-argv' to information about the command
line arguments supported by the QEMU binary. This is intended to remove the
need for apps to parse '-help' output.

    [
        {
            "name": "help",
        },
        {
            "name": "M",
            "parameters": [
                {
                }
            ]
        },
    ]

NB, command line args which accept parameters have a non-zero length
parameters list. The element of the list is currently empty though
since the parameter names are not easily available in QEMU source in
a format suitable for exposing as a stable ABI.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
---
 monitor.c |    8 ++++++
 monitor.h |    2 +
 vl.c      |   74 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 84 insertions(+), 0 deletions(-)

diff --git a/monitor.c b/monitor.c
index d55b27b..1c5157d 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2544,6 +2544,14 @@ static const mon_cmd_t info_cmds[] = {
         .mhandler.info_new = do_info_commands,
     },
     {
+        .name       = "argv",
+        .args_type  = "",
+        .params     = "",
+        .help       = "list QEMU command line argv",
+        .user_print = monitor_user_noop,
+        .mhandler.info_new = do_info_argv,
+    },
+    {
         .name       = "network",
         .args_type  = "",
         .params     = "",
diff --git a/monitor.h b/monitor.h
index ea15469..46b7a0e 100644
--- a/monitor.h
+++ b/monitor.h
@@ -55,4 +55,6 @@ typedef void (MonitorCompletion)(void *opaque, QObject *ret_data);
 
 void monitor_set_error(Monitor *mon, QError *qerror);
 
+void do_info_argv(Monitor *mon, QObject **data);
+
 #endif /* !MONITOR_H */
diff --git a/vl.c b/vl.c
index 8043fac..a76c673 100644
--- a/vl.c
+++ b/vl.c
@@ -1987,6 +1987,80 @@ static void version(void)
     printf("QEMU emulator version " QEMU_VERSION QEMU_PKGVERSION ", Copyright (c) 2003-2008 Fabrice Bellard\n");
 }
 
+
+/**
+ * do_info_argv():
+ *
+ * Provide info about the command line arguments
+ * supported by the QEMU binary. The returned
+ * data is a QList with one QDict entry for  each named
+ * argument. Each entry's QDict contains the following
+ * keys
+ *
+ *  'name': the command argument name (eg 'drive' for -drive arg)
+ *  'parameters': list of parameter values (if any)
+ *
+ * NB, the 'parameters' key is omitted completely if
+ * the argument has no associated value. 
+ *
+ * XXXX details of the parameters are not yet filled in
+ * since this info is not easily available
+ *
+ *     [
+ *         {
+ *             "name": "help",
+ *             "parameters": [
+ *             ]
+ *         },
+ *         {
+ *             "name": "M",
+ *             "parameters": [
+ *                 {
+ *                 }
+ *             ]
+ *         },
+ *     ]
+ */
+void do_info_argv(Monitor *mon, QObject **data)
+{
+    QList *args = qlist_new();
+    struct {
+       const char *name;
+       int has_arg;
+       const char *help;
+    } options_help[] = {
+#define DEF(option, opt_arg, opt_enum, opt_help, arch_mask)     \
+        { option, opt_arg },
+#define DEFHEADING(text)
+#define HAS_ARG 1
+#include "qemu-options.h"
+#undef DEF
+#undef DEFHEADING
+#undef HAS_ARG
+       { NULL, 0 },
+    };
+    int i;
+
+    for (i = 0 ; options_help[i].name != NULL ; i++) {
+	QObject *opt;
+
+	if (options_help[i].has_arg) {
+	    /* XXX actually fill in the parameter details */
+	    opt = qobject_from_jsonf("{ 'name': %s, 'parameters': [] }",
+				     options_help[i].name);
+	} else {
+	    opt = qobject_from_jsonf("{ 'name': %s }",
+				     options_help[i].name);
+	}
+
+
+	qlist_append_obj(args, opt);
+    }
+
+    *data = QOBJECT(args);
+}
+
+
 static void help(int exitcode)
 {
     const char *options_help =
-- 
1.6.6.1

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [Qemu-devel] [PATCH 15/19] Expand query-argv to include help string
  2010-06-07 14:42 [Qemu-devel] [PATCH 00/19] RFC: Reporting QEMU binary capabilities Daniel P. Berrange
                   ` (13 preceding siblings ...)
  2010-06-07 14:42 ` [Qemu-devel] [PATCH 14/19] Add a query-argv " Daniel P. Berrange
@ 2010-06-07 14:42 ` Daniel P. Berrange
  2010-06-07 14:42 ` [Qemu-devel] [PATCH 16/19] Add a query-netdev command to QMP Daniel P. Berrange
                   ` (6 subsequent siblings)
  21 siblings, 0 replies; 62+ messages in thread
From: Daniel P. Berrange @ 2010-06-07 14:42 UTC (permalink / raw)
  To: qemu-devel

This expands the query-argv data format to include the help
string for each argument. This is not really very desirable
since the help strings are not in a predictable format for apps
to use. Ideally the full structured details about each argument
parameter would be included instead. This makes the data format
look like

    [
        {
            "name": "help",
            "help": "-h or -help     display this help and exit\n",
        },
        {
            "name": "M",
            "help": "-M machine      select emulated machine (-M ? for list)\n",
            "parameters": [
            ]
        },
    ]

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
---
 vl.c |   15 ++++++++-------
 1 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/vl.c b/vl.c
index a76c673..35d2b51 100644
--- a/vl.c
+++ b/vl.c
@@ -2030,14 +2030,14 @@ void do_info_argv(Monitor *mon, QObject **data)
        const char *help;
     } options_help[] = {
 #define DEF(option, opt_arg, opt_enum, opt_help, arch_mask)     \
-        { option, opt_arg },
+        { option, opt_arg, opt_help },
 #define DEFHEADING(text)
 #define HAS_ARG 1
 #include "qemu-options.h"
 #undef DEF
 #undef DEFHEADING
 #undef HAS_ARG
-       { NULL, 0 },
+	{ NULL, 0, NULL },
     };
     int i;
 
@@ -2046,14 +2046,15 @@ void do_info_argv(Monitor *mon, QObject **data)
 
 	if (options_help[i].has_arg) {
 	    /* XXX actually fill in the parameter details */
-	    opt = qobject_from_jsonf("{ 'name': %s, 'parameters': [] }",
-				     options_help[i].name);
+	    opt = qobject_from_jsonf("{ 'name': %s, 'help': %s, 'parameters': [] }",
+				     options_help[i].name,
+				     options_help[i].help);
 	} else {
-	    opt = qobject_from_jsonf("{ 'name': %s }",
-				     options_help[i].name);
+	    opt = qobject_from_jsonf("{ 'name': %s, 'help': %s }",
+				     options_help[i].name,
+				     options_help[i].help);
 	}
 
-
 	qlist_append_obj(args, opt);
     }
 
-- 
1.6.6.1

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [Qemu-devel] [PATCH 16/19] Add a query-netdev command to QMP
  2010-06-07 14:42 [Qemu-devel] [PATCH 00/19] RFC: Reporting QEMU binary capabilities Daniel P. Berrange
                   ` (14 preceding siblings ...)
  2010-06-07 14:42 ` [Qemu-devel] [PATCH 15/19] Expand query-argv to include help string Daniel P. Berrange
@ 2010-06-07 14:42 ` Daniel P. Berrange
  2010-06-07 15:15   ` Anthony Liguori
  2010-06-07 19:13   ` Miguel Di Ciurcio Filho
  2010-06-07 14:42 ` [Qemu-devel] [PATCH 17/19] Add a query-config " Daniel P. Berrange
                   ` (5 subsequent siblings)
  21 siblings, 2 replies; 62+ messages in thread
From: Daniel P. Berrange @ 2010-06-07 14:42 UTC (permalink / raw)
  To: qemu-devel

This adds a new QMP command called query-netdev to provide information
about the available netdev backends in the QEMU binary. There is no
existing '-netdev ?' support, but if there was, this would obsolete it

The data format looks like

    [
        {
            "name": "user",
            "props": [
                {
                    "name": "type",
                    "help": "net client type (nic, tap etc.)",
                    "type": "string"
                },
                {
                    "name": "name",
                    "help": "identifier for monitor commands",
                    "type": "string"
                },
                {
                    "name": "hostname",
                    "help": "client hostname reported by the builtin DHCP server",
                    "type": "string"
                },
                ...
            ]
        }
        {
            "name": "tap",
            "props": [
                {
                    "name": "type",
                    "help": "net client type (nic, tap etc.)",
                    "type": "string"
                },
                {
                    "name": "ifname",
                    "help": "interface name",
                    "type": "string"
                },
                ...
            ]
        }
        ...
    ]

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
---
 monitor.c     |    8 ++++++++
 net.c         |   49 +++++++++++++++++++++++++++++++++++++++++++++++++
 net.h         |    2 ++
 qemu-option.c |    4 ++++
 qemu-option.h |    4 ++++
 5 files changed, 67 insertions(+), 0 deletions(-)

diff --git a/monitor.c b/monitor.c
index 1c5157d..19f42f3 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2552,6 +2552,14 @@ static const mon_cmd_t info_cmds[] = {
         .mhandler.info_new = do_info_argv,
     },
     {
+        .name       = "netdev",
+        .args_type  = "",
+        .params     = "",
+        .help       = "list valid netdev backend types",
+        .user_print = monitor_user_noop,
+        .mhandler.info_new = do_info_netdev,
+    },
+    {
         .name       = "network",
         .args_type  = "",
         .params     = "",
diff --git a/net.c b/net.c
index 5349001..90929d4 100644
--- a/net.c
+++ b/net.c
@@ -36,6 +36,8 @@
 #include "qemu-common.h"
 #include "qemu_socket.h"
 #include "hw/qdev.h"
+#include "qjson.h"
+#include "qlist.h"
 
 static QTAILQ_HEAD(, VLANState) vlans;
 static QTAILQ_HEAD(, VLANClientState) non_vlan_clients;
@@ -1080,6 +1082,53 @@ static const struct {
 };
 verify(ARRAY_SIZE(net_client_types) == NET_CLIENT_LAST);
 
+
+void do_info_netdev(Monitor *mon, QObject **data)
+{
+    QList *backends = qlist_new();
+    int i, j;
+
+    for (i = 0; i < ARRAY_SIZE(net_client_types) ; i++) {
+	QObject *backend;
+	QList *props = qlist_new();
+
+	if (i == NET_CLIENT_NIC ||
+	    i == NET_CLIENT_DUMP||
+	    i == NET_CLIENT_NONE)
+	    continue;
+
+	for (j = 0 ; net_client_types[i].desc[j].name != NULL ; j++) {
+	    const QemuOptDesc *desc = net_client_types[i].desc + j;
+	    QObject *prop;
+
+	    if (strcmp(desc->name, "vlan") == 0)
+		continue;
+
+	    if (desc->help) {
+		prop = qobject_from_jsonf("{ 'name': %s, 'type': %s, 'help': %s }",
+					  desc->name,
+					  qemu_opt_type_to_string(desc->type),
+					  desc->help);
+	    } else {
+		prop = qobject_from_jsonf("{ 'name': %s, 'type': %s }",
+					  desc->name,
+					  qemu_opt_type_to_string(desc->type));
+	    }
+
+	    qlist_append_obj(props, prop);
+	}
+
+	backend = qobject_from_jsonf("{ 'name': %s, 'props': %p }",
+				     qemu_net_type_to_string(i),
+				     props);
+
+	qlist_append_obj(backends, backend);
+    }
+
+    *data = qobject_from_jsonf("{ 'backends': %p }", backends);
+}
+
+
 int net_client_init(Monitor *mon, QemuOpts *opts, int is_netdev)
 {
     const char *name;
diff --git a/net.h b/net.h
index b83f615..9c0e385 100644
--- a/net.h
+++ b/net.h
@@ -167,6 +167,8 @@ void net_host_device_remove(Monitor *mon, const QDict *qdict);
 int do_netdev_add(Monitor *mon, const QDict *qdict, QObject **ret_data);
 int do_netdev_del(Monitor *mon, const QDict *qdict, QObject **ret_data);
 
+void do_info_netdev(Monitor *mon, QObject **data);
+
 #define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup"
 #define DEFAULT_NETWORK_DOWN_SCRIPT "/etc/qemu-ifdown"
 #ifdef __sun__
diff --git a/qemu-option.c b/qemu-option.c
index bb9cc43..f132a9b 100644
--- a/qemu-option.c
+++ b/qemu-option.c
@@ -32,6 +32,10 @@
 #include "qemu-option.h"
 #include "qerror.h"
 
+QEMU_ENUM_IMPL(qemu_opt_type, QEMU_OPT_LAST,
+	       "string", "bool", "number",
+	       "size", "enum");
+
 /*
  * Extracts the name of an option from the parameter string (p points at the
  * first byte of the option name)
diff --git a/qemu-option.h b/qemu-option.h
index 3540a9b..9382cc3 100644
--- a/qemu-option.h
+++ b/qemu-option.h
@@ -28,6 +28,7 @@
 
 #include <stdint.h>
 #include "qemu-queue.h"
+#include "qemu-enum.h"
 #include "qdict.h"
 
 enum QEMUOptionParType {
@@ -90,7 +91,10 @@ enum QemuOptType {
     QEMU_OPT_NUMBER,      /* simple number                                        */
     QEMU_OPT_SIZE,        /* size, accepts (K)ilo, (M)ega, (G)iga, (T)era postfix */
     QEMU_OPT_ENUM,        /* int, from user string validated against an enum      */
+
+    QEMU_OPT_LAST,
 };
+QEMU_ENUM_DECL(qemu_opt_type);
 
 typedef struct QemuOptDesc {
     const char *name;
-- 
1.6.6.1

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [Qemu-devel] [PATCH 17/19] Add a query-config command to QMP
  2010-06-07 14:42 [Qemu-devel] [PATCH 00/19] RFC: Reporting QEMU binary capabilities Daniel P. Berrange
                   ` (15 preceding siblings ...)
  2010-06-07 14:42 ` [Qemu-devel] [PATCH 16/19] Add a query-netdev command to QMP Daniel P. Berrange
@ 2010-06-07 14:42 ` Daniel P. Berrange
  2010-06-26  7:34   ` Markus Armbruster
  2010-06-07 14:42 ` [Qemu-devel] [PATCH 18/19] Add option to turn on JSON pretty printing in monitor Daniel P. Berrange
                   ` (4 subsequent siblings)
  21 siblings, 1 reply; 62+ messages in thread
From: Daniel P. Berrange @ 2010-06-07 14:42 UTC (permalink / raw)
  To: qemu-devel

Add a new command to QMP called 'query-config' that provides
information about the allowed configuration file entries for
the binary.

The data format looks like

    [
        {
            "name": "drive",
            "properties": [
                {
                    "name": "bus",
                    "validate": {
                    },
                    "help": "bus number",
                    "type": "number"
                },
                {
                    "name": "unit",
                    "validate": {
                    },
                    "help": "unit number (i.e. lun for scsi)",
                    "type": "number"
                },
                {
                    "name": "if",
                    "validate": {
                        "values": [
                            "none",
                            "ide",
                            "scsi",
                            "floppy",
                            "pflash",
                            "mtd",
                            "sd",
                            "virtio",
                            "xen"
                        ]
                    },
                    "help": "interface (ide, scsi, sd, mtd, floppy, pflash, virtio)",
                    "type": "enum"
                },
                {
          ..........
       }
   ]

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
---
 monitor.c     |    8 ++++
 qemu-config.c |  127 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 qemu-config.h |    2 +
 3 files changed, 136 insertions(+), 1 deletions(-)

diff --git a/monitor.c b/monitor.c
index 19f42f3..39f8150 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2560,6 +2560,14 @@ static const mon_cmd_t info_cmds[] = {
         .mhandler.info_new = do_info_netdev,
     },
     {
+        .name       = "config",
+        .args_type  = "",
+        .params     = "",
+        .help       = "list valid config file parameters",
+        .user_print = monitor_user_noop,
+        .mhandler.info_new = do_info_config,
+    },
+    {
         .name       = "network",
         .args_type  = "",
         .params     = "",
diff --git a/qemu-config.c b/qemu-config.c
index 75cddc1..925bd04 100644
--- a/qemu-config.c
+++ b/qemu-config.c
@@ -5,6 +5,9 @@
 #include "sysemu.h"
 #include "hw/qdev.h"
 #include "block.h"
+#include "qjson.h"
+#include "qlist.h"
+
 
 QemuOptsList qemu_drive_opts = {
     .name = "drive",
@@ -97,7 +100,7 @@ QemuOptsList qemu_drive_opts = {
                     .to_string = bdrv_aio_to_string,
                     .to_string_list = bdrv_aio_to_string_list,
                     .from_string = bdrv_aio_from_string,
-                    .last = BDRV_CACHE_LAST
+                    .last = BDRV_AIO_LAST
                 },
             },
         },{
@@ -612,3 +615,125 @@ int qemu_read_config_file(const char *filename)
         return -EINVAL;
     }
 }
+
+
+/*
+ * do_info_config():
+ *
+ * Return information about allowed configuration file
+ * parameters and their data types.
+ *
+ * At the top level is a QList containing one QDict entry
+ * for each top level config group. The QDict contains
+ * keys for
+ *
+ *  'name': name of the config group
+ *  'properties': QList of a config properties
+ *
+ * Each entry in the properties QList is another QDict
+ * containing keys
+ *
+ *  'name': name of the config parameter
+ *  'help': a short help string (optional)
+ *  'type': data type of the parameter (string, bool, number, size, enum)
+ *  'validate': a QDict of data validation rules
+ *
+ * The 'validate' key is only used for options for type='enum' and
+ * in this case describes the valid strings for the enumeration
+ *
+ * Example snippet of data:
+ *
+ * [
+ *   {
+ *     "name": "drive",
+ *     "properties": [
+ *         {
+ *             "name": "bus",
+ *             "validate": {
+ *             },
+ *             "help": "bus number",
+ *             "type": "number"
+ *         },
+ *         {
+ *             "name": "unit",
+ *             "validate": {
+ *             },
+ *             "help": "unit number (i.e. lun for scsi)",
+ *             "type": "number"
+ *         },
+ *         {
+ *             "name": "if",
+ *             "validate": {
+ *                 "values": [
+ *                     "none",
+ *                     "ide",
+ *                     "scsi",
+ *                     "floppy",
+ *                     "pflash",
+ *                     "mtd",
+ *                     "sd",
+ *                     "virtio",
+ *                     "xen"
+ *                 ]
+ *             },
+ *             "help": "interface (ide, scsi, sd, mtd, floppy, pflash, virtio)",
+ *             "type": "enum"
+ *         },
+ *      ]
+ *   }
+ *   ...
+ * ]
+ */
+void do_info_config(Monitor *mon, QObject **ret_data)
+{
+    QList *config = qlist_new();
+    int i, j, k;
+
+    for (i = 0 ; vm_config_groups[i] != NULL ; i++) {
+	QemuOptsList *grp = vm_config_groups[i];
+	QList *props = qlist_new();
+	QObject *entry;
+
+	for (j = 0 ; grp->desc[j].name != NULL ; j++) {
+	    QemuOptDesc *desc = &grp->desc[j];
+	    QObject *validate  = QOBJECT(qlist_new());
+	    QObject *prop;
+
+	    if (desc->type == QEMU_OPT_ENUM) {
+		QList *valid = qlist_new();
+
+		for (k = 0 ; k < desc->validate.optEnum.last ; k++) {
+		    fprintf(stderr, "name %s %d %d\n", grp->desc[j].name, k, desc->validate.optEnum.last);
+		    const char *str = (desc->validate.optEnum.to_string)(k);
+		    qlist_append_obj(valid, QOBJECT(qstring_from_str(str)));
+		}
+
+		validate = qobject_from_jsonf("{ 'values': %p }", valid);
+	    } else {
+		validate = qobject_from_jsonf("{}");
+	    }
+
+	    if (desc->help) {
+		prop = qobject_from_jsonf("{ 'name': %s, 'type': %s, 'help': %s, 'validate': %p }",
+					  desc->name,
+					  qemu_opt_type_to_string(desc->type),
+					  desc->help,
+					  validate);
+	    } else {
+		prop = qobject_from_jsonf("{ 'name': %s, 'type': %s, 'validate': %p }",
+					  desc->name,
+					  qemu_opt_type_to_string(desc->type),
+					  validate);
+	    }
+
+	    qlist_append_obj(props, prop);
+	}
+
+	entry = qobject_from_jsonf("{ 'name': %s, 'properties': %p }",
+				   grp->name, props);
+
+	qlist_append_obj(config, entry);
+    }
+
+    *ret_data = QOBJECT(config);
+}
diff --git a/qemu-config.h b/qemu-config.h
index dca69d4..b87e8fc 100644
--- a/qemu-config.h
+++ b/qemu-config.h
@@ -25,4 +25,6 @@ int qemu_config_parse(FILE *fp, QemuOptsList **lists, const char *fname);
 
 int qemu_read_config_file(const char *filename);
 
+void do_info_config(Monitor *mon, QObject **ret_data);
+
 #endif /* QEMU_CONFIG_H */
-- 
1.6.6.1

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [Qemu-devel] [PATCH 18/19] Add option to turn on JSON pretty printing in monitor
  2010-06-07 14:42 [Qemu-devel] [PATCH 00/19] RFC: Reporting QEMU binary capabilities Daniel P. Berrange
                   ` (16 preceding siblings ...)
  2010-06-07 14:42 ` [Qemu-devel] [PATCH 17/19] Add a query-config " Daniel P. Berrange
@ 2010-06-07 14:42 ` Daniel P. Berrange
  2010-06-07 14:42 ` [Qemu-devel] [PATCH 19/19] Add a -capabilities argument to allow easy query for static QEMU info Daniel P. Berrange
                   ` (3 subsequent siblings)
  21 siblings, 0 replies; 62+ messages in thread
From: Daniel P. Berrange @ 2010-06-07 14:42 UTC (permalink / raw)
  To: qemu-devel

Expaned '-mon' arg to allow a 'pretty=on' flag. This makes the
monitor pretty print its replies to easy human debugging / reading

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
---
 monitor.c     |    5 ++++-
 monitor.h     |    1 +
 qemu-config.c |    3 +++
 vl.c          |    3 +++
 4 files changed, 11 insertions(+), 1 deletions(-)

diff --git a/monitor.c b/monitor.c
index 39f8150..6203f75 100644
--- a/monitor.c
+++ b/monitor.c
@@ -341,7 +341,10 @@ static void monitor_json_emitter(Monitor *mon, const QObject *data)
 {
     QString *json;
 
-    json = qobject_to_json(data);
+    if (mon->flags & MONITOR_USE_PRETTY)
+	json = qobject_to_json_pretty(data);
+    else
+	json = qobject_to_json(data);
     assert(json != NULL);
 
     qstring_append_chr(json, '\n');
diff --git a/monitor.h b/monitor.h
index 46b7a0e..733485f 100644
--- a/monitor.h
+++ b/monitor.h
@@ -14,6 +14,7 @@ extern Monitor *default_mon;
 #define MONITOR_IS_DEFAULT    0x01
 #define MONITOR_USE_READLINE  0x02
 #define MONITOR_USE_CONTROL   0x04
+#define MONITOR_USE_PRETTY    0x08
 
 /* QMP events */
 typedef enum MonitorEvent {
diff --git a/qemu-config.c b/qemu-config.c
index 925bd04..20ed8c2 100644
--- a/qemu-config.c
+++ b/qemu-config.c
@@ -362,6 +362,9 @@ QemuOptsList qemu_mon_opts = {
         },{
             .name = "default",
             .type = QEMU_OPT_BOOL,
+        },{
+            .name = "pretty",
+            .type = QEMU_OPT_BOOL,
         },
         { /* end if list */ }
     },
diff --git a/vl.c b/vl.c
index 35d2b51..de010cc 100644
--- a/vl.c
+++ b/vl.c
@@ -2391,6 +2391,9 @@ static int mon_init_func(QemuOpts *opts, void *opaque)
         exit(1);
     }
 
+    if (qemu_opt_get_bool(opts, "pretty", 0))
+        flags |= MONITOR_USE_PRETTY;
+
     if (qemu_opt_get_bool(opts, "default", 0))
         flags |= MONITOR_IS_DEFAULT;
 
-- 
1.6.6.1

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [Qemu-devel] [PATCH 19/19] Add a -capabilities argument to allow easy query for static QEMU info
  2010-06-07 14:42 [Qemu-devel] [PATCH 00/19] RFC: Reporting QEMU binary capabilities Daniel P. Berrange
                   ` (17 preceding siblings ...)
  2010-06-07 14:42 ` [Qemu-devel] [PATCH 18/19] Add option to turn on JSON pretty printing in monitor Daniel P. Berrange
@ 2010-06-07 14:42 ` Daniel P. Berrange
  2010-06-07 16:04   ` [Qemu-devel] " Paolo Bonzini
  2010-06-07 16:04   ` [Qemu-devel] " Anthony Liguori
  2010-06-07 14:58 ` [Qemu-devel] [PATCH 00/19] RFC: Reporting QEMU binary capabilities Anthony Liguori
                   ` (2 subsequent siblings)
  21 siblings, 2 replies; 62+ messages in thread
From: Daniel P. Berrange @ 2010-06-07 14:42 UTC (permalink / raw)
  To: qemu-devel

The QMP monitor provides a number of commands for querying info about
the QEMU binary capabilities. Given that these commands don't take
any options and just return static data, requiring the use of QMP is
unnecessarily onerous. This adds a new '-capabilities' command line
argument as a syntactic sugar for accessing the QMP commands that
just return static QEMU binary capabilities.

Setting the '-capabilities' argument causes QEMU to output the requested
data on stdout, pretty printed in JSON format. The argument expects an
associated value to identify the data to be printed. This can be one of
the strings version|machines|devices|cputypes|target|commands|argv|netdev

To query all possible data at once, the shorthand 'all' is allowed.

The output is a QDict where the key is the type of data requested, and
the value is the JSON data from the associated monitor command. For
example:

  $ qemu -capabilities all
  {
    "machines": [
        {
            "name": "pc-0.13",
            "description": "Standard PC",
            "default": 0
        },
        {
            "name": "pc",
            ....
        }
        ....
     }
     "version": {
        "qemu": {
            "micro": 50,
            "minor": 12,
            "major": 0
        },
        "package": ""
     },
     "target": {
        "arch": "i386",
        "wordsize": 32,
     ...
   }

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
---
 monitor.c       |    4 +-
 monitor.h       |    2 +
 qemu-options.hx |    9 +++++
 vl.c            |  100 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 113 insertions(+), 2 deletions(-)

diff --git a/monitor.c b/monitor.c
index 6203f75..401a27a 100644
--- a/monitor.c
+++ b/monitor.c
@@ -711,7 +711,7 @@ static void do_info_version_print(Monitor *mon, const QObject *data)
  *
  * { qemu: { "major": 0, "minor": 11, "micro": 5 }, "package": "" }
  */
-static void do_info_version(Monitor *mon, QObject **ret_data)
+void do_info_version(Monitor *mon, QObject **ret_data)
 {
     const char *version = QEMU_VERSION;
     int major = 0, minor = 0, micro = 0;
@@ -760,7 +760,7 @@ static QObject *get_cmd_dict(const char *name)
     return qobject_from_jsonf("{ 'name': %s }", p);
 }
 
-static void do_info_commands(Monitor *mon, QObject **ret_data)
+void do_info_commands(Monitor *mon, QObject **ret_data)
 {
     QList *cmd_list;
     const mon_cmd_t *cmd;
diff --git a/monitor.h b/monitor.h
index 733485f..dc376af 100644
--- a/monitor.h
+++ b/monitor.h
@@ -57,5 +57,7 @@ typedef void (MonitorCompletion)(void *opaque, QObject *ret_data);
 void monitor_set_error(Monitor *mon, QError *qerror);
 
 void do_info_argv(Monitor *mon, QObject **data);
+void do_info_version(Monitor *mon, QObject **ret_data);
+void do_info_commands(Monitor *mon, QObject **ret_data);
 
 #endif /* !MONITOR_H */
diff --git a/qemu-options.hx b/qemu-options.hx
index a6928b7..5f82347 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -27,6 +27,15 @@ STEXI
 Display version information and exit
 ETEXI
 
+DEF("capabilities", HAS_ARG, QEMU_OPTION_capabilities,
+    "-capabilities   all|version|machines|devices|cputypes|target|commands|argv|netdev\n"
+    "                display capabilities of the QEMU binary and exit\n", QEMU_ARCH_ALL)
+STEXI
+@item -capabilities  all|version|machines|devices|cputypes|target|commands|argv|netdev
+@findex -capabilities
+Display capabilities of the QEMU binary and exit
+ETEXI
+
 DEF("M", HAS_ARG, QEMU_OPTION_M,
     "-M machine      select emulated machine (-M ? for list)\n", QEMU_ARCH_ALL)
 STEXI
diff --git a/vl.c b/vl.c
index de010cc..1f165a1 100644
--- a/vl.c
+++ b/vl.c
@@ -1988,6 +1988,97 @@ static void version(void)
 }
 
 
+enum {
+    QEMU_CAPS_VERSION,
+    QEMU_CAPS_MACHINES,
+    QEMU_CAPS_DEVICES,
+    QEMU_CAPS_CPUTYPES,
+    QEMU_CAPS_TARGET,
+    QEMU_CAPS_COMMANDS,
+    QEMU_CAPS_ARGV,
+    QEMU_CAPS_NETDEV,
+    QEMU_CAPS_CONFIG,
+
+    QEMU_CAPS_LAST
+};
+
+QEMU_ENUM_DECL(qemu_caps_flag);
+QEMU_ENUM_IMPL(qemu_caps_flag, QEMU_CAPS_LAST,
+               "version",
+               "machines",
+               "devices",
+               "cputypes",
+               "target",
+               "commands",
+               "argv",
+               "netdev",
+               "config");
+
+static int qemu_caps_flags_from_string(const char *flagsstr)
+{
+    if (strcmp(flagsstr, "all") == 0)
+        return ~0;
+    else {
+        int i = qemu_caps_flag_from_string(flagsstr);
+        if (i < 0)
+            return 0;
+        return (1 << i);
+    }
+
+    return 0;
+}
+typedef void (*qemu_caps_handler)(Monitor *mon, QObject **);
+
+/* Binding capabilities to a subset of monitor commands.
+ * The commands must only use static binary state, no
+ * VM runtime state and must accept mon=NULL
+ */
+static const qemu_caps_handler qemu_caps_handlers[] = {
+    do_info_version,
+    do_info_machines,
+    do_info_devices,
+    do_info_cpu_types,
+    do_info_target,
+    do_info_commands,
+    do_info_argv,
+    do_info_netdev,
+    do_info_config,
+};
+verify(ARRAY_SIZE(qemu_caps_handlers) == QEMU_CAPS_LAST);
+
+static void qemu_show_caps(const char *flagsstr)
+{
+    QDict *data = qdict_new();
+    QString *json;
+    int i;
+    int flags;
+
+    flags = qemu_caps_flags_from_string(flagsstr);
+    if (flags == 0) {
+        fprintf(stderr, "Unknown capabilities '%s'\n", flagsstr);
+        exit(1);
+    }
+
+    for (i = 0 ; i < QEMU_CAPS_LAST ; i++) {
+        if (flags & (1 << i)) {
+            QObject *val;
+            qemu_caps_handler handler = qemu_caps_handlers[i];
+            const char *name = qemu_caps_flag_to_string(i);
+            (*handler)(NULL, &val);
+            qdict_put_obj(data, name, val);
+        }
+    }
+    json = qobject_to_json_pretty(QOBJECT(data));
+    assert(json != NULL);
+
+    qstring_append_chr(json, '\n');
+    fprintf(stdout, qstring_get_str(json));
+
+    QDECREF(json);
+
+}
+
+
 /**
  * do_info_argv():
  *
@@ -2647,6 +2738,7 @@ int main(int argc, char **argv, char **envp)
 #endif
     int show_vnc_port = 0;
     int defconfig = 1;
+    const char *showcaps = NULL;
 
     error_set_progname(argv[0]);
 
@@ -3020,6 +3112,9 @@ int main(int argc, char **argv, char **envp)
                 version();
                 exit(0);
                 break;
+            case QEMU_OPTION_capabilities:
+                showcaps = optarg;
+                break;
             case QEMU_OPTION_m: {
                 uint64_t value;
                 char *ptr;
@@ -3785,6 +3880,11 @@ int main(int argc, char **argv, char **envp)
     if (qemu_opts_foreach(&qemu_device_opts, device_help_func, NULL, 0) != 0)
         exit(0);
 
+    if (showcaps) {
+        qemu_show_caps(showcaps);
+        exit(0);
+    }
+
     if (watchdog) {
         i = select_watchdog(watchdog);
         if (i > 0)
-- 
1.6.6.1

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* Re: [Qemu-devel] [PATCH 00/19] RFC: Reporting QEMU binary capabilities
  2010-06-07 14:42 [Qemu-devel] [PATCH 00/19] RFC: Reporting QEMU binary capabilities Daniel P. Berrange
                   ` (18 preceding siblings ...)
  2010-06-07 14:42 ` [Qemu-devel] [PATCH 19/19] Add a -capabilities argument to allow easy query for static QEMU info Daniel P. Berrange
@ 2010-06-07 14:58 ` Anthony Liguori
  2010-06-07 15:10   ` Daniel P. Berrange
  2010-06-07 16:02   ` [Qemu-devel] " Paolo Bonzini
  2010-06-07 16:07 ` [Qemu-devel] " Anthony Liguori
  2010-06-26  6:45 ` Markus Armbruster
  21 siblings, 2 replies; 62+ messages in thread
From: Anthony Liguori @ 2010-06-07 14:58 UTC (permalink / raw)
  To: Daniel P. Berrange; +Cc: qemu-devel

On 06/07/2010 09:42 AM, Daniel P. Berrange wrote:
> As everyone here agrees, having management apps parse -help output
> to determine the QEMU capabilities is not at all nice, because it
> is an ill-defined&  fragile data format. Looking more broadly these
> same issues apply to all the other command line options that accept
> a '?' flag for querying capabilities.
>
> We have a very nice structured data format we could be using for
> this: JSON. What's lacking is code to output all this information
> in the JSON format. This patch series can thus be summarized as
> 'JSON for everything'
>    

I'm slightly skeptical that JSON is the right format for this TBH.

> For reference, here is the full list of information libvirt currently
> queries from QEMU:
>
>    * Detection of command line flags (-help parsing)
>
>      -no-kqemu, -no-kvm, -enable-kvm, -no-reboot
>      -name, -uuid, -xen-domid, -domid, -drive
>      -vga, -std-vga, -pcidevice, -mem-path
>      -chardev, -balloon, -device, -rtc, -rtc-td-hack
>      -no-hpet, -no-kvm-pit-reinjection, -tdf
>      -fsdev -sdl
>    

Most of these things can be associated with a config option and/or a 
version.

>    * Detection of parameters (-help parsing)
>
>       -drive format=
>       -drive boot=
>       -drive serial=
>       -drive cache=
>       -cpu cores=, threads=, sockets=
>       -netdev vhost=
>    

Likewise.

>    * Detection of parameter values (-help parsing)
>
>       -drive cache=writethrough|writeback|none
>         vs
>       -drive cache=default|on|off
>    

Same here.

>    * Version number  (-help parsing)
>
>      -netdev  + 0.13.0
>
>      0.9.0  for VNC syntax
>
>      0.10.0 for vnet hdr
>
>    * Parse -M ?  output to get list of machine types + aliases
>    

Yeah, it would be a good to have a qmp command to list supported machines.

>    * Parse -device pci-assign,? to check for 'configfd' parameter
>
>    * Parse -cpu ?  to get list of named CPU types
>    

Would be good to have qmp for this too.

>    * Parse binary name (qemu-system-XXXX) to guess arch of target
>    

Same here.

> This isn't an 100% exhaustive list of things that we would like
> to be able to get access to though. It can likely cover all of
> the following:
>
>   * Version
>
>        QEMU major, minor, micro numbers. KVM version. Package
>        version
>
>   * Devices
>
>        List of device names. Parameter names. Parameter value
>        data types. Allowed strings for enums
>
>   * Arguments
>
>        List of command line arguments. Parameter names. Parameter
>        value data types. Allowed strings for enums
>    

I'm a bit sceptical that this is the right thing to offer.

Generally speaking, libvirt is not going to be capable of handling every 
possible combination of qemu features.  Instead, for 0.12 it will use 
this set of functionality, for 0.13 it might use a different set.

>   * Machine types
>
>        List of names + aliases
>        List of default devices in machine
>
>   * CPU types
>
>        List of names, associated feature flags, all allowed
>        feature flags
>
>   * Target info
>
>        Arch name, wordsize
>
>   * Monitor commands
>
>        List of all monitor commands. Parameter names. Parameter
>        value data types. Allowed strings for enums
>
>   * Block device backends
>
>        List of all block device backends. Parameter names.
>        Parameter value data types. Allowed strings for enums
>
>   * Netdev device backends
>
>        List of all netdev device backends. Parameter names.
>        Parameter value data types. Allowed strings for enums
>
>   * Chardev device backends
>
>        List of all chardev device backends. Parameter names.
>        Parameter value data types. Allowed strings for enums
>
>
> This patch series attempts to satisfy as much of this as is
> feasible with the current QEMU codebase structure. The series
> comprises four stages
>
>   * Some basic infrastructure. Support for JSON pretty printing.
>     Introduction of standardized helpers for converting enums
>     to/from strings. Introduction of an 'enum' data type for
>     QemuOpt to expose a formal list of valid values&  simplify
>     config handling / parsing. Compile time assertion checking
>
>   * Convert driver, netdev&  rtc config options to use the new
>     enum data type for all appropriate args
>
>   * Add new QMP monitor commands exposing data for machine
>     types, devices, cpu types, arch target, argv, config params,
>     and netdev backends.
>
>   * Add a new '-capabilities' command line arg as syntactic
>     sugar for the monitor commands that just report on static
>     info about the QEMU binary.
>
> The main problem encountered with this patch series is the
> split between argv and config parameters. The qemu-config.c
> file provides the information is a good data format, allowing
> programatic access to the list of parameters for each config
> option (eg, the 'cache', 'file', 'aio', etc bits for -drive).
> There are some issues with it though
>
>   - It lacks a huge amount of coverage wrt to the full argv
>     available, even simple things like the '-m' argument
>     don't exist.
>
>   - It is inconsistent in handling parameters. eg it  hands
>     off validation of netdev backends to other code, to allow
>     for handling of different parameters for tap vs user vs
>     socket backends.  For chardev backends though, it directly
>     includes a union of all possible parameters.
>
> Ideally the 'query-argv' command would not be required, but
> unless those problems with the qemu-config are resolved, it
> is the only way to access alot of the information. This is
> sub-optimal because although it lets apps easily determine
> whether an arg like '-smp' is present, it still leaves them
> parsing that args' help string to discover parameters.
>    

A query-argv is a really bad idea IMHO.

Regards,

Anthony Liguori

> This series is lacking a 'query-blockdev' and 'query-chardev'
> commands to report on availability of backends for -blockdev
> and '-chardev' commands.
>
> Finally the existing 'query-commands' output is lacking any
> information about the parameters associated with each command.
> This needs to be addressed somehow.
>
> In summary though, IMHO, this patch series provides a good
> base for providing information about static QEMU binary
> capabilities to applications. It should ensure apps never
> again need to go anywhere near -help, -M ?, -cpu ?, -device ?,
> -soundhw ? and other such ill defined output formats.
>
> NB, I know this patch series will probably clash horribly
> with other patch series recently posted for review, in
> particular Jes' cleanup of vl.c   I will rebase as required
> if any of those get merged.
>
> This series is currently based on GIT master as of:
>
>    commit fd1dc858370d9a9ac7ea2512812c3a152ee6484b
>    Author: Edgar E. Iglesias<edgar.iglesias@gmail.com>
>    Date:   Mon Jun 7 11:54:27 2010 +0200
>
> Regards,
> Daniel
>
>   Makefile.objs                |    2
>   block.c                      |   32 +-
>   block.h                      |   55 ++++
>   cpus.c                       |   78 ++++++
>   cpus.h                       |    1
>   hw/boards.h                  |    2
>   hw/mc146818rtc.c             |    8
>   hw/qdev.c                    |  148 +++++++++++++
>   hw/qdev.h                    |    2
>   monitor.c                    |  167 ++++++++++++++
>   monitor.h                    |    5
>   net.c                        |  173 ++++++++++-----
>   net.h                        |    2
>   qemu-config.c                |  228 +++++++++++++++++++-
>   qemu-config.h                |    2
>   qemu-enum.c                  |   44 +++
>   qemu-enum.h                  |   45 ++++
>   qemu-option.c                |   35 +++
>   qemu-option.h                |   14 +
>   qemu-options.hx              |    9
>   qjson.c                      |   55 ++++
>   qjson.h                      |    1
>   sysemu.h                     |   43 +++
>   target-arm/cpu.h             |    7
>   target-arm/helper.c          |   21 +
>   target-cris/cpu.h            |    7
>   target-cris/translate.c      |   22 +
>   target-i386/cpu.h            |    7
>   target-i386/cpuid.c          |   79 +++++++
>   target-m68k/cpu.h            |    9
>   target-m68k/helper.c         |   23 ++
>   target-mips/cpu.h            |    7
>   target-mips/translate.c      |    4
>   target-mips/translate_init.c |   19 +
>   target-ppc/cpu.h             |    7
>   target-ppc/translate.c       |    4
>   target-ppc/translate_init.c  |   17 +
>   target-sh4/cpu.h             |    8
>   target-sh4/translate.c       |   23 ++
>   target-sparc/cpu.h           |    9
>   target-sparc/helper.c        |   60 +++++
>   verify.h                     |  164 ++++++++++++++
>   vl.c                         |  482 +++++++++++++++++++++++++++++--------------
>   43 files changed, 1869 insertions(+), 261 deletions(-)
>
>
>
>    

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [Qemu-devel] [PATCH 14/19] Add a query-argv command to QMP
  2010-06-07 14:42 ` [Qemu-devel] [PATCH 14/19] Add a query-argv " Daniel P. Berrange
@ 2010-06-07 15:01   ` Anthony Liguori
  2010-06-10 15:34     ` [Qemu-devel] " Paolo Bonzini
  2010-06-26  7:30     ` [Qemu-devel] " Markus Armbruster
  0 siblings, 2 replies; 62+ messages in thread
From: Anthony Liguori @ 2010-06-07 15:01 UTC (permalink / raw)
  To: Daniel P. Berrange; +Cc: qemu-devel

On 06/07/2010 09:42 AM, Daniel P. Berrange wrote:
> Add a new QMP command called 'query-argv' to information about the command
> line arguments supported by the QEMU binary. This is intended to remove the
> need for apps to parse '-help' output.
>    

This is just as bad as parsing -help output IMHO.

The problem with something like this is that it discourages people from 
using proper APIs to get at capabilities information.

Regards,

Anthony Liguori

>      [
>          {
>              "name": "help",
>          },
>          {
>              "name": "M",
>              "parameters": [
>                  {
>                  }
>              ]
>          },
>      ]
>
> NB, command line args which accept parameters have a non-zero length
> parameters list. The element of the list is currently empty though
> since the parameter names are not easily available in QEMU source in
> a format suitable for exposing as a stable ABI.
>
> Signed-off-by: Daniel P. Berrange<berrange@redhat.com>
> ---
>   monitor.c |    8 ++++++
>   monitor.h |    2 +
>   vl.c      |   74 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>   3 files changed, 84 insertions(+), 0 deletions(-)
>
> diff --git a/monitor.c b/monitor.c
> index d55b27b..1c5157d 100644
> --- a/monitor.c
> +++ b/monitor.c
> @@ -2544,6 +2544,14 @@ static const mon_cmd_t info_cmds[] = {
>           .mhandler.info_new = do_info_commands,
>       },
>       {
> +        .name       = "argv",
> +        .args_type  = "",
> +        .params     = "",
> +        .help       = "list QEMU command line argv",
> +        .user_print = monitor_user_noop,
> +        .mhandler.info_new = do_info_argv,
> +    },
> +    {
>           .name       = "network",
>           .args_type  = "",
>           .params     = "",
> diff --git a/monitor.h b/monitor.h
> index ea15469..46b7a0e 100644
> --- a/monitor.h
> +++ b/monitor.h
> @@ -55,4 +55,6 @@ typedef void (MonitorCompletion)(void *opaque, QObject *ret_data);
>
>   void monitor_set_error(Monitor *mon, QError *qerror);
>
> +void do_info_argv(Monitor *mon, QObject **data);
> +
>   #endif /* !MONITOR_H */
> diff --git a/vl.c b/vl.c
> index 8043fac..a76c673 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -1987,6 +1987,80 @@ static void version(void)
>       printf("QEMU emulator version " QEMU_VERSION QEMU_PKGVERSION ", Copyright (c) 2003-2008 Fabrice Bellard\n");
>   }
>
> +
> +/**
> + * do_info_argv():
> + *
> + * Provide info about the command line arguments
> + * supported by the QEMU binary. The returned
> + * data is a QList with one QDict entry for  each named
> + * argument. Each entry's QDict contains the following
> + * keys
> + *
> + *  'name': the command argument name (eg 'drive' for -drive arg)
> + *  'parameters': list of parameter values (if any)
> + *
> + * NB, the 'parameters' key is omitted completely if
> + * the argument has no associated value.
> + *
> + * XXXX details of the parameters are not yet filled in
> + * since this info is not easily available
> + *
> + *     [
> + *         {
> + *             "name": "help",
> + *             "parameters": [
> + *             ]
> + *         },
> + *         {
> + *             "name": "M",
> + *             "parameters": [
> + *                 {
> + *                 }
> + *             ]
> + *         },
> + *     ]
> + */
> +void do_info_argv(Monitor *mon, QObject **data)
> +{
> +    QList *args = qlist_new();
> +    struct {
> +       const char *name;
> +       int has_arg;
> +       const char *help;
> +    } options_help[] = {
> +#define DEF(option, opt_arg, opt_enum, opt_help, arch_mask)     \
> +        { option, opt_arg },
> +#define DEFHEADING(text)
> +#define HAS_ARG 1
> +#include "qemu-options.h"
> +#undef DEF
> +#undef DEFHEADING
> +#undef HAS_ARG
> +       { NULL, 0 },
> +    };
> +    int i;
> +
> +    for (i = 0 ; options_help[i].name != NULL ; i++) {
> +	QObject *opt;
> +
> +	if (options_help[i].has_arg) {
> +	    /* XXX actually fill in the parameter details */
> +	    opt = qobject_from_jsonf("{ 'name': %s, 'parameters': [] }",
> +				     options_help[i].name);
> +	} else {
> +	    opt = qobject_from_jsonf("{ 'name': %s }",
> +				     options_help[i].name);
> +	}
> +
> +
> +	qlist_append_obj(args, opt);
> +    }
> +
> +    *data = QOBJECT(args);
> +}
> +
> +
>   static void help(int exitcode)
>   {
>       const char *options_help =
>    

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [Qemu-devel] [PATCH 07/19] Convert netdev client types to use an enumeration
  2010-06-07 14:42 ` [Qemu-devel] [PATCH 07/19] Convert netdev client types to use an enumeration Daniel P. Berrange
@ 2010-06-07 15:09   ` Anthony Liguori
  2010-06-07 15:13     ` Daniel P. Berrange
  0 siblings, 1 reply; 62+ messages in thread
From: Anthony Liguori @ 2010-06-07 15:09 UTC (permalink / raw)
  To: Daniel P. Berrange; +Cc: qemu-devel

On 06/07/2010 09:42 AM, Daniel P. Berrange wrote:
> Declare an enumeration for all netdev client types, values
> matching indexes in the net_client_types array. Use the
> enum helpers for the string<->  int conversion of client types.
>
> Before:
>
>    $ qemu -net type=foo,sfs
>    qemu: -net type=foo,sfs: Parameter 'type' expects a network client type
>
> After:
>
>    $ qemu -net type=foo,sfs
>    qemu: -net type=foo,sfs: Parameter 'type' expects none, nic, user, tap, socket, dump
>
> Signed-off-by: Daniel P. Berrange<berrange@redhat.com>
> ---
>   net.c |  124 ++++++++++++++++++++++++++++++++++++++--------------------------
>   1 files changed, 74 insertions(+), 50 deletions(-)
>
> diff --git a/net.c b/net.c
> index efa8b3d..5349001 100644
> --- a/net.c
> +++ b/net.c
> @@ -42,6 +42,36 @@ static QTAILQ_HEAD(, VLANClientState) non_vlan_clients;
>
>   int default_net = 1;
>
> +enum {
> +    NET_CLIENT_NONE,
> +    NET_CLIENT_NIC,
> +#ifdef CONFIG_SLIRP
> +    NET_CLIENT_USER,
> +#endif
> +    NET_CLIENT_TAP,
> +    NET_CLIENT_SOCKET,
> +#ifdef CONFIG_VDE
> +    NET_CLIENT_VDE,
> +#endif
> +    NET_CLIENT_DUMP,
> +
> +    NET_CLIENT_LAST
> +};
> +
> +QEMU_ENUM_DECL(qemu_net_type);
> +QEMU_ENUM_IMPL(qemu_net_type, NET_CLIENT_LAST,
> +	       "none",
> +	       "nic",
> +#ifdef CONFIG_SLIRP
> +	       "user",
> +#endif
> +	       "tap",
> +	       "socket",
> +#ifdef CONFIG_VDE
> +	       "vde",
> +#endif
> +	       "dump");
> +
>   /***********************************************************/
>   /* network device redirectors */
>
> @@ -844,18 +874,15 @@ typedef int (*net_client_init_func)(QemuOpts *opts,
>   #define NET_MAX_DESC 20
>
>   static const struct {
> -    const char *type;
>       net_client_init_func init;
>       QemuOptDesc desc[NET_MAX_DESC];
>   } net_client_types[] = {
>    

I think:

  [NET_CLIENT_NONE] = {
             .desc = {...}
},

Would be a bit more robust than relying on explicit ordering.

Regards,

Anthony Liguori

> -    {
> -        .type = "none",
> +    { /* NET_CLIENT_NONE */
>           .desc = {
>               NET_COMMON_PARAMS_DESC,
>               { /* end of list */ }
>           },
> -    }, {
> -        .type = "nic",
> +    }, { /* NET_CLIENT_NIC */
>           .init = net_init_nic,
>           .desc = {
>               NET_COMMON_PARAMS_DESC,
> @@ -884,8 +911,7 @@ static const struct {
>               { /* end of list */ }
>           },
>   #ifdef CONFIG_SLIRP
> -    }, {
> -        .type = "user",
> +    }, { /* NET_CLIENT_USER */
>           .init = net_init_slirp,
>           .desc = {
>               NET_COMMON_PARAMS_DESC,
> @@ -945,8 +971,7 @@ static const struct {
>               { /* end of list */ }
>           },
>   #endif
> -    }, {
> -        .type = "tap",
> +    }, { /* NET_CLIENT_TAP */
>           .init = net_init_tap,
>           .desc = {
>               NET_COMMON_PARAMS_DESC,
> @@ -988,8 +1013,7 @@ static const struct {
>   #endif /* _WIN32 */
>               { /* end of list */ }
>           },
> -    }, {
> -        .type = "socket",
> +    }, { /* NET_CLIENT_SOCKET */
>           .init = net_init_socket,
>           .desc = {
>               NET_COMMON_PARAMS_DESC,
> @@ -1013,8 +1037,7 @@ static const struct {
>               { /* end of list */ }
>           },
>   #ifdef CONFIG_VDE
> -    }, {
> -        .type = "vde",
> +    }, { /* NET_CLIENT_VDE */
>           .init = net_init_vde,
>           .desc = {
>               NET_COMMON_PARAMS_DESC,
> @@ -1038,8 +1061,7 @@ static const struct {
>               { /* end of list */ }
>           },
>   #endif
> -    }, {
> -        .type = "dump",
> +    }, { /* NET_CLIENT_DUMP */
>           .init = net_init_dump,
>           .desc = {
>               NET_COMMON_PARAMS_DESC,
> @@ -1055,30 +1077,41 @@ static const struct {
>               { /* end of list */ }
>           },
>       },
> -    { /* end of list */ }
>   };
> +verify(ARRAY_SIZE(net_client_types) == NET_CLIENT_LAST);
>
>   int net_client_init(Monitor *mon, QemuOpts *opts, int is_netdev)
>   {
>       const char *name;
> -    const char *type;
> -    int i;
> +    const char *typestr;
> +    VLANState *vlan = NULL;
> +    int type;
>
> -    type = qemu_opt_get(opts, "type");
> -    if (!type) {
> +    typestr = qemu_opt_get(opts, "type");
> +    if (!typestr) {
>           qerror_report(QERR_MISSING_PARAMETER, "type");
>           return -1;
>       }
> +    type = qemu_net_type_from_string(typestr);
> +
> +    if (type<  0) {
> +	char *valid = qemu_net_type_to_string_list();
> +	qerror_report(QERR_INVALID_PARAMETER_VALUE, "type",
> +		      valid);
> +	qemu_free(valid);
> +	return -1;
> +    }
>
>       if (is_netdev) {
> -        if (strcmp(type, "tap") != 0&&
> +	if (type<  0 ||
> +	    (type != NET_CLIENT_TAP&&
>   #ifdef CONFIG_SLIRP
> -            strcmp(type, "user") != 0&&
> +	     type != NET_CLIENT_USER&&
>   #endif
>   #ifdef CONFIG_VDE
> -            strcmp(type, "vde") != 0&&
> +	     type != NET_CLIENT_VDE&&
>   #endif
> -            strcmp(type, "socket") != 0) {
> +	     type != NET_CLIENT_SOCKET)) {
>               qerror_report(QERR_INVALID_PARAMETER_VALUE, "type",
>                             "a netdev backend type");
>               return -1;
> @@ -1103,35 +1136,26 @@ int net_client_init(Monitor *mon, QemuOpts *opts, int is_netdev)
>           name = qemu_opt_get(opts, "name");
>       }
>
> -    for (i = 0; net_client_types[i].type != NULL; i++) {
> -        if (!strcmp(net_client_types[i].type, type)) {
> -            VLANState *vlan = NULL;
> -
> -            if (qemu_opts_validate(opts,&net_client_types[i].desc[0]) == -1) {
> -                return -1;
> -            }
> -
> -            /* Do not add to a vlan if it's a -netdev or a nic with a
> -             * netdev= parameter. */
> -            if (!(is_netdev ||
> -                  (strcmp(type, "nic") == 0&&  qemu_opt_get(opts, "netdev")))) {
> -                vlan = qemu_find_vlan(qemu_opt_get_number(opts, "vlan", 0), 1);
> -            }
> +    if (qemu_opts_validate(opts,&net_client_types[type].desc[0]) == -1) {
> +	return -1;
> +    }
>
> -            if (net_client_types[i].init) {
> -                if (net_client_types[i].init(opts, mon, name, vlan)<  0) {
> -                    /* TODO push error reporting into init() methods */
> -                    qerror_report(QERR_DEVICE_INIT_FAILED, type);
> -                    return -1;
> -                }
> -            }
> -            return 0;
> -        }
> +    /* Do not add to a vlan if it's a -netdev or a nic with a
> +     * netdev= parameter. */
> +    if (!(is_netdev ||
> +	  (type == NET_CLIENT_NIC&&  qemu_opt_get(opts, "netdev")))) {
> +	vlan = qemu_find_vlan(qemu_opt_get_number(opts, "vlan", 0), 1);
>       }
>
> -    qerror_report(QERR_INVALID_PARAMETER_VALUE, "type",
> -                  "a network client type");
> -    return -1;
> +    if (net_client_types[type].init) {
> +	if (net_client_types[type].init(opts, mon, name, vlan)<  0) {
> +	    /* TODO push error reporting into init() methods */
> +	    qerror_report(QERR_DEVICE_INIT_FAILED,
> +			  qemu_net_type_to_string(type));
> +	    return -1;
> +	}
> +    }
> +    return 0;
>   }
>
>   static int net_host_check_device(const char *device)
>    

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [Qemu-devel] [PATCH 00/19] RFC: Reporting QEMU binary capabilities
  2010-06-07 14:58 ` [Qemu-devel] [PATCH 00/19] RFC: Reporting QEMU binary capabilities Anthony Liguori
@ 2010-06-07 15:10   ` Daniel P. Berrange
  2010-06-07 15:18     ` Anthony Liguori
  2010-06-07 16:02   ` [Qemu-devel] " Paolo Bonzini
  1 sibling, 1 reply; 62+ messages in thread
From: Daniel P. Berrange @ 2010-06-07 15:10 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: qemu-devel

On Mon, Jun 07, 2010 at 09:58:11AM -0500, Anthony Liguori wrote:
> On 06/07/2010 09:42 AM, Daniel P. Berrange wrote:
> >As everyone here agrees, having management apps parse -help output
> >to determine the QEMU capabilities is not at all nice, because it
> >is an ill-defined&  fragile data format. Looking more broadly these
> >same issues apply to all the other command line options that accept
> >a '?' flag for querying capabilities.
> >
> >We have a very nice structured data format we could be using for
> >this: JSON. What's lacking is code to output all this information
> >in the JSON format. This patch series can thus be summarized as
> >'JSON for everything'
> >   
> 
> I'm slightly skeptical that JSON is the right format for this TBH.
> 
> >For reference, here is the full list of information libvirt currently
> >queries from QEMU:
> >
> >   * Detection of command line flags (-help parsing)
> >
> >     -no-kqemu, -no-kvm, -enable-kvm, -no-reboot
> >     -name, -uuid, -xen-domid, -domid, -drive
> >     -vga, -std-vga, -pcidevice, -mem-path
> >     -chardev, -balloon, -device, -rtc, -rtc-td-hack
> >     -no-hpet, -no-kvm-pit-reinjection, -tdf
> >     -fsdev -sdl
> >   
> 
> Most of these things can be associated with a config option and/or a 
> version.

If the 'qemu-config.c' file had parity with the config options
that were available as argv then I would not suggest including
the argv data at all. This patchset is an attempt to provide
all the information we need based on current state of the QEMU
codebase, since qemu-config is seriously incomplete at this time.
If we instead want to make a concerted effort to finish porting
all existing config options over to the new style qemu-config.c 
format, that would definitely be much nicer than reporting about
argv.

Regards,
Daniel
-- 
|: Red Hat, Engineering, London    -o-   http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://deltacloud.org :|
|: http://autobuild.org        -o-         http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505  -o-   F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [Qemu-devel] [PATCH 09/19] Change 'query-version' to output broken down version string
  2010-06-07 14:42 ` [Qemu-devel] [PATCH 09/19] Change 'query-version' to output broken down version string Daniel P. Berrange
@ 2010-06-07 15:11   ` Anthony Liguori
  2010-06-09 20:04     ` Luiz Capitulino
  0 siblings, 1 reply; 62+ messages in thread
From: Anthony Liguori @ 2010-06-07 15:11 UTC (permalink / raw)
  To: Daniel P. Berrange; +Cc: qemu-devel

On 06/07/2010 09:42 AM, Daniel P. Berrange wrote:
> A previous discussion brought up the fact that clients should
> not have to parse version string from QMP, it should be given
> to them pre-split.
>
> Change query-version output format from:
>
>    { "qemu": "0.11.50", "package": "" }
>
> to:
>
>    { qemu: { "major": 0, "minor": 11, "micro": 5 }, "package": "" }
>    

We need to drop package entirely.

Instead vendors should use the vendor specific namespace to extend the 
version.

I'd suggest changing the version output to:

{ 'major': 0, 'minor': 11, 'micro': 5 }

For something like kvm, it can introduce a '__org.linux-kvm.release', 2 
to that main dictionary.

Regards,

Anthony Liguori

> The major, minor&  micro keys are all integer values. package is
> an arbitrary string whose format is defined by the OS package
> maintainer.
>
> There is no need to preserve the existing string format of the 'qemu'
> key, since QMP is not yet declared stable.
>
> Signed-off-by: Daniel P. Berrange<berrange@redhat.com>
> ---
>   monitor.c |   47 +++++++++++++++++++++++++++++++++++++++++++----
>   1 files changed, 43 insertions(+), 4 deletions(-)
>
> diff --git a/monitor.c b/monitor.c
> index 15b53b9..f0406e8 100644
> --- a/monitor.c
> +++ b/monitor.c
> @@ -670,17 +670,56 @@ help:
>   static void do_info_version_print(Monitor *mon, const QObject *data)
>   {
>       QDict *qdict;
> +    QDict *qemu;
>
>       qdict = qobject_to_qdict(data);
> +    qemu = qdict_get_qdict(qdict, "qemu");
>
> -    monitor_printf(mon, "%s%s\n", qdict_get_str(qdict, "qemu"),
> -                                  qdict_get_str(qdict, "package"));
> +    monitor_printf(mon, "%" PRId64 ".%" PRId64 ".%" PRId64 "%s\n",
> +		   qdict_get_int(qemu, "major"),
> +		   qdict_get_int(qemu, "minor"),
> +		   qdict_get_int(qemu, "micro"),
> +		   qdict_get_str(qdict, "package"));
>   }
>
> +
> +/**
> + * do_info_version(): Show QEMU version
> + *
> + * Return a QDict with the following information:
> + *
> + * - "qemu": QEMU upstream version
> + * - "package": QEMU packager's version
> + *
> + * The 'qemu' key value is a QDict containing three
> + * integer values
> + *
> + * - "major": QEMU's major version
> + * - "minor": QEMU's minor version
> + * - "micro": QEMU's micro version
> + *
> + * The 'package' key value is a string in an format
> + * defined by the OS distributor to reflect their
> + * packaging of QEMU.
> + *
> + * Example:
> + *
> + * { qemu: { "major": 0, "minor": 11, "micro": 5 }, "package": "" }
> + */
>   static void do_info_version(Monitor *mon, QObject **ret_data)
>   {
> -    *ret_data = qobject_from_jsonf("{ 'qemu': %s, 'package': %s }",
> -                                   QEMU_VERSION, QEMU_PKGVERSION);
> +    const char *version = QEMU_VERSION;
> +    int major = 0, minor = 0, micro = 0;
> +    char *tmp;
> +
> +    major = strtol(version,&tmp, 10);
> +    tmp++;
> +    minor = strtol(tmp,&tmp, 10);
> +    tmp++;
> +    micro = strtol(tmp,&tmp, 10);
> +
> +    *ret_data = qobject_from_jsonf("{ 'qemu': { 'major': %d, 'minor': %d, 'micro': %d }, 'package': %s }",
> +                                   major, minor, micro, QEMU_PKGVERSION);
>   }
>
>   static void do_info_name_print(Monitor *mon, const QObject *data)
>    

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [Qemu-devel] [PATCH 10/19] Add a query-machines command to QMP
  2010-06-07 14:42 ` [Qemu-devel] [PATCH 10/19] Add a query-machines command to QMP Daniel P. Berrange
@ 2010-06-07 15:13   ` Anthony Liguori
  2010-06-07 16:44     ` Daniel P. Berrange
  0 siblings, 1 reply; 62+ messages in thread
From: Anthony Liguori @ 2010-06-07 15:13 UTC (permalink / raw)
  To: Daniel P. Berrange; +Cc: qemu-devel

On 06/07/2010 09:42 AM, Daniel P. Berrange wrote:
> Add a new QMP monitor command 'query-machines' to discover what
> machines are defined in the QEMU binary. This is an easily
> parsable replacement for 'qemu -M ?'
>
>      [
>          {
>              "name": "pc-0.13",
>              "description": "Standard PC",
>              "default": 0
>          },
>          {
>              "name": "pc",
>              "description": "Standard PC",
>              "canonical": "pc-0.13",
>              "default": 1
>          },
>          {
>              "name": "pc-0.12",
>              "description": "Standard PC",
>              "default": 0
>          },
>          ....
>      ]
>
> No legacy readline monitor output is provided.
>
> In the future it would be desirable for each machine's QDict to
> also include details of any qdev devices that are included by
> default in the machine type.
>
> Signed-off-by: Daniel P. Berrange<berrange@redhat.com>
> ---
>   hw/boards.h |    1 +
>   monitor.c   |    9 +++++++
>   vl.c        |   70 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>   3 files changed, 80 insertions(+), 0 deletions(-)
>
> diff --git a/hw/boards.h b/hw/boards.h
> index 6f0f0d7..2f6003d 100644
> --- a/hw/boards.h
> +++ b/hw/boards.h
> @@ -32,6 +32,7 @@ typedef struct QEMUMachine {
>   } QEMUMachine;
>
>   int qemu_register_machine(QEMUMachine *m);
> +void do_info_machines(Monitor *mon, QObject **data);
>
>   extern QEMUMachine *current_machine;
>
> diff --git a/monitor.c b/monitor.c
> index f0406e8..b6aa2b4 100644
> --- a/monitor.c
> +++ b/monitor.c
> @@ -55,6 +55,7 @@
>   #include "json-streamer.h"
>   #include "json-parser.h"
>   #include "osdep.h"
> +#include "hw/boards.h"
>
>   //#define DEBUG
>   //#define DEBUG_COMPLETION
> @@ -2449,6 +2450,14 @@ static const mon_cmd_t info_cmds[] = {
>           .mhandler.info_new = do_info_version,
>       },
>       {
> +        .name       = "machines",
> +        .args_type  = "",
> +        .params     = "",
> +        .help       = "show the machine boards",
> +        .user_print = monitor_user_noop,
> +        .mhandler.info_new = do_info_machines,
> +    },
> +    {
>           .name       = "commands",
>           .args_type  = "",
>           .params     = "",
> diff --git a/vl.c b/vl.c
> index 0b38d62..8043fac 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -1537,6 +1537,76 @@ static QEMUMachine *find_default_machine(void)
>       return NULL;
>   }
>
> +
> +/**
> + * do_info_machines(): Show machine boards
> + *
> + * Returns a QList object listing all machine boards
> + * available with this QEMU target. Each element in
> + * the list is a QDict object containing the following
> + * keys
> + *
> + *  - "name": short name for the machine board
> + *  - "description": long description of the board
> + *  - "alias": name of an alias
> + *
> + * Example:
> + *
> + *  [
> + *     {
> + *       "name": "pc-0.13",
> + *        "description": "Standard PC",
> + *        "default": 0
> + *     },
> + *     {
> + *       "name": "pc",
> + *       "description": "Standard PC",
> + *       "canonical": "pc-0.13",
> + *       "default": 1
> + *     },
> + *     {
> + *       "name": "pc-0.12",
> + *       "description": "Standard PC",
> + *       "default": 0
> + *     },
> + *     ....
> + *  ]
> + *
> + */
>    

My only suggestion would be to:

{ 'default-machine': 'pc',
    'machines': [{
      'name': 'pc',
      'description': 'Standard PC',
    },...]
}

I'd drop 'canonical' too.  Aliasing is an implementation detail and 
should not be exposed via the ABI.

Regards,

Anthony Liguori

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [Qemu-devel] [PATCH 07/19] Convert netdev client types to use an enumeration
  2010-06-07 15:09   ` Anthony Liguori
@ 2010-06-07 15:13     ` Daniel P. Berrange
  0 siblings, 0 replies; 62+ messages in thread
From: Daniel P. Berrange @ 2010-06-07 15:13 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: qemu-devel

On Mon, Jun 07, 2010 at 10:09:02AM -0500, Anthony Liguori wrote:
> On 06/07/2010 09:42 AM, Daniel P. Berrange wrote:
> >Declare an enumeration for all netdev client types, values
> >matching indexes in the net_client_types array. Use the
> >enum helpers for the string<->  int conversion of client types.
> >
> >Before:
> >
> >   $ qemu -net type=foo,sfs
> >   qemu: -net type=foo,sfs: Parameter 'type' expects a network client type
> >
> >After:
> >
> >   $ qemu -net type=foo,sfs
> >   qemu: -net type=foo,sfs: Parameter 'type' expects none, nic, user, tap, 
> >   socket, dump
> >
> >Signed-off-by: Daniel P. Berrange<berrange@redhat.com>
> >---
> >  net.c |  124 
> >  ++++++++++++++++++++++++++++++++++++++--------------------------
> >  1 files changed, 74 insertions(+), 50 deletions(-)
> >
> >diff --git a/net.c b/net.c
> >index efa8b3d..5349001 100644
> >--- a/net.c
> >+++ b/net.c
> >@@ -42,6 +42,36 @@ static QTAILQ_HEAD(, VLANClientState) non_vlan_clients;
> >
> >  int default_net = 1;
> >
> >+enum {
> >+    NET_CLIENT_NONE,
> >+    NET_CLIENT_NIC,
> >+#ifdef CONFIG_SLIRP
> >+    NET_CLIENT_USER,
> >+#endif
> >+    NET_CLIENT_TAP,
> >+    NET_CLIENT_SOCKET,
> >+#ifdef CONFIG_VDE
> >+    NET_CLIENT_VDE,
> >+#endif
> >+    NET_CLIENT_DUMP,
> >+
> >+    NET_CLIENT_LAST
> >+};
> >+
> >+QEMU_ENUM_DECL(qemu_net_type);
> >+QEMU_ENUM_IMPL(qemu_net_type, NET_CLIENT_LAST,
> >+	       "none",
> >+	       "nic",
> >+#ifdef CONFIG_SLIRP
> >+	       "user",
> >+#endif
> >+	       "tap",
> >+	       "socket",
> >+#ifdef CONFIG_VDE
> >+	       "vde",
> >+#endif
> >+	       "dump");
> >+
> >  /***********************************************************/
> >  /* network device redirectors */
> >
> >@@ -844,18 +874,15 @@ typedef int (*net_client_init_func)(QemuOpts *opts,
> >  #define NET_MAX_DESC 20
> >
> >  static const struct {
> >-    const char *type;
> >      net_client_init_func init;
> >      QemuOptDesc desc[NET_MAX_DESC];
> >  } net_client_types[] = {
> >   
> 
> I think:
> 
>  [NET_CLIENT_NONE] = {
>             .desc = {...}
> },
> 
> Would be a bit more robust than relying on explicit ordering.

Ah, I didn't know you could do that for array initializers. That
should result in even stronger compile time validation which is always
nice.

Daniel
-- 
|: Red Hat, Engineering, London    -o-   http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://deltacloud.org :|
|: http://autobuild.org        -o-         http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505  -o-   F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [Qemu-devel] [PATCH 11/19] Add a query-devices command to QMP
  2010-06-07 14:42 ` [Qemu-devel] [PATCH 11/19] Add a query-devices " Daniel P. Berrange
@ 2010-06-07 15:14   ` Anthony Liguori
  2010-06-07 16:03     ` Daniel P. Berrange
  0 siblings, 1 reply; 62+ messages in thread
From: Anthony Liguori @ 2010-06-07 15:14 UTC (permalink / raw)
  To: Daniel P. Berrange; +Cc: qemu-devel

On 06/07/2010 09:42 AM, Daniel P. Berrange wrote:
> Adds a command to QMP called 'query-devices' to allow for discovery
> of all devices known to the QEMU binary. THis is inteded to replace
> use of the '-device ?' and '-device devtype,?' command line args
>
> The data format is designed to allow easy extension to support more
> data:
>    

query-qdm?

Regards,

Anthony Liguori

>      [
>          {
>              "name": "virtio-9p-pci",
>              "creatable": true,
>              "bus": "PCI",
>              "props": [
>                  {
>                      "name": "indirect_desc",
>                      "type": "bit",
>                      "info": "on/off"
>                  },
>                  {
>                      "name": "mount_tag",
>                      "type": "string",
>                      "info": "string"
>                  },
>                  {
>                      "name": "fsdev",
>                      "type": "string",
>                      "info": "string"
>                  }
>              ]
>          },
>          {
>              "name": "virtio-balloon-pci",
>              "creatable": true,
>              "bus": "PCI",
>              "props": [
>                  {
>                      "name": "indirect_desc",
>                      "type": "bit",
>                      "info": "on/off"
>                  }
>              ]
>          },
>          ...
>      ]
>
> No legacy readline monitor output is provided.
>
> Signed-off-by: Daniel P. Berrange<berrange@redhat.com>
> ---
>   hw/qdev.c |  146 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>   hw/qdev.h |    2 +
>   monitor.c |    8 +++
>   3 files changed, 156 insertions(+), 0 deletions(-)
>
> diff --git a/hw/qdev.c b/hw/qdev.c
> index 1186dfa..0a10c3c 100644
> --- a/hw/qdev.c
> +++ b/hw/qdev.c
> @@ -29,6 +29,7 @@
>   #include "qdev.h"
>   #include "sysemu.h"
>   #include "monitor.h"
> +#include "qjson.h"
>
>   static int qdev_hotplug = 0;
>
> @@ -810,3 +811,148 @@ int do_device_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
>       }
>       return qdev_unplug(dev);
>   }
> +
> +static const char *qdev_property_type_to_string(int type) {
> +    switch (type) {
> +    case PROP_TYPE_UNSPEC:
> +	return "unknown";
> +    case PROP_TYPE_UINT8:
> +	return "uint8";
> +    case PROP_TYPE_UINT16:
> +	return "uint16";
> +    case PROP_TYPE_UINT32:
> +	return "uint32";
> +    case PROP_TYPE_INT32:
> +	return "int32";
> +    case PROP_TYPE_UINT64:
> +	return "uint64";
> +    case PROP_TYPE_TADDR:
> +	return "taddr";
> +    case PROP_TYPE_MACADDR:
> +	return "macaddr";
> +    case PROP_TYPE_DRIVE:
> +	return "drive";
> +    case PROP_TYPE_CHR:
> +	return "chr";
> +    case PROP_TYPE_STRING:
> +	return "string";
> +    case PROP_TYPE_NETDEV:
> +	return "netdev";
> +    case PROP_TYPE_VLAN:
> +	return "vlan";
> +    case PROP_TYPE_PTR:
> +	return "pointer";
> +    case PROP_TYPE_BIT:
> +	return "bit";
> +    }
> +    return NULL;
> +}
> +
> +
> +/*
> + * Describe capabilities of all devices registered with qdev
> + *
> + * The returned output is a QList, each element is a QDict
> + * describing a single device type. The valid keys for the
> + * device dictionary are
> + *
> + *  - "name": the short name of the device
> + *  - "bus": the name of the bus type for the device
> + *  - "alias": an alias by which the device is also known (optional)
> + *  - "description": a long description the device (optional)
> + *  - "props": a list of device properties
> + *  - "creatable": whether this device can be created on command line
> + *
> + * The 'props' list is a QList, with each element being a
> + * QDict describing a single property of the device. The
> + * valid property keys are
> + *
> + *  - "name": the short name of the property
> + *  - "info": short description of the property
> + *  - "type": the data type of the property value
> + *
> + * An example:
> + *
> + *   [
> + *       {
> + *           "name": "virtio-9p-pci",
> + *           "creatable": true,
> + *           "bus": "PCI",
> + *           "props": [
> + *               {
> + *                   "name": "indirect_desc",
> + *                   "type": "bit",
> + *                   "info": "on/off"
> + *               },
> + *               {
> + *                   "name": "mount_tag",
> + *                   "type": "string",
> + *                   "info": "string"
> + *               },
> + *               {
> + *                   "name": "fsdev",
> + *                   "type": "string",
> + *                   "info": "string"
> + *               }
> + *           ]
> + *       },
> + *       {
> + *           "name": "virtio-balloon-pci",
> + *           "creatable": true,
> + *           "bus": "PCI",
> + *           "props": [
> + *               {
> + *                   "name": "indirect_desc",
> + *                   "type": "bit",
> + *                   "info": "on/off"
> + *               }
> + *           ]
> + *       },
> + *       ....
> + *   ]
> + */
> +void do_info_devices(Monitor *mon, QObject **data)
> +{
> +    DeviceInfo *info;
> +    QList *devs = qlist_new();
> +
> +    for (info = device_info_list; info != NULL; info = info->next) {
> +	QObject *dev;
> +	QList *props = qlist_new();
> +	Property *prop;
> +
> +	for (prop = info->props; prop&&  prop->name; prop++) {
> +	    QObject *entry;
> +	    /*
> +	     * TODO Properties without a parser are just for dirty hacks.
> +	     * qdev_prop_ptr is the only such PropertyInfo.  It's marked
> +	     * for removal.  This conditional should be removed along with
> +	     * it.
> +	     */
> +	    if (!prop->info->parse) {
> +		continue;           /* no way to set it, don't show */
> +	    }
> +
> +	    const char *type = qdev_property_type_to_string(prop->info->type);
> +
> +	    entry = qobject_from_jsonf("{ 'name': %s, 'info': %s, 'type': %s }",
> +				       prop->name, prop->info->name, type);
> +
> +	    qlist_append_obj(props, entry);
> +	}
> +
> +	dev = qobject_from_jsonf("{ 'name': %s, 'bus': %s, 'props': %p, 'creatable': %i }",
> +				 info->name,
> +				 info->bus_info->name,
> +				 props,
> +				 info->no_user ? 0 : 1);
> +	if (info->alias)
> +	    qdict_put_obj((QDict*)dev, "alias", QOBJECT(qstring_from_str(info->alias)));
> +	if (info->desc)
> +	    qdict_put_obj((QDict*)dev, "description", QOBJECT(qstring_from_str(info->desc)));
> +
> +	qlist_append_obj(devs, dev);
> +    }
> +
> +    *data = QOBJECT(devs);
> +}
> diff --git a/hw/qdev.h b/hw/qdev.h
> index a44060e..fe6f981 100644
> --- a/hw/qdev.h
> +++ b/hw/qdev.h
> @@ -280,6 +280,8 @@ void qdev_prop_set_defaults(DeviceState *dev, Property *props);
>   void qdev_prop_register_global_list(GlobalProperty *props);
>   void qdev_prop_set_globals(DeviceState *dev);
>
> +void do_info_devices(Monitor *mon, QObject **data);
> +
>   /* This is a nasty hack to allow passing a NULL bus to qdev_create.  */
>   extern struct BusInfo system_bus_info;
>
> diff --git a/monitor.c b/monitor.c
> index b6aa2b4..13f70a0 100644
> --- a/monitor.c
> +++ b/monitor.c
> @@ -2458,6 +2458,14 @@ static const mon_cmd_t info_cmds[] = {
>           .mhandler.info_new = do_info_machines,
>       },
>       {
> +        .name       = "devices",
> +        .args_type  = "",
> +        .params     = "",
> +        .help       = "show the registered QDev devices",
> +        .user_print = monitor_user_noop,
> +        .mhandler.info_new = do_info_devices,
> +    },
> +    {
>           .name       = "commands",
>           .args_type  = "",
>           .params     = "",
>    

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [Qemu-devel] [PATCH 16/19] Add a query-netdev command to QMP
  2010-06-07 14:42 ` [Qemu-devel] [PATCH 16/19] Add a query-netdev command to QMP Daniel P. Berrange
@ 2010-06-07 15:15   ` Anthony Liguori
  2010-06-26  7:32     ` Markus Armbruster
  2010-06-07 19:13   ` Miguel Di Ciurcio Filho
  1 sibling, 1 reply; 62+ messages in thread
From: Anthony Liguori @ 2010-06-07 15:15 UTC (permalink / raw)
  To: Daniel P. Berrange; +Cc: qemu-devel

On 06/07/2010 09:42 AM, Daniel P. Berrange wrote:
> This adds a new QMP command called query-netdev to provide information
> about the available netdev backends in the QEMU binary. There is no
> existing '-netdev ?' support, but if there was, this would obsolete it
>
> The data format looks like
>
>      [
>          {
>              "name": "user",
>              "props": [
>                  {
>                      "name": "type",
>                      "help": "net client type (nic, tap etc.)",
>                      "type": "string"
>                  },
>    

I'm not sure it's a good idea to expose the help text.  That bakes it 
into the ABI which seems bad.

Regards,

Anthony Liguori

>                  {
>                      "name": "name",
>                      "help": "identifier for monitor commands",
>                      "type": "string"
>                  },
>                  {
>                      "name": "hostname",
>                      "help": "client hostname reported by the builtin DHCP server",
>                      "type": "string"
>                  },
>                  ...
>              ]
>          }
>          {
>              "name": "tap",
>              "props": [
>                  {
>                      "name": "type",
>                      "help": "net client type (nic, tap etc.)",
>                      "type": "string"
>                  },
>                  {
>                      "name": "ifname",
>                      "help": "interface name",
>                      "type": "string"
>                  },
>                  ...
>              ]
>          }
>          ...
>      ]
>
> Signed-off-by: Daniel P. Berrange<berrange@redhat.com>
> ---
>   monitor.c     |    8 ++++++++
>   net.c         |   49 +++++++++++++++++++++++++++++++++++++++++++++++++
>   net.h         |    2 ++
>   qemu-option.c |    4 ++++
>   qemu-option.h |    4 ++++
>   5 files changed, 67 insertions(+), 0 deletions(-)
>
> diff --git a/monitor.c b/monitor.c
> index 1c5157d..19f42f3 100644
> --- a/monitor.c
> +++ b/monitor.c
> @@ -2552,6 +2552,14 @@ static const mon_cmd_t info_cmds[] = {
>           .mhandler.info_new = do_info_argv,
>       },
>       {
> +        .name       = "netdev",
> +        .args_type  = "",
> +        .params     = "",
> +        .help       = "list valid netdev backend types",
> +        .user_print = monitor_user_noop,
> +        .mhandler.info_new = do_info_netdev,
> +    },
> +    {
>           .name       = "network",
>           .args_type  = "",
>           .params     = "",
> diff --git a/net.c b/net.c
> index 5349001..90929d4 100644
> --- a/net.c
> +++ b/net.c
> @@ -36,6 +36,8 @@
>   #include "qemu-common.h"
>   #include "qemu_socket.h"
>   #include "hw/qdev.h"
> +#include "qjson.h"
> +#include "qlist.h"
>
>   static QTAILQ_HEAD(, VLANState) vlans;
>   static QTAILQ_HEAD(, VLANClientState) non_vlan_clients;
> @@ -1080,6 +1082,53 @@ static const struct {
>   };
>   verify(ARRAY_SIZE(net_client_types) == NET_CLIENT_LAST);
>
> +
> +void do_info_netdev(Monitor *mon, QObject **data)
> +{
> +    QList *backends = qlist_new();
> +    int i, j;
> +
> +    for (i = 0; i<  ARRAY_SIZE(net_client_types) ; i++) {
> +	QObject *backend;
> +	QList *props = qlist_new();
> +
> +	if (i == NET_CLIENT_NIC ||
> +	    i == NET_CLIENT_DUMP||
> +	    i == NET_CLIENT_NONE)
> +	    continue;
> +
> +	for (j = 0 ; net_client_types[i].desc[j].name != NULL ; j++) {
> +	    const QemuOptDesc *desc = net_client_types[i].desc + j;
> +	    QObject *prop;
> +
> +	    if (strcmp(desc->name, "vlan") == 0)
> +		continue;
> +
> +	    if (desc->help) {
> +		prop = qobject_from_jsonf("{ 'name': %s, 'type': %s, 'help': %s }",
> +					  desc->name,
> +					  qemu_opt_type_to_string(desc->type),
> +					  desc->help);
> +	    } else {
> +		prop = qobject_from_jsonf("{ 'name': %s, 'type': %s }",
> +					  desc->name,
> +					  qemu_opt_type_to_string(desc->type));
> +	    }
> +
> +	    qlist_append_obj(props, prop);
> +	}
> +
> +	backend = qobject_from_jsonf("{ 'name': %s, 'props': %p }",
> +				     qemu_net_type_to_string(i),
> +				     props);
> +
> +	qlist_append_obj(backends, backend);
> +    }
> +
> +    *data = qobject_from_jsonf("{ 'backends': %p }", backends);
> +}
> +
> +
>   int net_client_init(Monitor *mon, QemuOpts *opts, int is_netdev)
>   {
>       const char *name;
> diff --git a/net.h b/net.h
> index b83f615..9c0e385 100644
> --- a/net.h
> +++ b/net.h
> @@ -167,6 +167,8 @@ void net_host_device_remove(Monitor *mon, const QDict *qdict);
>   int do_netdev_add(Monitor *mon, const QDict *qdict, QObject **ret_data);
>   int do_netdev_del(Monitor *mon, const QDict *qdict, QObject **ret_data);
>
> +void do_info_netdev(Monitor *mon, QObject **data);
> +
>   #define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup"
>   #define DEFAULT_NETWORK_DOWN_SCRIPT "/etc/qemu-ifdown"
>   #ifdef __sun__
> diff --git a/qemu-option.c b/qemu-option.c
> index bb9cc43..f132a9b 100644
> --- a/qemu-option.c
> +++ b/qemu-option.c
> @@ -32,6 +32,10 @@
>   #include "qemu-option.h"
>   #include "qerror.h"
>
> +QEMU_ENUM_IMPL(qemu_opt_type, QEMU_OPT_LAST,
> +	       "string", "bool", "number",
> +	       "size", "enum");
> +
>   /*
>    * Extracts the name of an option from the parameter string (p points at the
>    * first byte of the option name)
> diff --git a/qemu-option.h b/qemu-option.h
> index 3540a9b..9382cc3 100644
> --- a/qemu-option.h
> +++ b/qemu-option.h
> @@ -28,6 +28,7 @@
>
>   #include<stdint.h>
>   #include "qemu-queue.h"
> +#include "qemu-enum.h"
>   #include "qdict.h"
>
>   enum QEMUOptionParType {
> @@ -90,7 +91,10 @@ enum QemuOptType {
>       QEMU_OPT_NUMBER,      /* simple number                                        */
>       QEMU_OPT_SIZE,        /* size, accepts (K)ilo, (M)ega, (G)iga, (T)era postfix */
>       QEMU_OPT_ENUM,        /* int, from user string validated against an enum      */
> +
> +    QEMU_OPT_LAST,
>   };
> +QEMU_ENUM_DECL(qemu_opt_type);
>
>   typedef struct QemuOptDesc {
>       const char *name;
>    

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [Qemu-devel] [PATCH 00/19] RFC: Reporting QEMU binary capabilities
  2010-06-07 15:10   ` Daniel P. Berrange
@ 2010-06-07 15:18     ` Anthony Liguori
  0 siblings, 0 replies; 62+ messages in thread
From: Anthony Liguori @ 2010-06-07 15:18 UTC (permalink / raw)
  To: Daniel P. Berrange; +Cc: qemu-devel

On 06/07/2010 10:10 AM, Daniel P. Berrange wrote:
> On Mon, Jun 07, 2010 at 09:58:11AM -0500, Anthony Liguori wrote:
>    
>> On 06/07/2010 09:42 AM, Daniel P. Berrange wrote:
>>      
>>> As everyone here agrees, having management apps parse -help output
>>> to determine the QEMU capabilities is not at all nice, because it
>>> is an ill-defined&   fragile data format. Looking more broadly these
>>> same issues apply to all the other command line options that accept
>>> a '?' flag for querying capabilities.
>>>
>>> We have a very nice structured data format we could be using for
>>> this: JSON. What's lacking is code to output all this information
>>> in the JSON format. This patch series can thus be summarized as
>>> 'JSON for everything'
>>>
>>>        
>> I'm slightly skeptical that JSON is the right format for this TBH.
>>
>>      
>>> For reference, here is the full list of information libvirt currently
>>> queries from QEMU:
>>>
>>>    * Detection of command line flags (-help parsing)
>>>
>>>      -no-kqemu, -no-kvm, -enable-kvm, -no-reboot
>>>      -name, -uuid, -xen-domid, -domid, -drive
>>>      -vga, -std-vga, -pcidevice, -mem-path
>>>      -chardev, -balloon, -device, -rtc, -rtc-td-hack
>>>      -no-hpet, -no-kvm-pit-reinjection, -tdf
>>>      -fsdev -sdl
>>>
>>>        
>> Most of these things can be associated with a config option and/or a
>> version.
>>      
> If the 'qemu-config.c' file had parity with the config options
> that were available as argv then I would not suggest including
> the argv data at all.

I meant config-*.h. I can certainly imagine an query-config command to 
return a builtin copy of the build configuration.

If you know the qemu configuration along with the version, you basically 
know everything you need to know about the supported options (beyond 
what is configurable by the user).

Regards,

Anthony Liguori


>   This patchset is an attempt to provide
> all the information we need based on current state of the QEMU
> codebase, since qemu-config is seriously incomplete at this time.
> If we instead want to make a concerted effort to finish porting
> all existing config options over to the new style qemu-config.c
> format, that would definitely be much nicer than reporting about
> argv.
>
> Regards,
> Daniel
>    

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [Qemu-devel] Re: [PATCH 02/19] Add support for compile time assertions
  2010-06-07 14:42 ` [Qemu-devel] [PATCH 02/19] Add support for compile time assertions Daniel P. Berrange
@ 2010-06-07 15:35   ` Paolo Bonzini
  0 siblings, 0 replies; 62+ messages in thread
From: Paolo Bonzini @ 2010-06-07 15:35 UTC (permalink / raw)
  To: Daniel P. Berrange; +Cc: qemu-devel

On 06/07/2010 04:42 PM, Daniel P. Berrange wrote:
> The verify.h header, taken from GNULIB, provides macros for
> doing compile time assertions.
>
> There are two main variants
>
> For use in global namespace (eg header files, or global decls)
>
>    verify(CONDITION)

There is QEMU_BUILD_BUG_ON already.

Paolo

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [Qemu-devel] Re: [PATCH 13/19] Add a query-target command to QMP
  2010-06-07 14:42 ` [Qemu-devel] [PATCH 13/19] Add a query-target " Daniel P. Berrange
@ 2010-06-07 15:43   ` Paolo Bonzini
  0 siblings, 0 replies; 62+ messages in thread
From: Paolo Bonzini @ 2010-06-07 15:43 UTC (permalink / raw)
  To: Daniel P. Berrange; +Cc: qemu-devel

On 06/07/2010 04:42 PM, Daniel P. Berrange wrote:
> +#ifdef CONFIG_KVM
> +    qlist_append_obj(engines, qobject_from_jsonf("{ 'name': 'kvm' }"));
> +#endif
> +#ifdef CONFIG_XEN
> +    qlist_append_obj(engines, qobject_from_jsonf("{ 'name': 'xen' }"));
> +#endif

I suggest using kvm_available() and xen_available(), so that any 
cut-and-paste typos do not go undetected in the future.

Paolo

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [Qemu-devel] Re: [PATCH 00/19] RFC: Reporting QEMU binary capabilities
  2010-06-07 14:58 ` [Qemu-devel] [PATCH 00/19] RFC: Reporting QEMU binary capabilities Anthony Liguori
  2010-06-07 15:10   ` Daniel P. Berrange
@ 2010-06-07 16:02   ` Paolo Bonzini
  2010-06-07 16:03     ` Anthony Liguori
  1 sibling, 1 reply; 62+ messages in thread
From: Paolo Bonzini @ 2010-06-07 16:02 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: qemu-devel

On 06/07/2010 04:58 PM, Anthony Liguori wrote:
>
> A query-argv is a really bad idea IMHO.

Agreed.  Instead we should work towards improve the configurability of 
QEMU via monitor commands or -readconfig.  libvirt is already using 
-nodefaults on recent QEMU, so this is not _that_ far away.

Paolo

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [Qemu-devel] [PATCH 11/19] Add a query-devices command to QMP
  2010-06-07 15:14   ` Anthony Liguori
@ 2010-06-07 16:03     ` Daniel P. Berrange
  2010-06-26  7:12       ` Markus Armbruster
  0 siblings, 1 reply; 62+ messages in thread
From: Daniel P. Berrange @ 2010-06-07 16:03 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: qemu-devel

On Mon, Jun 07, 2010 at 10:14:00AM -0500, Anthony Liguori wrote:
> On 06/07/2010 09:42 AM, Daniel P. Berrange wrote:
> >Adds a command to QMP called 'query-devices' to allow for discovery
> >of all devices known to the QEMU binary. THis is inteded to replace
> >use of the '-device ?' and '-device devtype,?' command line args
> >
> >The data format is designed to allow easy extension to support more
> >data:
> >   
> 
> query-qdm?

Ahh, I missed that because it is not ported to QMP yet. This patch 
should nicely dovetail with that command.

Daniel
-- 
|: Red Hat, Engineering, London    -o-   http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://deltacloud.org :|
|: http://autobuild.org        -o-         http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505  -o-   F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [Qemu-devel] Re: [PATCH 00/19] RFC: Reporting QEMU binary capabilities
  2010-06-07 16:02   ` [Qemu-devel] " Paolo Bonzini
@ 2010-06-07 16:03     ` Anthony Liguori
  0 siblings, 0 replies; 62+ messages in thread
From: Anthony Liguori @ 2010-06-07 16:03 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: qemu-devel

On 06/07/2010 11:02 AM, Paolo Bonzini wrote:
> On 06/07/2010 04:58 PM, Anthony Liguori wrote:
>>
>> A query-argv is a really bad idea IMHO.
>
> Agreed.  Instead we should work towards improve the configurability of 
> QEMU via monitor commands or -readconfig.  libvirt is already using 
> -nodefaults on recent QEMU, so this is not _that_ far away.

I've also got a series that's just about ready to go based on Glauber's 
-machine option which converts quite a lot of existing options to config 
based.

Regards,

Anthony Liguori

> Paolo

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [Qemu-devel] Re: [PATCH 19/19] Add a -capabilities argument to allow easy query for static QEMU info
  2010-06-07 14:42 ` [Qemu-devel] [PATCH 19/19] Add a -capabilities argument to allow easy query for static QEMU info Daniel P. Berrange
@ 2010-06-07 16:04   ` Paolo Bonzini
  2010-06-07 16:09     ` Daniel P. Berrange
  2010-06-07 16:04   ` [Qemu-devel] " Anthony Liguori
  1 sibling, 1 reply; 62+ messages in thread
From: Paolo Bonzini @ 2010-06-07 16:04 UTC (permalink / raw)
  To: Daniel P. Berrange; +Cc: qemu-devel

On 06/07/2010 04:42 PM, Daniel P. Berrange wrote:
> The QMP monitor provides a number of commands for querying info about
> the QEMU binary capabilities. Given that these commands don't take
> any options and just return static data, requiring the use of QMP is
> unnecessarily onerous. This adds a new '-capabilities' command line
> argument as a syntactic sugar for accessing the QMP commands that
> just return static QEMU binary capabilities.
>
> Setting the '-capabilities' argument causes QEMU to output the requested
> data on stdout, pretty printed in JSON format. The argument expects an
> associated value to identify the data to be printed. This can be one of
> the strings version|machines|devices|cputypes|target|commands|argv|netdev
>
> To query all possible data at once, the shorthand 'all' is allowed.
>
> The output is a QDict where the key is the type of data requested, and
> the value is the JSON data from the associated monitor command. For
> example:

A lot of this patch and the other monitor.c changes you had can likely 
be moved in a capabilities.c file?

Paolo

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [Qemu-devel] [PATCH 19/19] Add a -capabilities argument to allow easy query for static QEMU info
  2010-06-07 14:42 ` [Qemu-devel] [PATCH 19/19] Add a -capabilities argument to allow easy query for static QEMU info Daniel P. Berrange
  2010-06-07 16:04   ` [Qemu-devel] " Paolo Bonzini
@ 2010-06-07 16:04   ` Anthony Liguori
  1 sibling, 0 replies; 62+ messages in thread
From: Anthony Liguori @ 2010-06-07 16:04 UTC (permalink / raw)
  To: Daniel P. Berrange; +Cc: qemu-devel

On 06/07/2010 09:42 AM, Daniel P. Berrange wrote:
> The QMP monitor provides a number of commands for querying info about
> the QEMU binary capabilities. Given that these commands don't take
> any options and just return static data, requiring the use of QMP is
> unnecessarily onerous. This adds a new '-capabilities' command line
> argument as a syntactic sugar for accessing the QMP commands that
> just return static QEMU binary capabilities.
>
> Setting the '-capabilities' argument causes QEMU to output the requested
> data on stdout, pretty printed in JSON format. The argument expects an
> associated value to identify the data to be printed. This can be one of
> the strings version|machines|devices|cputypes|target|commands|argv|netdev
>
> To query all possible data at once, the shorthand 'all' is allowed.
>
> The output is a QDict where the key is the type of data requested, and
> the value is the JSON data from the associated monitor command. For
> example:
>    

I think the idea is good but I think we should use a different name as 
QMP capabilities has a different meaning.

Maybe features?

Regards,

Anthony Liguori

>    $ qemu -capabilities all
>    {
>      "machines": [
>          {
>              "name": "pc-0.13",
>              "description": "Standard PC",
>              "default": 0
>          },
>          {
>              "name": "pc",
>              ....
>          }
>          ....
>       }
>       "version": {
>          "qemu": {
>              "micro": 50,
>              "minor": 12,
>              "major": 0
>          },
>          "package": ""
>       },
>       "target": {
>          "arch": "i386",
>          "wordsize": 32,
>       ...
>     }
>
> Signed-off-by: Daniel P. Berrange<berrange@redhat.com>
> ---
>   monitor.c       |    4 +-
>   monitor.h       |    2 +
>   qemu-options.hx |    9 +++++
>   vl.c            |  100 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>   4 files changed, 113 insertions(+), 2 deletions(-)
>
> diff --git a/monitor.c b/monitor.c
> index 6203f75..401a27a 100644
> --- a/monitor.c
> +++ b/monitor.c
> @@ -711,7 +711,7 @@ static void do_info_version_print(Monitor *mon, const QObject *data)
>    *
>    * { qemu: { "major": 0, "minor": 11, "micro": 5 }, "package": "" }
>    */
> -static void do_info_version(Monitor *mon, QObject **ret_data)
> +void do_info_version(Monitor *mon, QObject **ret_data)
>   {
>       const char *version = QEMU_VERSION;
>       int major = 0, minor = 0, micro = 0;
> @@ -760,7 +760,7 @@ static QObject *get_cmd_dict(const char *name)
>       return qobject_from_jsonf("{ 'name': %s }", p);
>   }
>
> -static void do_info_commands(Monitor *mon, QObject **ret_data)
> +void do_info_commands(Monitor *mon, QObject **ret_data)
>   {
>       QList *cmd_list;
>       const mon_cmd_t *cmd;
> diff --git a/monitor.h b/monitor.h
> index 733485f..dc376af 100644
> --- a/monitor.h
> +++ b/monitor.h
> @@ -57,5 +57,7 @@ typedef void (MonitorCompletion)(void *opaque, QObject *ret_data);
>   void monitor_set_error(Monitor *mon, QError *qerror);
>
>   void do_info_argv(Monitor *mon, QObject **data);
> +void do_info_version(Monitor *mon, QObject **ret_data);
> +void do_info_commands(Monitor *mon, QObject **ret_data);
>
>   #endif /* !MONITOR_H */
> diff --git a/qemu-options.hx b/qemu-options.hx
> index a6928b7..5f82347 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -27,6 +27,15 @@ STEXI
>   Display version information and exit
>   ETEXI
>
> +DEF("capabilities", HAS_ARG, QEMU_OPTION_capabilities,
> +    "-capabilities   all|version|machines|devices|cputypes|target|commands|argv|netdev\n"
> +    "                display capabilities of the QEMU binary and exit\n", QEMU_ARCH_ALL)
> +STEXI
> +@item -capabilities  all|version|machines|devices|cputypes|target|commands|argv|netdev
> +@findex -capabilities
> +Display capabilities of the QEMU binary and exit
> +ETEXI
> +
>   DEF("M", HAS_ARG, QEMU_OPTION_M,
>       "-M machine      select emulated machine (-M ? for list)\n", QEMU_ARCH_ALL)
>   STEXI
> diff --git a/vl.c b/vl.c
> index de010cc..1f165a1 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -1988,6 +1988,97 @@ static void version(void)
>   }
>
>
> +enum {
> +    QEMU_CAPS_VERSION,
> +    QEMU_CAPS_MACHINES,
> +    QEMU_CAPS_DEVICES,
> +    QEMU_CAPS_CPUTYPES,
> +    QEMU_CAPS_TARGET,
> +    QEMU_CAPS_COMMANDS,
> +    QEMU_CAPS_ARGV,
> +    QEMU_CAPS_NETDEV,
> +    QEMU_CAPS_CONFIG,
> +
> +    QEMU_CAPS_LAST
> +};
> +
> +QEMU_ENUM_DECL(qemu_caps_flag);
> +QEMU_ENUM_IMPL(qemu_caps_flag, QEMU_CAPS_LAST,
> +               "version",
> +               "machines",
> +               "devices",
> +               "cputypes",
> +               "target",
> +               "commands",
> +               "argv",
> +               "netdev",
> +               "config");
> +
> +static int qemu_caps_flags_from_string(const char *flagsstr)
> +{
> +    if (strcmp(flagsstr, "all") == 0)
> +        return ~0;
> +    else {
> +        int i = qemu_caps_flag_from_string(flagsstr);
> +        if (i<  0)
> +            return 0;
> +        return (1<<  i);
> +    }
> +
> +    return 0;
> +}
> +typedef void (*qemu_caps_handler)(Monitor *mon, QObject **);
> +
> +/* Binding capabilities to a subset of monitor commands.
> + * The commands must only use static binary state, no
> + * VM runtime state and must accept mon=NULL
> + */
> +static const qemu_caps_handler qemu_caps_handlers[] = {
> +    do_info_version,
> +    do_info_machines,
> +    do_info_devices,
> +    do_info_cpu_types,
> +    do_info_target,
> +    do_info_commands,
> +    do_info_argv,
> +    do_info_netdev,
> +    do_info_config,
> +};
> +verify(ARRAY_SIZE(qemu_caps_handlers) == QEMU_CAPS_LAST);
> +
> +static void qemu_show_caps(const char *flagsstr)
> +{
> +    QDict *data = qdict_new();
> +    QString *json;
> +    int i;
> +    int flags;
> +
> +    flags = qemu_caps_flags_from_string(flagsstr);
> +    if (flags == 0) {
> +        fprintf(stderr, "Unknown capabilities '%s'\n", flagsstr);
> +        exit(1);
> +    }
> +
> +    for (i = 0 ; i<  QEMU_CAPS_LAST ; i++) {
> +        if (flags&  (1<<  i)) {
> +            QObject *val;
> +            qemu_caps_handler handler = qemu_caps_handlers[i];
> +            const char *name = qemu_caps_flag_to_string(i);
> +            (*handler)(NULL,&val);
> +            qdict_put_obj(data, name, val);
> +        }
> +    }
> +    json = qobject_to_json_pretty(QOBJECT(data));
> +    assert(json != NULL);
> +
> +    qstring_append_chr(json, '\n');
> +    fprintf(stdout, qstring_get_str(json));
> +
> +    QDECREF(json);
> +
> +}
> +
> +
>   /**
>    * do_info_argv():
>    *
> @@ -2647,6 +2738,7 @@ int main(int argc, char **argv, char **envp)
>   #endif
>       int show_vnc_port = 0;
>       int defconfig = 1;
> +    const char *showcaps = NULL;
>
>       error_set_progname(argv[0]);
>
> @@ -3020,6 +3112,9 @@ int main(int argc, char **argv, char **envp)
>                   version();
>                   exit(0);
>                   break;
> +            case QEMU_OPTION_capabilities:
> +                showcaps = optarg;
> +                break;
>               case QEMU_OPTION_m: {
>                   uint64_t value;
>                   char *ptr;
> @@ -3785,6 +3880,11 @@ int main(int argc, char **argv, char **envp)
>       if (qemu_opts_foreach(&qemu_device_opts, device_help_func, NULL, 0) != 0)
>           exit(0);
>
> +    if (showcaps) {
> +        qemu_show_caps(showcaps);
> +        exit(0);
> +    }
> +
>       if (watchdog) {
>           i = select_watchdog(watchdog);
>           if (i>  0)
>    

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [Qemu-devel] [PATCH 00/19] RFC: Reporting QEMU binary capabilities
  2010-06-07 14:42 [Qemu-devel] [PATCH 00/19] RFC: Reporting QEMU binary capabilities Daniel P. Berrange
                   ` (19 preceding siblings ...)
  2010-06-07 14:58 ` [Qemu-devel] [PATCH 00/19] RFC: Reporting QEMU binary capabilities Anthony Liguori
@ 2010-06-07 16:07 ` Anthony Liguori
  2010-06-09 20:25   ` Luiz Capitulino
  2010-06-26  6:45 ` Markus Armbruster
  21 siblings, 1 reply; 62+ messages in thread
From: Anthony Liguori @ 2010-06-07 16:07 UTC (permalink / raw)
  To: Daniel P. Berrange; +Cc: qemu-devel

Hi Daniel,

On 06/07/2010 09:42 AM, Daniel P. Berrange wrote:
> As everyone here agrees, having management apps parse -help output
> to determine the QEMU capabilities is not at all nice, because it
> is an ill-defined&  fragile data format. Looking more broadly these
> same issues apply to all the other command line options that accept
> a '?' flag for querying capabilities.
>
> We have a very nice structured data format we could be using for
> this: JSON. What's lacking is code to output all this information
> in the JSON format. This patch series can thus be summarized as
> 'JSON for everything'
>    

For the most part, this series looks pretty nice.

I think my only real objection is the query-argv bits.  The enums are a 
bit awkward to define but I understand the value of it and I can't think 
of a better way to do it.

Regards,

Anthony Liguori

> For reference, here is the full list of information libvirt currently
> queries from QEMU:
>
>    * Detection of command line flags (-help parsing)
>
>      -no-kqemu, -no-kvm, -enable-kvm, -no-reboot
>      -name, -uuid, -xen-domid, -domid, -drive
>      -vga, -std-vga, -pcidevice, -mem-path
>      -chardev, -balloon, -device, -rtc, -rtc-td-hack
>      -no-hpet, -no-kvm-pit-reinjection, -tdf
>      -fsdev -sdl
>
>    * Detection of parameters (-help parsing)
>
>       -drive format=
>       -drive boot=
>       -drive serial=
>       -drive cache=
>       -cpu cores=, threads=, sockets=
>       -netdev vhost=
>
>    * Detection of parameter values (-help parsing)
>
>       -drive cache=writethrough|writeback|none
>         vs
>       -drive cache=default|on|off
>
>    * Version number  (-help parsing)
>
>      -netdev  + 0.13.0
>
>      0.9.0  for VNC syntax
>
>      0.10.0 for vnet hdr
>
>    * Parse -M ?  output to get list of machine types + aliases
>
>    * Parse -device pci-assign,? to check for 'configfd' parameter
>
>    * Parse -cpu ?  to get list of named CPU types
>
>    * Parse binary name (qemu-system-XXXX) to guess arch of target
>
>
> This isn't an 100% exhaustive list of things that we would like
> to be able to get access to though. It can likely cover all of
> the following:
>
>   * Version
>
>        QEMU major, minor, micro numbers. KVM version. Package
>        version
>
>   * Devices
>
>        List of device names. Parameter names. Parameter value
>        data types. Allowed strings for enums
>
>   * Arguments
>
>        List of command line arguments. Parameter names. Parameter
>        value data types. Allowed strings for enums
>
>   * Machine types
>
>        List of names + aliases
>        List of default devices in machine
>
>   * CPU types
>
>        List of names, associated feature flags, all allowed
>        feature flags
>
>   * Target info
>
>        Arch name, wordsize
>
>   * Monitor commands
>
>        List of all monitor commands. Parameter names. Parameter
>        value data types. Allowed strings for enums
>
>   * Block device backends
>
>        List of all block device backends. Parameter names.
>        Parameter value data types. Allowed strings for enums
>
>   * Netdev device backends
>
>        List of all netdev device backends. Parameter names.
>        Parameter value data types. Allowed strings for enums
>
>   * Chardev device backends
>
>        List of all chardev device backends. Parameter names.
>        Parameter value data types. Allowed strings for enums
>
>
> This patch series attempts to satisfy as much of this as is
> feasible with the current QEMU codebase structure. The series
> comprises four stages
>
>   * Some basic infrastructure. Support for JSON pretty printing.
>     Introduction of standardized helpers for converting enums
>     to/from strings. Introduction of an 'enum' data type for
>     QemuOpt to expose a formal list of valid values&  simplify
>     config handling / parsing. Compile time assertion checking
>
>   * Convert driver, netdev&  rtc config options to use the new
>     enum data type for all appropriate args
>
>   * Add new QMP monitor commands exposing data for machine
>     types, devices, cpu types, arch target, argv, config params,
>     and netdev backends.
>
>   * Add a new '-capabilities' command line arg as syntactic
>     sugar for the monitor commands that just report on static
>     info about the QEMU binary.
>
> The main problem encountered with this patch series is the
> split between argv and config parameters. The qemu-config.c
> file provides the information is a good data format, allowing
> programatic access to the list of parameters for each config
> option (eg, the 'cache', 'file', 'aio', etc bits for -drive).
> There are some issues with it though
>
>   - It lacks a huge amount of coverage wrt to the full argv
>     available, even simple things like the '-m' argument
>     don't exist.
>
>   - It is inconsistent in handling parameters. eg it  hands
>     off validation of netdev backends to other code, to allow
>     for handling of different parameters for tap vs user vs
>     socket backends.  For chardev backends though, it directly
>     includes a union of all possible parameters.
>
> Ideally the 'query-argv' command would not be required, but
> unless those problems with the qemu-config are resolved, it
> is the only way to access alot of the information. This is
> sub-optimal because although it lets apps easily determine
> whether an arg like '-smp' is present, it still leaves them
> parsing that args' help string to discover parameters.
>
> This series is lacking a 'query-blockdev' and 'query-chardev'
> commands to report on availability of backends for -blockdev
> and '-chardev' commands.
>
> Finally the existing 'query-commands' output is lacking any
> information about the parameters associated with each command.
> This needs to be addressed somehow.
>
> In summary though, IMHO, this patch series provides a good
> base for providing information about static QEMU binary
> capabilities to applications. It should ensure apps never
> again need to go anywhere near -help, -M ?, -cpu ?, -device ?,
> -soundhw ? and other such ill defined output formats.
>
> NB, I know this patch series will probably clash horribly
> with other patch series recently posted for review, in
> particular Jes' cleanup of vl.c   I will rebase as required
> if any of those get merged.
>
> This series is currently based on GIT master as of:
>
>    commit fd1dc858370d9a9ac7ea2512812c3a152ee6484b
>    Author: Edgar E. Iglesias<edgar.iglesias@gmail.com>
>    Date:   Mon Jun 7 11:54:27 2010 +0200
>
> Regards,
> Daniel
>
>   Makefile.objs                |    2
>   block.c                      |   32 +-
>   block.h                      |   55 ++++
>   cpus.c                       |   78 ++++++
>   cpus.h                       |    1
>   hw/boards.h                  |    2
>   hw/mc146818rtc.c             |    8
>   hw/qdev.c                    |  148 +++++++++++++
>   hw/qdev.h                    |    2
>   monitor.c                    |  167 ++++++++++++++
>   monitor.h                    |    5
>   net.c                        |  173 ++++++++++-----
>   net.h                        |    2
>   qemu-config.c                |  228 +++++++++++++++++++-
>   qemu-config.h                |    2
>   qemu-enum.c                  |   44 +++
>   qemu-enum.h                  |   45 ++++
>   qemu-option.c                |   35 +++
>   qemu-option.h                |   14 +
>   qemu-options.hx              |    9
>   qjson.c                      |   55 ++++
>   qjson.h                      |    1
>   sysemu.h                     |   43 +++
>   target-arm/cpu.h             |    7
>   target-arm/helper.c          |   21 +
>   target-cris/cpu.h            |    7
>   target-cris/translate.c      |   22 +
>   target-i386/cpu.h            |    7
>   target-i386/cpuid.c          |   79 +++++++
>   target-m68k/cpu.h            |    9
>   target-m68k/helper.c         |   23 ++
>   target-mips/cpu.h            |    7
>   target-mips/translate.c      |    4
>   target-mips/translate_init.c |   19 +
>   target-ppc/cpu.h             |    7
>   target-ppc/translate.c       |    4
>   target-ppc/translate_init.c  |   17 +
>   target-sh4/cpu.h             |    8
>   target-sh4/translate.c       |   23 ++
>   target-sparc/cpu.h           |    9
>   target-sparc/helper.c        |   60 +++++
>   verify.h                     |  164 ++++++++++++++
>   vl.c                         |  482 +++++++++++++++++++++++++++++--------------
>   43 files changed, 1869 insertions(+), 261 deletions(-)
>
>
>
>    

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [Qemu-devel] Re: [PATCH 19/19] Add a -capabilities argument to allow easy query for static QEMU info
  2010-06-07 16:04   ` [Qemu-devel] " Paolo Bonzini
@ 2010-06-07 16:09     ` Daniel P. Berrange
  0 siblings, 0 replies; 62+ messages in thread
From: Daniel P. Berrange @ 2010-06-07 16:09 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: qemu-devel

On Mon, Jun 07, 2010 at 06:04:24PM +0200, Paolo Bonzini wrote:
> On 06/07/2010 04:42 PM, Daniel P. Berrange wrote:
> >The QMP monitor provides a number of commands for querying info about
> >the QEMU binary capabilities. Given that these commands don't take
> >any options and just return static data, requiring the use of QMP is
> >unnecessarily onerous. This adds a new '-capabilities' command line
> >argument as a syntactic sugar for accessing the QMP commands that
> >just return static QEMU binary capabilities.
> >
> >Setting the '-capabilities' argument causes QEMU to output the requested
> >data on stdout, pretty printed in JSON format. The argument expects an
> >associated value to identify the data to be printed. This can be one of
> >the strings version|machines|devices|cputypes|target|commands|argv|netdev
> >
> >To query all possible data at once, the shorthand 'all' is allowed.
> >
> >The output is a QDict where the key is the type of data requested, and
> >the value is the JSON data from the associated monitor command. For
> >example:
> 
> A lot of this patch and the other monitor.c changes you had can likely 
> be moved in a capabilities.c file?

Yeah, I didn't much like adding more to vl.c or monitor.c. I can move this
to a new file, or a different existing one if there are any other better
suggestions

Daniel
-- 
|: Red Hat, Engineering, London    -o-   http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://deltacloud.org :|
|: http://autobuild.org        -o-         http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505  -o-   F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [Qemu-devel] [PATCH 10/19] Add a query-machines command to QMP
  2010-06-07 15:13   ` Anthony Liguori
@ 2010-06-07 16:44     ` Daniel P. Berrange
  2010-06-07 17:07       ` Anthony Liguori
  0 siblings, 1 reply; 62+ messages in thread
From: Daniel P. Berrange @ 2010-06-07 16:44 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: qemu-devel

On Mon, Jun 07, 2010 at 10:13:27AM -0500, Anthony Liguori wrote:
> On 06/07/2010 09:42 AM, Daniel P. Berrange wrote:
> >Add a new QMP monitor command 'query-machines' to discover what
> >machines are defined in the QEMU binary. This is an easily
> >parsable replacement for 'qemu -M ?'
> >
> >     [
> >         {
> >             "name": "pc-0.13",
> >             "description": "Standard PC",
> >             "default": 0
> >         },
> >         {
> >             "name": "pc",
> >             "description": "Standard PC",
> >             "canonical": "pc-0.13",
> >             "default": 1
> >         },
> >         {
> >             "name": "pc-0.12",
> >             "description": "Standard PC",
> >             "default": 0
> >         },
> >         ....
> >     ]
> >
> >No legacy readline monitor output is provided.
> >
> >In the future it would be desirable for each machine's QDict to
> >also include details of any qdev devices that are included by
> >default in the machine type.
> >
> >Signed-off-by: Daniel P. Berrange<berrange@redhat.com>
> >---
> >  hw/boards.h |    1 +
> >  monitor.c   |    9 +++++++
> >  vl.c        |   70 
> >  +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> >  3 files changed, 80 insertions(+), 0 deletions(-)
> >
> >diff --git a/hw/boards.h b/hw/boards.h
> >index 6f0f0d7..2f6003d 100644
> >--- a/hw/boards.h
> >+++ b/hw/boards.h
> >@@ -32,6 +32,7 @@ typedef struct QEMUMachine {
> >  } QEMUMachine;
> >
> >  int qemu_register_machine(QEMUMachine *m);
> >+void do_info_machines(Monitor *mon, QObject **data);
> >
> >  extern QEMUMachine *current_machine;
> >
> >diff --git a/monitor.c b/monitor.c
> >index f0406e8..b6aa2b4 100644
> >--- a/monitor.c
> >+++ b/monitor.c
> >@@ -55,6 +55,7 @@
> >  #include "json-streamer.h"
> >  #include "json-parser.h"
> >  #include "osdep.h"
> >+#include "hw/boards.h"
> >
> >  //#define DEBUG
> >  //#define DEBUG_COMPLETION
> >@@ -2449,6 +2450,14 @@ static const mon_cmd_t info_cmds[] = {
> >          .mhandler.info_new = do_info_version,
> >      },
> >      {
> >+        .name       = "machines",
> >+        .args_type  = "",
> >+        .params     = "",
> >+        .help       = "show the machine boards",
> >+        .user_print = monitor_user_noop,
> >+        .mhandler.info_new = do_info_machines,
> >+    },
> >+    {
> >          .name       = "commands",
> >          .args_type  = "",
> >          .params     = "",
> >diff --git a/vl.c b/vl.c
> >index 0b38d62..8043fac 100644
> >--- a/vl.c
> >+++ b/vl.c
> >@@ -1537,6 +1537,76 @@ static QEMUMachine *find_default_machine(void)
> >      return NULL;
> >  }
> >
> >+
> >+/**
> >+ * do_info_machines(): Show machine boards
> >+ *
> >+ * Returns a QList object listing all machine boards
> >+ * available with this QEMU target. Each element in
> >+ * the list is a QDict object containing the following
> >+ * keys
> >+ *
> >+ *  - "name": short name for the machine board
> >+ *  - "description": long description of the board
> >+ *  - "alias": name of an alias
> >+ *
> >+ * Example:
> >+ *
> >+ *  [
> >+ *     {
> >+ *       "name": "pc-0.13",
> >+ *        "description": "Standard PC",
> >+ *        "default": 0
> >+ *     },
> >+ *     {
> >+ *       "name": "pc",
> >+ *       "description": "Standard PC",
> >+ *       "canonical": "pc-0.13",
> >+ *       "default": 1
> >+ *     },
> >+ *     {
> >+ *       "name": "pc-0.12",
> >+ *       "description": "Standard PC",
> >+ *       "default": 0
> >+ *     },
> >+ *     ....
> >+ *  ]
> >+ *
> >+ */
> >   
> 
> My only suggestion would be to:
> 
> { 'default-machine': 'pc',
>    'machines': [{
>      'name': 'pc',
>      'description': 'Standard PC',
>    },...]
> }
> 
> I'd drop 'canonical' too.  Aliasing is an implementation detail and 
> should not be exposed via the ABI.

The alias/canonical mapping is something that libvirt needs to know in
order guarentee stable guest ABI for all configs it has.

What happens is that an app using libvirt will request a guest config
with machine type 'pc', and libvirt resolves that to the canonical
type 'pc-0.12', and then launches QEMU with '-M pc-0.12' instead of
the '-M pc'. If libvirt passed '-M pc' and let QEMU do the canonicalization,
the guest ABI would no longer be stable across QEMU upgrades because the
canonicalization changes to point to the newer version.

Regards,
Daniel
-- 
|: Red Hat, Engineering, London    -o-   http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://deltacloud.org :|
|: http://autobuild.org        -o-         http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505  -o-   F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [Qemu-devel] [PATCH 10/19] Add a query-machines command to QMP
  2010-06-07 16:44     ` Daniel P. Berrange
@ 2010-06-07 17:07       ` Anthony Liguori
  2010-06-07 17:14         ` Daniel P. Berrange
  2010-06-09 20:06         ` Luiz Capitulino
  0 siblings, 2 replies; 62+ messages in thread
From: Anthony Liguori @ 2010-06-07 17:07 UTC (permalink / raw)
  To: Daniel P. Berrange; +Cc: qemu-devel

On 06/07/2010 11:44 AM, Daniel P. Berrange wrote:
> On Mon, Jun 07, 2010 at 10:13:27AM -0500, Anthony Liguori wrote:
>    
>> On 06/07/2010 09:42 AM, Daniel P. Berrange wrote:
>>      
>>> Add a new QMP monitor command 'query-machines' to discover what
>>> machines are defined in the QEMU binary. This is an easily
>>> parsable replacement for 'qemu -M ?'
>>>
>>>      [
>>>          {
>>>              "name": "pc-0.13",
>>>              "description": "Standard PC",
>>>              "default": 0
>>>          },
>>>          {
>>>              "name": "pc",
>>>              "description": "Standard PC",
>>>              "canonical": "pc-0.13",
>>>              "default": 1
>>>          },
>>>          {
>>>              "name": "pc-0.12",
>>>              "description": "Standard PC",
>>>              "default": 0
>>>          },
>>>          ....
>>>      ]
>>>
>>> No legacy readline monitor output is provided.
>>>
>>> In the future it would be desirable for each machine's QDict to
>>> also include details of any qdev devices that are included by
>>> default in the machine type.
>>>
>>> Signed-off-by: Daniel P. Berrange<berrange@redhat.com>
>>> ---
>>>   hw/boards.h |    1 +
>>>   monitor.c   |    9 +++++++
>>>   vl.c        |   70
>>>   +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>>>   3 files changed, 80 insertions(+), 0 deletions(-)
>>>
>>> diff --git a/hw/boards.h b/hw/boards.h
>>> index 6f0f0d7..2f6003d 100644
>>> --- a/hw/boards.h
>>> +++ b/hw/boards.h
>>> @@ -32,6 +32,7 @@ typedef struct QEMUMachine {
>>>   } QEMUMachine;
>>>
>>>   int qemu_register_machine(QEMUMachine *m);
>>> +void do_info_machines(Monitor *mon, QObject **data);
>>>
>>>   extern QEMUMachine *current_machine;
>>>
>>> diff --git a/monitor.c b/monitor.c
>>> index f0406e8..b6aa2b4 100644
>>> --- a/monitor.c
>>> +++ b/monitor.c
>>> @@ -55,6 +55,7 @@
>>>   #include "json-streamer.h"
>>>   #include "json-parser.h"
>>>   #include "osdep.h"
>>> +#include "hw/boards.h"
>>>
>>>   //#define DEBUG
>>>   //#define DEBUG_COMPLETION
>>> @@ -2449,6 +2450,14 @@ static const mon_cmd_t info_cmds[] = {
>>>           .mhandler.info_new = do_info_version,
>>>       },
>>>       {
>>> +        .name       = "machines",
>>> +        .args_type  = "",
>>> +        .params     = "",
>>> +        .help       = "show the machine boards",
>>> +        .user_print = monitor_user_noop,
>>> +        .mhandler.info_new = do_info_machines,
>>> +    },
>>> +    {
>>>           .name       = "commands",
>>>           .args_type  = "",
>>>           .params     = "",
>>> diff --git a/vl.c b/vl.c
>>> index 0b38d62..8043fac 100644
>>> --- a/vl.c
>>> +++ b/vl.c
>>> @@ -1537,6 +1537,76 @@ static QEMUMachine *find_default_machine(void)
>>>       return NULL;
>>>   }
>>>
>>> +
>>> +/**
>>> + * do_info_machines(): Show machine boards
>>> + *
>>> + * Returns a QList object listing all machine boards
>>> + * available with this QEMU target. Each element in
>>> + * the list is a QDict object containing the following
>>> + * keys
>>> + *
>>> + *  - "name": short name for the machine board
>>> + *  - "description": long description of the board
>>> + *  - "alias": name of an alias
>>> + *
>>> + * Example:
>>> + *
>>> + *  [
>>> + *     {
>>> + *       "name": "pc-0.13",
>>> + *        "description": "Standard PC",
>>> + *        "default": 0
>>> + *     },
>>> + *     {
>>> + *       "name": "pc",
>>> + *       "description": "Standard PC",
>>> + *       "canonical": "pc-0.13",
>>> + *       "default": 1
>>> + *     },
>>> + *     {
>>> + *       "name": "pc-0.12",
>>> + *       "description": "Standard PC",
>>> + *       "default": 0
>>> + *     },
>>> + *     ....
>>> + *  ]
>>> + *
>>> + */
>>>
>>>        
>> My only suggestion would be to:
>>
>> { 'default-machine': 'pc',
>>     'machines': [{
>>       'name': 'pc',
>>       'description': 'Standard PC',
>>     },...]
>> }
>>
>> I'd drop 'canonical' too.  Aliasing is an implementation detail and
>> should not be exposed via the ABI.
>>      
> The alias/canonical mapping is something that libvirt needs to know in
> order guarentee stable guest ABI for all configs it has.
>
> What happens is that an app using libvirt will request a guest config
> with machine type 'pc',

Does the guest config encode the machine type?  Does that mean that I 
can't specify pc-0.12 or pc-0.13?

Since most guests don't specify an explicit machine, can't libvirt just 
use pc-<version> and be done with it?

Regards,

Anthony Liguori

>   and libvirt resolves that to the canonical
> type 'pc-0.12', and then launches QEMU with '-M pc-0.12' instead of
> the '-M pc'. If libvirt passed '-M pc' and let QEMU do the canonicalization,
> the guest ABI would no longer be stable across QEMU upgrades because the
> canonicalization changes to point to the newer version.
>
> Regards,
> Daniel
>    

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [Qemu-devel] [PATCH 10/19] Add a query-machines command to QMP
  2010-06-07 17:07       ` Anthony Liguori
@ 2010-06-07 17:14         ` Daniel P. Berrange
  2010-06-09 20:06         ` Luiz Capitulino
  1 sibling, 0 replies; 62+ messages in thread
From: Daniel P. Berrange @ 2010-06-07 17:14 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: qemu-devel

On Mon, Jun 07, 2010 at 12:07:56PM -0500, Anthony Liguori wrote:
> On 06/07/2010 11:44 AM, Daniel P. Berrange wrote:
> >On Mon, Jun 07, 2010 at 10:13:27AM -0500, Anthony Liguori wrote:
> >   
> >>On 06/07/2010 09:42 AM, Daniel P. Berrange wrote:
> >>     
> >>>Add a new QMP monitor command 'query-machines' to discover what
> >>>machines are defined in the QEMU binary. This is an easily
> >>>parsable replacement for 'qemu -M ?'
> >>>
> >>>     [
> >>>         {
> >>>             "name": "pc-0.13",
> >>>             "description": "Standard PC",
> >>>             "default": 0
> >>>         },
> >>>         {
> >>>             "name": "pc",
> >>>             "description": "Standard PC",
> >>>             "canonical": "pc-0.13",
> >>>             "default": 1
> >>>         },
> >>>         {
> >>>             "name": "pc-0.12",
> >>>             "description": "Standard PC",
> >>>             "default": 0
> >>>         },
> >>>         ....
> >>>     ]
> >>>
> >>>No legacy readline monitor output is provided.
> >>>
> >>>In the future it would be desirable for each machine's QDict to
> >>>also include details of any qdev devices that are included by
> >>>default in the machine type.
> >>>
> >>>Signed-off-by: Daniel P. Berrange<berrange@redhat.com>
> >>>---
> >>>  hw/boards.h |    1 +
> >>>  monitor.c   |    9 +++++++
> >>>  vl.c        |   70
> >>>  +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> >>>  3 files changed, 80 insertions(+), 0 deletions(-)
> >>>
> >>>diff --git a/hw/boards.h b/hw/boards.h
> >>>index 6f0f0d7..2f6003d 100644
> >>>--- a/hw/boards.h
> >>>+++ b/hw/boards.h
> >>>@@ -32,6 +32,7 @@ typedef struct QEMUMachine {
> >>>  } QEMUMachine;
> >>>
> >>>  int qemu_register_machine(QEMUMachine *m);
> >>>+void do_info_machines(Monitor *mon, QObject **data);
> >>>
> >>>  extern QEMUMachine *current_machine;
> >>>
> >>>diff --git a/monitor.c b/monitor.c
> >>>index f0406e8..b6aa2b4 100644
> >>>--- a/monitor.c
> >>>+++ b/monitor.c
> >>>@@ -55,6 +55,7 @@
> >>>  #include "json-streamer.h"
> >>>  #include "json-parser.h"
> >>>  #include "osdep.h"
> >>>+#include "hw/boards.h"
> >>>
> >>>  //#define DEBUG
> >>>  //#define DEBUG_COMPLETION
> >>>@@ -2449,6 +2450,14 @@ static const mon_cmd_t info_cmds[] = {
> >>>          .mhandler.info_new = do_info_version,
> >>>      },
> >>>      {
> >>>+        .name       = "machines",
> >>>+        .args_type  = "",
> >>>+        .params     = "",
> >>>+        .help       = "show the machine boards",
> >>>+        .user_print = monitor_user_noop,
> >>>+        .mhandler.info_new = do_info_machines,
> >>>+    },
> >>>+    {
> >>>          .name       = "commands",
> >>>          .args_type  = "",
> >>>          .params     = "",
> >>>diff --git a/vl.c b/vl.c
> >>>index 0b38d62..8043fac 100644
> >>>--- a/vl.c
> >>>+++ b/vl.c
> >>>@@ -1537,6 +1537,76 @@ static QEMUMachine *find_default_machine(void)
> >>>      return NULL;
> >>>  }
> >>>
> >>>+
> >>>+/**
> >>>+ * do_info_machines(): Show machine boards
> >>>+ *
> >>>+ * Returns a QList object listing all machine boards
> >>>+ * available with this QEMU target. Each element in
> >>>+ * the list is a QDict object containing the following
> >>>+ * keys
> >>>+ *
> >>>+ *  - "name": short name for the machine board
> >>>+ *  - "description": long description of the board
> >>>+ *  - "alias": name of an alias
> >>>+ *
> >>>+ * Example:
> >>>+ *
> >>>+ *  [
> >>>+ *     {
> >>>+ *       "name": "pc-0.13",
> >>>+ *        "description": "Standard PC",
> >>>+ *        "default": 0
> >>>+ *     },
> >>>+ *     {
> >>>+ *       "name": "pc",
> >>>+ *       "description": "Standard PC",
> >>>+ *       "canonical": "pc-0.13",
> >>>+ *       "default": 1
> >>>+ *     },
> >>>+ *     {
> >>>+ *       "name": "pc-0.12",
> >>>+ *       "description": "Standard PC",
> >>>+ *       "default": 0
> >>>+ *     },
> >>>+ *     ....
> >>>+ *  ]
> >>>+ *
> >>>+ */
> >>>
> >>>       
> >>My only suggestion would be to:
> >>
> >>{ 'default-machine': 'pc',
> >>    'machines': [{
> >>      'name': 'pc',
> >>      'description': 'Standard PC',
> >>    },...]
> >>}
> >>
> >>I'd drop 'canonical' too.  Aliasing is an implementation detail and
> >>should not be exposed via the ABI.
> >>     
> >The alias/canonical mapping is something that libvirt needs to know in
> >order guarentee stable guest ABI for all configs it has.
> >
> >What happens is that an app using libvirt will request a guest config
> >with machine type 'pc',
> 
> Does the guest config encode the machine type?  Does that mean that I 
> can't specify pc-0.12 or pc-0.13?

Yes, the XML lets you specify an explicit machine type yourself.

> Since most guests don't specify an explicit machine, can't libvirt just 
> use pc-<version> and be done with it?

If we make sure the 'default-machine' pointed to the latest version
machine type ('pc-0.13' and not 'pc') we could just hardcode to use
the default machine type whenever we see 'pc' in libvirt. Currently
the 'default-machine' and 'pc' canonicalization are separately varied
in QEMU.

Regards,
Daniel
-- 
|: Red Hat, Engineering, London    -o-   http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://deltacloud.org :|
|: http://autobuild.org        -o-         http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505  -o-   F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [Qemu-devel] [PATCH 16/19] Add a query-netdev command to QMP
  2010-06-07 14:42 ` [Qemu-devel] [PATCH 16/19] Add a query-netdev command to QMP Daniel P. Berrange
  2010-06-07 15:15   ` Anthony Liguori
@ 2010-06-07 19:13   ` Miguel Di Ciurcio Filho
  2010-06-08  8:38     ` Daniel P. Berrange
  1 sibling, 1 reply; 62+ messages in thread
From: Miguel Di Ciurcio Filho @ 2010-06-07 19:13 UTC (permalink / raw)
  To: Daniel P. Berrange; +Cc: qemu-devel, Luiz Capitulino

On Mon, Jun 7, 2010 at 11:42 AM, Daniel P. Berrange <berrange@redhat.com> wrote:
> This adds a new QMP command called query-netdev to provide information
> about the available netdev backends in the QEMU binary. There is no
> existing '-netdev ?' support, but if there was, this would obsolete it
>

Hi Daniel,

Could we work on a different name? Just a few hours ago on another
thread query-netdev, instead of the originaly proposed
query-netdevices, was proposed, with similar functionality. I see that
your patch shows the supported backends. I'm working on another patch
that actually shows the current used backend network devices.

Regards,

Miguel

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [Qemu-devel] [PATCH 16/19] Add a query-netdev command to QMP
  2010-06-07 19:13   ` Miguel Di Ciurcio Filho
@ 2010-06-08  8:38     ` Daniel P. Berrange
  0 siblings, 0 replies; 62+ messages in thread
From: Daniel P. Berrange @ 2010-06-08  8:38 UTC (permalink / raw)
  To: Miguel Di Ciurcio Filho; +Cc: qemu-devel, Luiz Capitulino

On Mon, Jun 07, 2010 at 04:13:48PM -0300, Miguel Di Ciurcio Filho wrote:
> On Mon, Jun 7, 2010 at 11:42 AM, Daniel P. Berrange <berrange@redhat.com> wrote:
> > This adds a new QMP command called query-netdev to provide information
> > about the available netdev backends in the QEMU binary. There is no
> > existing '-netdev ?' support, but if there was, this would obsolete it
> >
> 
> Hi Daniel,
> 
> Could we work on a different name? Just a few hours ago on another
> thread query-netdev, instead of the originaly proposed
> query-netdevices, was proposed, with similar functionality. I see that
> your patch shows the supported backends. I'm working on another patch
> that actually shows the current used backend network devices.

Yeah perhaps I should rename mine to 'query-netdev-types' so show that it
is static info about the types of netdev available, rather than about the
configured instances


Daniel
-- 
|: Red Hat, Engineering, London    -o-   http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://deltacloud.org :|
|: http://autobuild.org        -o-         http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505  -o-   F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [Qemu-devel] [PATCH 01/19] Add support for JSON pretty printing
  2010-06-07 14:42 ` [Qemu-devel] [PATCH 01/19] Add support for JSON pretty printing Daniel P. Berrange
@ 2010-06-09 19:51   ` Luiz Capitulino
  0 siblings, 0 replies; 62+ messages in thread
From: Luiz Capitulino @ 2010-06-09 19:51 UTC (permalink / raw)
  To: Daniel P. Berrange; +Cc: qemu-devel

On Mon,  7 Jun 2010 15:42:14 +0100
"Daniel P. Berrange" <berrange@redhat.com> wrote:

> The monitor does not pretty-print JSON output, so that everything
> will be on a single line reply. When JSON docs get large this is
> quite unpleasant to read. For the future command line capabilities
> query ability, huge JSON docs will be available. This needs the
> ability to pretty-print.
> 
> This introduces a new API qobject_to_json_pretty() that does
> a minimal indentation of list and dict members. As an example,
> this makes
> 
>   {"QMP": {"version": {"micro": 50, "minor": 12, "package": "", "major": 0}, "capabilities": []}}
> 
> Output as
> 
>   {
>       "QMP": {
>           "version": {
>               "micro": 50,
>               "minor": 12,
>               "package": "",
>               "major": 0
>           },
>           "capabilities": [
>           ]
>       }
>   }
> 
> NB: this is not turned on for the QMP monitor.
> 
> Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
> ---
>  qjson.c |   55 +++++++++++++++++++++++++++++++++++++++++++++++--------
>  qjson.h |    1 +
>  2 files changed, 48 insertions(+), 8 deletions(-)
> 
> diff --git a/qjson.c b/qjson.c
> index 483c667..f402103 100644
> --- a/qjson.c
> +++ b/qjson.c
> @@ -72,43 +72,57 @@ QObject *qobject_from_jsonf(const char *string, ...)
>  
>  typedef struct ToJsonIterState
>  {
> +    int indent;
> +    int pretty;
>      int count;
>      QString *str;
>  } ToJsonIterState;
>  
> -static void to_json(const QObject *obj, QString *str);
> +static void to_json(const QObject *obj, QString *str, int pretty, int indent);
>  
>  static void to_json_dict_iter(const char *key, QObject *obj, void *opaque)
>  {
>      ToJsonIterState *s = opaque;
>      QString *qkey;
> +    int j;
>  
> -    if (s->count) {
> +    if (s->count)
>          qstring_append(s->str, ", ");
> +
> +    if (s->pretty) {
> +        qstring_append(s->str, "\n");
> +        for (j = 0 ; j < s->indent ; j++)
> +            qstring_append(s->str, "    ");
>      }
>  
>      qkey = qstring_from_str(key);
> -    to_json(QOBJECT(qkey), s->str);
> +    to_json(QOBJECT(qkey), s->str, s->pretty, s->indent);
>      QDECREF(qkey);
>  
>      qstring_append(s->str, ": ");
> -    to_json(obj, s->str);
> +    to_json(obj, s->str, s->pretty, s->indent);
>      s->count++;
>  }
>  
>  static void to_json_list_iter(QObject *obj, void *opaque)
>  {
>      ToJsonIterState *s = opaque;
> +    int j;
>  
> -    if (s->count) {
> +    if (s->count)
>          qstring_append(s->str, ", ");
> +
> +    if (s->pretty) {
> +        qstring_append(s->str, "\n");

 Nitpick: we also have qstring_append_chr()

> +        for (j = 0 ; j < s->indent ; j++)
> +            qstring_append(s->str, "    ");
>      }
>  
> -    to_json(obj, s->str);
> +    to_json(obj, s->str, s->pretty, s->indent);
>      s->count++;
>  }
>  
> -static void to_json(const QObject *obj, QString *str)
> +static void to_json(const QObject *obj, QString *str, int pretty, int indent)
>  {
>      switch (qobject_type(obj)) {
>      case QTYPE_QINT: {
> @@ -190,8 +204,16 @@ static void to_json(const QObject *obj, QString *str)
>  
>          s.count = 0;
>          s.str = str;
> +        s.indent = indent + 1;
> +        s.pretty = pretty;
>          qstring_append(str, "{");
>          qdict_iter(val, to_json_dict_iter, &s);
> +        if (pretty) {
> +            int j;
> +            qstring_append(str, "\n");
> +            for (j = 0 ; j < indent ; j++)
> +                qstring_append(str, "    ");
> +        }
>          qstring_append(str, "}");
>          break;
>      }
> @@ -201,8 +223,16 @@ static void to_json(const QObject *obj, QString *str)
>  
>          s.count = 0;
>          s.str = str;
> +        s.indent = indent + 1;
> +        s.pretty = pretty;
>          qstring_append(str, "[");
>          qlist_iter(val, (void *)to_json_list_iter, &s);
> +        if (pretty) {
> +            int j;
> +            qstring_append(str, "\n");
> +            for (j = 0 ; j < indent ; j++)
> +                qstring_append(str, "    ");
> +        }
>          qstring_append(str, "]");
>          break;
>      }
> @@ -246,7 +276,16 @@ QString *qobject_to_json(const QObject *obj)
>  {
>      QString *str = qstring_new();
>  
> -    to_json(obj, str);
> +    to_json(obj, str, 0, 0);
> +
> +    return str;
> +}
> +
> +QString *qobject_to_json_pretty(const QObject *obj)
> +{
> +    QString *str = qstring_new();
> +
> +    to_json(obj, str, 1, 0);
>  
>      return str;
>  }
> diff --git a/qjson.h b/qjson.h
> index 7afec2e..cd60e0b 100644
> --- a/qjson.h
> +++ b/qjson.h
> @@ -24,5 +24,6 @@ QObject *qobject_from_jsonf(const char *string, ...)
>  QObject *qobject_from_jsonv(const char *string, va_list *ap);
>  
>  QString *qobject_to_json(const QObject *obj);
> +QString *qobject_to_json_pretty(const QObject *obj);
>  
>  #endif /* QJSON_H */

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [Qemu-devel] [PATCH 03/19] Add enum handlers for easy & efficient string <-> int conversion
  2010-06-07 14:42 ` [Qemu-devel] [PATCH 03/19] Add enum handlers for easy & efficient string <-> int conversion Daniel P. Berrange
@ 2010-06-09 19:52   ` Luiz Capitulino
  2010-06-26  6:52   ` Markus Armbruster
  1 sibling, 0 replies; 62+ messages in thread
From: Luiz Capitulino @ 2010-06-09 19:52 UTC (permalink / raw)
  To: Daniel P. Berrange; +Cc: qemu-devel

On Mon,  7 Jun 2010 15:42:16 +0100
"Daniel P. Berrange" <berrange@redhat.com> wrote:

> There is quite alot of code using an enumeration of possible
> values, which also needs todo conversions to/from a string
> representation of enum values. These string <-> int conversions
> have been repeated in an adhoc manner throughout the code.
> 
> This makes it hard to report on the list of valid strings,
> eg in help output, or todo proper validation in the qemu
> config/option parsing routines.
> 
> This addresses the first problem by introducing a standard
> set of routines for performing string <-> int conversions
> for enums. There are two restrictions on using these helpers,
> the first enum value must be 0, and there must be a sentinal
> in the enum to provide the max value.
> 
> For each enumeration, three functions will be made available
> 
>  - string to int convertor:
> 
>    int XXXX_from_string(const char *value);
> 
>    Returns -1 if the value was not an allowed string for the
>    enumeration. Returns >= 0 for a valid value
> 
>  - int to string convertor
> 
>    const char * XXXX_to_string(int value);
> 
>    Returns NULL if the value was not a member of the
>    enumeration. Returns a non-NULL sstring for valid value
> 
>  - string list generator
> 
>    char * XXXX_to_string_list(void);
> 
>    Returns a malloc'd string containing all valid values,
>    separated by commas. Caller must free the string.
> 
> The general usage pattern is as follows.
> 
> In the header file (eg qemu-option.h):
> 
>   enum QemuOptType {
>     QEMU_OPT_STRING = 0,  /* no parsing (use string as-is)                        */
>     QEMU_OPT_BOOL,        /* on/off                                               */
>     QEMU_OPT_NUMBER,      /* simple number                                        */
>     QEMU_OPT_SIZE,        /* size, accepts (K)ilo, (M)ega, (G)iga, (T)era postfix */
> 
>     QEMU_OPT_LAST
>   };
>   QEMU_ENUM_DECL(qemu_opt_type);
> 
> This declares the function prototypes for the 3 methods
> outlined above.
> 
> In the corresponding source file (eg qemu-option.c):
> 
>   QEMU_ENUM_IMPL(qemu_opt_type,
>                  QEMU_OPT_LAST,
>                  "string", "bool", "number", "size");
> 
> This provides the implementation of the 3 methods. If there
> are greater/fewer strings provided than the number of values
> in the  enumeration, this generates a compile time assertion
> failure that looks like
> 
>   qemu-option.c:35: error: negative width in bit-field ‘verify_error_if_negative_size__’
> 
> Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
> ---
>  Makefile.objs |    2 +-
>  qemu-enum.c   |   44 ++++++++++++++++++++++++++++++++++++++++++++
>  qemu-enum.h   |   45 +++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 90 insertions(+), 1 deletions(-)
>  create mode 100644 qemu-enum.c
>  create mode 100644 qemu-enum.h
> 
> diff --git a/Makefile.objs b/Makefile.objs
> index 9796dcb..0ba9966 100644
> --- a/Makefile.objs
> +++ b/Makefile.objs
> @@ -8,7 +8,7 @@ qobject-obj-y += qerror.o
>  # block-obj-y is code used by both qemu system emulation and qemu-img
>  
>  block-obj-y = cutils.o cache-utils.o qemu-malloc.o qemu-option.o module.o
> -block-obj-y += nbd.o block.o aio.o aes.o osdep.o qemu-config.o
> +block-obj-y += nbd.o block.o aio.o aes.o osdep.o qemu-config.o qemu-enum.o
>  block-obj-$(CONFIG_POSIX) += posix-aio-compat.o
>  block-obj-$(CONFIG_LINUX_AIO) += linux-aio.o
>  
> diff --git a/qemu-enum.c b/qemu-enum.c
> new file mode 100644
> index 0000000..9bb33ac
> --- /dev/null
> +++ b/qemu-enum.c
> @@ -0,0 +1,44 @@
> +#include "qemu-enum.h"

 Missing license text.

> +
> +int qemu_enum_from_string(const char *const*types,
> +			  unsigned int ntypes,
> +			  const char *type)
> +{
> +    unsigned int i;
> +    if (!type)
> +        return -1;
> +
> +    for (i = 0 ; i < ntypes ; i++)
> +        if (strcmp(types[i], type) == 0)
> +            return i;
> +
> +    return -1;
> +}
> +
> +const char *qemu_enum_to_string(const char *const*types,
> +				unsigned int ntypes,
> +				int type)
> +{
> +    if (type < 0 || type >= ntypes)
> +        return NULL;
> +
> +    return types[type];
> +}
> +
> +char *qemu_enum_to_string_list(const char *const*types,
> +			       unsigned int ntypes)
> +{
> +    size_t len = 0;
> +    char *ret;
> +    int i;
> +    for (i = 0 ; i < ntypes ; i++)
> +	len += strlen(types[i]) + 2;
> +    ret = qemu_malloc(len);
> +    *ret = '\0';
> +    for (i = 0 ; i < ntypes ; i++) {
> +	if (i > 0)
> +	    strcat(ret, ", ");
> +	strcat(ret, types[i]);
> +    }
> +    return ret;
> +}
> diff --git a/qemu-enum.h b/qemu-enum.h
> new file mode 100644
> index 0000000..ff47798
> --- /dev/null
> +++ b/qemu-enum.h
> @@ -0,0 +1,45 @@
> +#ifndef QEMU_ENUM_H
> +#define QEMU_ENUM_H
> +
> +#include "qemu-common.h"
> +#include "verify.h"
> +
> +
> +int qemu_enum_from_string(const char *const*types,
> +			  unsigned int ntypes,
> +			  const char *type);
> +
> +const char *qemu_enum_to_string(const char *const*types,
> +				unsigned int ntypes,
> +				int type);
> +
> +char *qemu_enum_to_string_list(const char *const*types,
> +			       unsigned int ntypes);
> +
> +#define QEMU_ENUM_IMPL(name, lastVal, ...)				\
> +    static const char *const name ## _string_list[] = { __VA_ARGS__ };	\
> +    char *name ## _to_string_list(void) {				\
> +        return qemu_enum_to_string_list(name ## _string_list,		\
> +					ARRAY_SIZE(name ## _string_list)); \
> +    }                                                                   \
> +    const char *name ## _to_string(int type) {				\
> +        return qemu_enum_to_string(name ## _string_list,		\
> +				   ARRAY_SIZE(name ## _string_list),	\
> +				   type);				\
> +    }                                                                   \
> +    int name ## _from_string(const char *type) {			\
> +        return qemu_enum_from_string(name ## _string_list,		\
> +				     ARRAY_SIZE(name ## _string_list),	\
> +				     type);				\
> +    }									\
> +    extern int (* name ## Verify (void))				\
> +        [verify_true (ARRAY_SIZE(name ## _string_list) == lastVal)]
> +
> +# define QEMU_ENUM_DECL(name)				\
> +    const char *name ## _to_string(int type);		\
> +    char *name ## _to_string_list(void);		\
> +    int name ## _from_string(const char*type)
> +
> +
> +
> +#endif /* QEMU_ENUM_H */

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [Qemu-devel] [PATCH 06/19] Convert drive options to use enumeration data type
  2010-06-07 14:42 ` [Qemu-devel] [PATCH 06/19] Convert drive options to use enumeration data type Daniel P. Berrange
@ 2010-06-09 19:52   ` Luiz Capitulino
  2010-06-26  7:07   ` Markus Armbruster
  1 sibling, 0 replies; 62+ messages in thread
From: Luiz Capitulino @ 2010-06-09 19:52 UTC (permalink / raw)
  To: Daniel P. Berrange; +Cc: qemu-devel

On Mon,  7 Jun 2010 15:42:19 +0100
"Daniel P. Berrange" <berrange@redhat.com> wrote:

> This converts the drive options if, trans, media, cache, aio,
> rerror and werror to use the QEMU_OPT_ENUM datatype. This
> standardizes the string parsing and error reporting
> 
>   $ qemu  -drive file=foo,werror=stop3
>   qemu: -drive file=foo,if=mtd,werror=stop3: Parameter 'werror' expects report, ignore, enospc, stop
> 
>   $ qemu  -readconfig bar.cfg
>   qemu:bar.cfg:6: Parameter 'werror' expects report, ignore, enospc, stop
>   read config bar.cfg: Invalid argument
> 
> * block.c: Implementations for all enumerations
> * block.h, sysemu.h: Declare enumerations
> * qemu-config.c: Convert if, trans, media, cache, aio,
>   rerror and werror to use the QEMU_OPT_ENUM
> * vl.c: Remove handcrafted string -> int conversions in drive_init
> 
> Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
> ---
>  block.c       |   32 +++++++-----
>  block.h       |   55 +++++++++++++++++---
>  hw/qdev.c     |    2 +-
>  qemu-config.c |   73 +++++++++++++++++++++++---
>  sysemu.h      |   23 +++++++--
>  vl.c          |  162 ++++++++++++++++-----------------------------------------
>  6 files changed, 197 insertions(+), 150 deletions(-)
> 
> diff --git a/block.c b/block.c
> index 39724c1..7ca55e2 100644
> --- a/block.c
> +++ b/block.c
> @@ -27,6 +27,7 @@
>  #include "block_int.h"
>  #include "module.h"
>  #include "qemu-objects.h"
> +#include "sysemu.h"
>  
>  #ifdef CONFIG_BSD
>  #include <sys/types.h>
> @@ -42,6 +43,22 @@
>  #include <windows.h>
>  #endif
>  
> +QEMU_ENUM_IMPL(bdrv_type, BDRV_TYPE_LAST,
> +               "hd", "cdrom", "floppy");
> +QEMU_ENUM_IMPL(bdrv_bios_ata_translation, BIOS_ATA_TRANSLATION_LAST,
> +               "auto", "none", "lba", "large", "rechs");
> +QEMU_ENUM_IMPL(bdrv_cache, BDRV_CACHE_LAST,
> +               "none", "off", "writeback", "writethrough", "unsafe");
> +QEMU_ENUM_IMPL(bdrv_if_type, IF_LAST,
> +               "none", "ide", "scsi", "floppy", "pflash",
> +               "mtd", "sd", "virtio", "xen");
> +QEMU_ENUM_IMPL(bdrv_if_error_action, BLOCK_ERR_LAST,
> +               "report", "ignore", "enospc", "stop");
> +QEMU_ENUM_IMPL(bdrv_media, BDRV_MEDIA_LAST,
> +               "disk", "cdrom");
> +QEMU_ENUM_IMPL(bdrv_aio, BDRV_AIO_LAST,
> +               "native", "threads");
> +
>  static BlockDriverAIOCB *bdrv_aio_readv_em(BlockDriverState *bs,
>          int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
>          BlockDriverCompletionFunc *cb, void *opaque);
> @@ -1454,19 +1471,8 @@ void bdrv_info(Monitor *mon, QObject **ret_data)
>  
>      QTAILQ_FOREACH(bs, &bdrv_states, list) {
>          QObject *bs_obj;
> -        const char *type = "unknown";
> -
> -        switch(bs->type) {
> -        case BDRV_TYPE_HD:
> -            type = "hd";
> -            break;
> -        case BDRV_TYPE_CDROM:
> -            type = "cdrom";
> -            break;
> -        case BDRV_TYPE_FLOPPY:
> -            type = "floppy";
> -            break;
> -        }
> +        const char *type = bdrv_type_to_string(bs->type);
> +        assert(type != NULL);

 'unknown' has to be dropped from query-block's documentation in
qemu-monitor.hx too.

>  
>          bs_obj = qobject_from_jsonf("{ 'device': %s, 'type': %s, "
>                                      "'removable': %i, 'locked': %i }",
> diff --git a/block.h b/block.h
> index 756670d..11a029b 100644
> --- a/block.h
> +++ b/block.h
> @@ -4,6 +4,7 @@
>  #include "qemu-aio.h"
>  #include "qemu-common.h"
>  #include "qemu-option.h"
> +#include "qemu-enum.h"
>  #include "qobject.h"
>  
>  /* block.c */
> @@ -128,14 +129,52 @@ int bdrv_has_zero_init(BlockDriverState *bs);
>  int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
>  	int *pnum);
>  
> -#define BDRV_TYPE_HD     0
> -#define BDRV_TYPE_CDROM  1
> -#define BDRV_TYPE_FLOPPY 2
> -#define BIOS_ATA_TRANSLATION_AUTO   0
> -#define BIOS_ATA_TRANSLATION_NONE   1
> -#define BIOS_ATA_TRANSLATION_LBA    2
> -#define BIOS_ATA_TRANSLATION_LARGE  3
> -#define BIOS_ATA_TRANSLATION_RECHS  4
> +enum {
> +    BDRV_TYPE_HD,
> +    BDRV_TYPE_CDROM,
> +    BDRV_TYPE_FLOPPY,
> +
> +    BDRV_TYPE_LAST
> +};
> +QEMU_ENUM_DECL(bdrv_type);
> +
> +enum {
> +    BIOS_ATA_TRANSLATION_AUTO,
> +    BIOS_ATA_TRANSLATION_NONE,
> +    BIOS_ATA_TRANSLATION_LBA,
> +    BIOS_ATA_TRANSLATION_LARGE,
> +    BIOS_ATA_TRANSLATION_RECHS,
> +
> +    BIOS_ATA_TRANSLATION_LAST
> +};
> +QEMU_ENUM_DECL(bdrv_bios_ata_translation);
> +
> +enum {
> +    BDRV_CACHE_NONE,
> +    BDRV_CACHE_OFF,
> +    BDRV_CACHE_WRITEBACK,
> +    BDRV_CACHE_WRITETHROUGH,
> +    BDRV_CACHE_UNSAFE,
> +
> +    BDRV_CACHE_LAST
> +};
> +QEMU_ENUM_DECL(bdrv_cache);
> +
> +enum {
> +    BDRV_MEDIA_DISK,
> +    BDRV_MEDIA_CDROM,
> +
> +    BDRV_MEDIA_LAST
> +};
> +QEMU_ENUM_DECL(bdrv_media);
> +
> +enum {
> +    BDRV_AIO_NATIVE,
> +    BDRV_AIO_THREADS,
> +
> +    BDRV_AIO_LAST
> +};
> +QEMU_ENUM_DECL(bdrv_aio);
>  
>  void bdrv_set_geometry_hint(BlockDriverState *bs,
>                              int cyls, int heads, int secs);
> diff --git a/hw/qdev.c b/hw/qdev.c
> index aa2ce01..1186dfa 100644
> --- a/hw/qdev.c
> +++ b/hw/qdev.c
> @@ -414,7 +414,7 @@ void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd)
>      }
>  }
>  
> -static int next_block_unit[IF_COUNT];
> +static int next_block_unit[IF_LAST];
>  
>  /* Get a block device.  This should only be used for single-drive devices
>     (e.g. SD/Floppy/MTD).  Multi-disk devices (scsi/ide) should use the
> diff --git a/qemu-config.c b/qemu-config.c
> index 5a4e61b..f656e6b 100644
> --- a/qemu-config.c
> +++ b/qemu-config.c
> @@ -4,6 +4,7 @@
>  #include "qemu-config.h"
>  #include "sysemu.h"
>  #include "hw/qdev.h"
> +#include "block.h"
>  
>  QemuOptsList qemu_drive_opts = {
>      .name = "drive",
> @@ -19,8 +20,16 @@ QemuOptsList qemu_drive_opts = {
>              .help = "unit number (i.e. lun for scsi)",
>          },{
>              .name = "if",
> -            .type = QEMU_OPT_STRING,
> +            .type = QEMU_OPT_ENUM,
>              .help = "interface (ide, scsi, sd, mtd, floppy, pflash, virtio)",
> +            .validate = {
> +                .optEnum = {
> +                    .to_string = bdrv_if_type_to_string,
> +                    .to_string_list = bdrv_if_type_to_string_list,
> +                    .from_string = bdrv_if_type_from_string,
> +                    .last = IF_LAST
> +                }
> +            },
>          },{
>              .name = "index",
>              .type = QEMU_OPT_NUMBER,
> @@ -38,12 +47,28 @@ QemuOptsList qemu_drive_opts = {
>              .help = "number of sectors (ide disk geometry)",
>          },{
>              .name = "trans",
> -            .type = QEMU_OPT_STRING,
> +            .type = QEMU_OPT_ENUM,
>              .help = "chs translation (auto, lba. none)",
> +            .validate = {
> +                .optEnum = {
> +                    .to_string = bdrv_bios_ata_translation_to_string,
> +                    .to_string_list = bdrv_bios_ata_translation_to_string_list,
> +                    .from_string = bdrv_bios_ata_translation_from_string,
> +                    .last = BIOS_ATA_TRANSLATION_LAST,
> +                }
> +            }
>          },{
>              .name = "media",
> -            .type = QEMU_OPT_STRING,
> +            .type = QEMU_OPT_ENUM,
>              .help = "media type (disk, cdrom)",
> +            .validate = {
> +                .optEnum = {
> +                    .to_string = bdrv_media_to_string,
> +                    .to_string_list = bdrv_media_to_string_list,
> +                    .from_string = bdrv_media_from_string,
> +                    .last = BDRV_MEDIA_LAST,
> +                }
> +            }
>          },{
>              .name = "snapshot",
>              .type = QEMU_OPT_BOOL,
> @@ -53,25 +78,57 @@ QemuOptsList qemu_drive_opts = {
>              .help = "disk image",
>          },{
>              .name = "cache",
> -            .type = QEMU_OPT_STRING,
> +            .type = QEMU_OPT_ENUM,
>              .help = "host cache usage (none, writeback, writethrough, unsafe)",
> +            .validate = {
> +                .optEnum = {
> +                    .to_string = bdrv_cache_to_string,
> +                    .to_string_list = bdrv_cache_to_string_list,
> +                    .from_string = bdrv_cache_from_string,
> +                    .last = BDRV_CACHE_LAST
> +                },
> +            },
>          },{
>              .name = "aio",
> -            .type = QEMU_OPT_STRING,
> +            .type = QEMU_OPT_ENUM,
>              .help = "host AIO implementation (threads, native)",
> +            .validate = {
> +                .optEnum = {
> +                    .to_string = bdrv_aio_to_string,
> +                    .to_string_list = bdrv_aio_to_string_list,
> +                    .from_string = bdrv_aio_from_string,
> +                    .last = BDRV_CACHE_LAST
> +                },
> +            },
>          },{
>              .name = "format",
> -            .type = QEMU_OPT_STRING,
> +            .type = QEMU_OPT_STRING, /* Be nice as an enum, but the data is too dynamic */
>              .help = "disk format (raw, qcow2, ...)",
>          },{
>              .name = "serial",
>              .type = QEMU_OPT_STRING,
>          },{
>              .name = "rerror",
> -            .type = QEMU_OPT_STRING,
> +            .type = QEMU_OPT_ENUM,
> +            .validate = {
> +                .optEnum = {
> +                    .to_string = bdrv_if_error_action_to_string,
> +                    .to_string_list = bdrv_if_error_action_to_string_list,
> +                    .from_string = bdrv_if_error_action_from_string,
> +                    .last = BLOCK_ERR_LAST,
> +                },
> +            },
>          },{
>              .name = "werror",
> -            .type = QEMU_OPT_STRING,
> +            .type = QEMU_OPT_ENUM,
> +            .validate = {
> +                .optEnum = {
> +                    .to_string = bdrv_if_error_action_to_string,
> +                    .to_string_list = bdrv_if_error_action_to_string_list,
> +                    .from_string = bdrv_if_error_action_from_string,
> +                    .last = BLOCK_ERR_LAST,
> +                },
> +            },
>          },{
>              .name = "addr",
>              .type = QEMU_OPT_STRING,
> diff --git a/sysemu.h b/sysemu.h
> index 879446a..f0c5eb8 100644
> --- a/sysemu.h
> +++ b/sysemu.h
> @@ -6,6 +6,7 @@
>  #include "qemu-option.h"
>  #include "qemu-queue.h"
>  #include "qemu-timer.h"
> +#include "qemu-enum.h"
>  
>  #ifdef _WIN32
>  #include <windows.h>
> @@ -149,14 +150,28 @@ extern unsigned int nb_prom_envs;
>  
>  typedef enum {
>      IF_NONE,
> -    IF_IDE, IF_SCSI, IF_FLOPPY, IF_PFLASH, IF_MTD, IF_SD, IF_VIRTIO, IF_XEN,
> -    IF_COUNT
> +    IF_IDE,
> +    IF_SCSI,
> +    IF_FLOPPY,
> +    IF_PFLASH,
> +    IF_MTD,
> +    IF_SD,
> +    IF_VIRTIO,
> +    IF_XEN,
> +
> +    IF_LAST
>  } BlockInterfaceType;
> +QEMU_ENUM_DECL(bdrv_if_type);
>  
>  typedef enum {
> -    BLOCK_ERR_REPORT, BLOCK_ERR_IGNORE, BLOCK_ERR_STOP_ENOSPC,
> -    BLOCK_ERR_STOP_ANY
> +    BLOCK_ERR_REPORT,
> +    BLOCK_ERR_IGNORE,
> +    BLOCK_ERR_STOP_ENOSPC,
> +    BLOCK_ERR_STOP_ANY,
> +
> +    BLOCK_ERR_LAST
>  } BlockInterfaceErrorAction;
> +QEMU_ENUM_DECL(bdrv_if_error_action);
>  
>  #define BLOCK_SERIAL_STRLEN 20
>  
> diff --git a/vl.c b/vl.c
> index 3d08a44..16491c4 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -754,23 +754,6 @@ void drive_uninit(DriveInfo *dinfo)
>      qemu_free(dinfo);
>  }
>  
> -static int parse_block_error_action(const char *buf, int is_read)
> -{
> -    if (!strcmp(buf, "ignore")) {
> -        return BLOCK_ERR_IGNORE;
> -    } else if (!is_read && !strcmp(buf, "enospc")) {
> -        return BLOCK_ERR_STOP_ENOSPC;
> -    } else if (!strcmp(buf, "stop")) {
> -        return BLOCK_ERR_STOP_ANY;
> -    } else if (!strcmp(buf, "report")) {
> -        return BLOCK_ERR_REPORT;
> -    } else {
> -        fprintf(stderr, "qemu: '%s' invalid %s error action\n",
> -            buf, is_read ? "read" : "write");
> -        return -1;
> -    }
> -}
> -
>  DriveInfo *drive_init(QemuOpts *opts, void *opaque,
>                        int *fatal_error)
>  {
> @@ -780,7 +763,7 @@ DriveInfo *drive_init(QemuOpts *opts, void *opaque,
>      const char *serial;
>      const char *mediastr = "";
>      BlockInterfaceType type;
> -    enum { MEDIA_DISK, MEDIA_CDROM } media;
> +    int media;
>      int bus_id, unit_id;
>      int cyls, heads, secs, translation;
>      BlockDriver *drv = NULL;
> @@ -796,8 +779,6 @@ DriveInfo *drive_init(QemuOpts *opts, void *opaque,
>  
>      *fatal_error = 1;
>  
> -    translation = BIOS_ATA_TRANSLATION_AUTO;
> -
>      if (machine && machine->use_scsi) {
>          type = IF_SCSI;
>          max_devs = MAX_SCSI_DEVS;
> @@ -807,7 +788,6 @@ DriveInfo *drive_init(QemuOpts *opts, void *opaque,
>          max_devs = MAX_IDE_DEVS;
>          pstrcpy(devname, sizeof(devname), "ide");
>      }
> -    media = MEDIA_DISK;
>  
>      /* extract parameters */
>      bus_id  = qemu_opt_get_number(opts, "bus", 0);
> @@ -824,40 +804,15 @@ DriveInfo *drive_init(QemuOpts *opts, void *opaque,
>      file = qemu_opt_get(opts, "file");
>      serial = qemu_opt_get(opts, "serial");
>  
> -    if ((buf = qemu_opt_get(opts, "if")) != NULL) {
> +    type = qemu_opt_get_enum(opts, "if", IF_IDE);
> +    if (type == IF_IDE)
> +	max_devs = MAX_IDE_DEVS;
> +    else if (type == IF_SCSI)
> +	max_devs = MAX_SCSI_DEVS;
> +    else
> +	max_devs = 0;
> +    if ((buf = qemu_opt_get(opts, "if")))
>          pstrcpy(devname, sizeof(devname), buf);
> -        if (!strcmp(buf, "ide")) {
> -	    type = IF_IDE;
> -            max_devs = MAX_IDE_DEVS;
> -        } else if (!strcmp(buf, "scsi")) {
> -	    type = IF_SCSI;
> -            max_devs = MAX_SCSI_DEVS;
> -        } else if (!strcmp(buf, "floppy")) {
> -	    type = IF_FLOPPY;
> -            max_devs = 0;
> -        } else if (!strcmp(buf, "pflash")) {
> -	    type = IF_PFLASH;
> -            max_devs = 0;
> -	} else if (!strcmp(buf, "mtd")) {
> -	    type = IF_MTD;
> -            max_devs = 0;
> -	} else if (!strcmp(buf, "sd")) {
> -	    type = IF_SD;
> -            max_devs = 0;
> -        } else if (!strcmp(buf, "virtio")) {
> -            type = IF_VIRTIO;
> -            max_devs = 0;
> -	} else if (!strcmp(buf, "xen")) {
> -	    type = IF_XEN;
> -            max_devs = 0;
> -	} else if (!strcmp(buf, "none")) {
> -	    type = IF_NONE;
> -            max_devs = 0;
> -	} else {
> -            fprintf(stderr, "qemu: unsupported bus type '%s'\n", buf);
> -            return NULL;
> -	}
> -    }
>  
>      if (cyls || heads || secs) {
>          if (cyls < 1 || (type == IF_IDE && cyls > 16383)) {
> @@ -874,67 +829,52 @@ DriveInfo *drive_init(QemuOpts *opts, void *opaque,
>  	}
>      }
>  
> -    if ((buf = qemu_opt_get(opts, "trans")) != NULL) {
> +    translation = qemu_opt_get_enum(opts, "trans", BIOS_ATA_TRANSLATION_AUTO);
> +    if (translation != BIOS_ATA_TRANSLATION_AUTO) {
>          if (!cyls) {
>              fprintf(stderr,
>                      "qemu: '%s' trans must be used with cyls,heads and secs\n",
>                      buf);
>              return NULL;
>          }
> -        if (!strcmp(buf, "none"))
> -            translation = BIOS_ATA_TRANSLATION_NONE;
> -        else if (!strcmp(buf, "lba"))
> -            translation = BIOS_ATA_TRANSLATION_LBA;
> -        else if (!strcmp(buf, "auto"))
> -            translation = BIOS_ATA_TRANSLATION_AUTO;
> -	else {
> -            fprintf(stderr, "qemu: '%s' invalid translation type\n", buf);
> -	    return NULL;
> -	}
>      }
>  
> -    if ((buf = qemu_opt_get(opts, "media")) != NULL) {
> -        if (!strcmp(buf, "disk")) {
> -	    media = MEDIA_DISK;
> -	} else if (!strcmp(buf, "cdrom")) {
> -            if (cyls || secs || heads) {
> -                fprintf(stderr,
> -                        "qemu: '%s' invalid physical CHS format\n", buf);
> -	        return NULL;
> -            }
> -	    media = MEDIA_CDROM;
> -	} else {
> -	    fprintf(stderr, "qemu: '%s' invalid media\n", buf);
> +    media = qemu_opt_get_enum(opts, "media", BDRV_MEDIA_DISK);
> +
> +    if (media == BDRV_MEDIA_CDROM) {
> +	if (cyls || secs || heads) {
> +	    fprintf(stderr,
> +		    "qemu: '%s' invalid physical CHS format\n", buf);
>  	    return NULL;
>  	}
>      }
>  
>      if ((buf = qemu_opt_get(opts, "cache")) != NULL) {
> -        if (!strcmp(buf, "off") || !strcmp(buf, "none")) {
> -            bdrv_flags |= BDRV_O_NOCACHE;
> -        } else if (!strcmp(buf, "writeback")) {
> -            bdrv_flags |= BDRV_O_CACHE_WB;
> -        } else if (!strcmp(buf, "unsafe")) {
> -            bdrv_flags |= BDRV_O_CACHE_WB;
> -            bdrv_flags |= BDRV_O_NO_FLUSH;
> -        } else if (!strcmp(buf, "writethrough")) {
> -            /* this is the default */
> -        } else {
> +        int mode = bdrv_cache_from_string(buf);
> +        int flags[] = {
> +            BDRV_O_NOCACHE,                 /* none */
> +            BDRV_O_NOCACHE,                 /* off */
> +            BDRV_O_CACHE_WB,                /* writeback */
> +            0,                              /* writethrough */
> +            BDRV_O_CACHE_WB|BDRV_O_NO_FLUSH /* unsafe */
> +        };
> +        verify_true(ARRAY_SIZE(flags) == BDRV_CACHE_LAST);
> +        if (mode < 0) {
>             fprintf(stderr, "qemu: invalid cache option\n");
>             return NULL;
>          }
> +        bdrv_flags |= flags[mode];
>      }
>  
>  #ifdef CONFIG_LINUX_AIO
>      if ((buf = qemu_opt_get(opts, "aio")) != NULL) {
> -        if (!strcmp(buf, "native")) {
> -            bdrv_flags |= BDRV_O_NATIVE_AIO;
> -        } else if (!strcmp(buf, "threads")) {
> -            /* this is the default */
> -        } else {
> +        int aio = bdrv_aio_from_string(buf);
> +        if (aio < 0) {
>             fprintf(stderr, "qemu: invalid aio option\n");
>             return NULL;
>          }
> +        if (aio == BDRV_AIO_NATIVE)
> +            bdrv_flags |= BDRV_O_NATIVE_AIO;
>      }
>  #endif
>  
> @@ -952,28 +892,18 @@ DriveInfo *drive_init(QemuOpts *opts, void *opaque,
>          }
>      }
>  
> -    on_write_error = BLOCK_ERR_STOP_ENOSPC;
> -    if ((buf = qemu_opt_get(opts, "werror")) != NULL) {
> +    on_write_error = qemu_opt_get_enum(opts, "werror", BLOCK_ERR_STOP_ENOSPC);
> +    if (on_write_error != BLOCK_ERR_STOP_ENOSPC) {
>          if (type != IF_IDE && type != IF_SCSI && type != IF_VIRTIO && type != IF_NONE) {
> -            fprintf(stderr, "werror is no supported by this format\n");
> -            return NULL;
> -        }
> -
> -        on_write_error = parse_block_error_action(buf, 0);
> -        if (on_write_error < 0) {
> +            fprintf(stderr, "werror is not supported by this format\n");
>              return NULL;
>          }
>      }
>  
> -    on_read_error = BLOCK_ERR_REPORT;
> -    if ((buf = qemu_opt_get(opts, "rerror")) != NULL) {
> +    on_read_error = qemu_opt_get_enum(opts, "rerror", BLOCK_ERR_REPORT);
> +    if (on_read_error != BLOCK_ERR_REPORT) {
>          if (type != IF_IDE && type != IF_VIRTIO && type != IF_NONE) {
> -            fprintf(stderr, "rerror is no supported by this format\n");
> -            return NULL;
> -        }
> -
> -        on_read_error = parse_block_error_action(buf, 1);
> -        if (on_read_error < 0) {
> +            fprintf(stderr, "rerror is not supported by this format\n");
>              return NULL;
>          }
>      }
> @@ -1044,7 +974,7 @@ DriveInfo *drive_init(QemuOpts *opts, void *opaque,
>          /* no id supplied -> create one */
>          dinfo->id = qemu_mallocz(32);
>          if (type == IF_IDE || type == IF_SCSI)
> -            mediastr = (media == MEDIA_CDROM) ? "-cd" : "-hd";
> +            mediastr = (media == BDRV_MEDIA_CDROM) ? "-cd" : "-hd";
>          if (max_devs)
>              snprintf(dinfo->id, 32, "%s%i%s%i",
>                       devname, bus_id, mediastr, unit_id);
> @@ -1070,16 +1000,16 @@ DriveInfo *drive_init(QemuOpts *opts, void *opaque,
>      case IF_XEN:
>      case IF_NONE:
>          switch(media) {
> -	case MEDIA_DISK:
> +        case BDRV_MEDIA_DISK:
>              if (cyls != 0) {
>                  bdrv_set_geometry_hint(dinfo->bdrv, cyls, heads, secs);
>                  bdrv_set_translation_hint(dinfo->bdrv, translation);
>              }
> -	    break;
> -	case MEDIA_CDROM:
> +            break;
> +        case BDRV_MEDIA_CDROM:
>              bdrv_set_type_hint(dinfo->bdrv, BDRV_TYPE_CDROM);
> -	    break;
> -	}
> +            break;
> +        }
>          break;
>      case IF_SD:
>          /* FIXME: This isn't really a floppy, but it's a reasonable
> @@ -1098,7 +1028,7 @@ DriveInfo *drive_init(QemuOpts *opts, void *opaque,
>          if (devaddr)
>              qemu_opt_set(opts, "addr", devaddr);
>          break;
> -    case IF_COUNT:
> +    default:
>          abort();
>      }
>      if (!file) {
> @@ -1111,7 +1041,7 @@ DriveInfo *drive_init(QemuOpts *opts, void *opaque,
>          bdrv_flags |= (BDRV_O_SNAPSHOT|BDRV_O_CACHE_WB|BDRV_O_NO_FLUSH);
>      }
>  
> -    if (media == MEDIA_CDROM) {
> +    if (media == BDRV_MEDIA_CDROM) {
>          /* CDROM is fine for any interface, don't check.  */
>          ro = 1;
>      } else if (ro == 1) {

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [Qemu-devel] [PATCH 08/19] Convert RTC to use enumerations for configuration parameters
  2010-06-07 14:42 ` [Qemu-devel] [PATCH 08/19] Convert RTC to use enumerations for configuration parameters Daniel P. Berrange
@ 2010-06-09 19:54   ` Luiz Capitulino
  0 siblings, 0 replies; 62+ messages in thread
From: Luiz Capitulino @ 2010-06-09 19:54 UTC (permalink / raw)
  To: Daniel P. Berrange; +Cc: qemu-devel

On Mon,  7 Jun 2010 15:42:21 +0100
"Daniel P. Berrange" <berrange@redhat.com> wrote:

> Convert the rtc clock and driftfix parameters to use enums for
> configuration. This ensures strict validation at time of config
> parsing.
> 
> Also fixes a bug in qemu-config.c where 'driftfix' was never
> enabled because this is a target independant compliation unit,
> thus cannot include config-target.h and thus never has the
> TARGET_I386 symbol defined.
> 
> Ideally the 'base' parameter would be an enum too, but this
> value is overloaded to also accept a pretty-printed start
> date.
> 
> Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
> ---
>  hw/mc146818rtc.c |    8 ++++----
>  qemu-config.c    |   27 +++++++++++++++++++++++----
>  sysemu.h         |   20 +++++++++++++++++++-
>  vl.c             |   34 ++++++++++------------------------
>  4 files changed, 56 insertions(+), 33 deletions(-)
> 
> diff --git a/hw/mc146818rtc.c b/hw/mc146818rtc.c
> index c3e6a70..cbb072c 100644
> --- a/hw/mc146818rtc.c
> +++ b/hw/mc146818rtc.c
> @@ -202,7 +202,7 @@ static void rtc_periodic_timer(void *opaque)
>      if (s->cmos_data[RTC_REG_B] & REG_B_PIE) {
>          s->cmos_data[RTC_REG_C] |= 0xc0;
>  #ifdef TARGET_I386
> -        if(rtc_td_hack) {
> +        if(rtc_driftfix == QEMU_RTC_DRIFTFIX_SLEW) {
>              if (s->irq_reinject_on_ack_count >= RTC_REINJECT_ON_ACK_COUNT)
>                  s->irq_reinject_on_ack_count = 0;		
>              apic_reset_irq_delivered();
> @@ -552,7 +552,7 @@ static int rtc_post_load(void *opaque, int version_id)
>      RTCState *s = opaque;
>  
>      if (version_id >= 2) {
> -        if (rtc_td_hack) {
> +        if (rtc_driftfix == QEMU_RTC_DRIFTFIX_SLEW) {
>              rtc_coalesced_timer_update(s);
>          }
>      }
> @@ -597,7 +597,7 @@ static void rtc_reset(void *opaque)
>      qemu_irq_lower(s->irq);
>  
>  #ifdef TARGET_I386
> -    if (rtc_td_hack)
> +    if (rtc_driftfix == QEMU_RTC_DRIFTFIX_SLEW)
>  	    s->irq_coalesced = 0;
>  #endif
>  }
> @@ -619,7 +619,7 @@ static int rtc_initfn(ISADevice *dev)
>  
>      s->periodic_timer = qemu_new_timer(rtc_clock, rtc_periodic_timer, s);
>  #ifdef TARGET_I386
> -    if (rtc_td_hack)
> +    if (rtc_driftfix == QEMU_RTC_DRIFTFIX_SLEW)
>          s->coalesced_timer =
>              qemu_new_timer(rtc_clock, rtc_coalesced_timer, s);
>  #endif
> diff --git a/qemu-config.c b/qemu-config.c
> index f656e6b..75cddc1 100644
> --- a/qemu-config.c
> +++ b/qemu-config.c
> @@ -288,6 +288,11 @@ QemuOptsList qemu_net_opts = {
>      },
>  };
>  
> +QEMU_ENUM_IMPL(qemu_rtc_clock, QEMU_RTC_CLOCK_LAST,
> +	       "host", "guest");
> +QEMU_ENUM_IMPL(qemu_rtc_driftfix, QEMU_RTC_DRIFTFIX_LAST,
> +	       "none", "slew");
> +
>  QemuOptsList qemu_rtc_opts = {
>      .name = "rtc",
>      .head = QTAILQ_HEAD_INITIALIZER(qemu_rtc_opts.head),
> @@ -297,12 +302,26 @@ QemuOptsList qemu_rtc_opts = {
>              .type = QEMU_OPT_STRING,
>          },{
>              .name = "clock",
> -            .type = QEMU_OPT_STRING,
> -#ifdef TARGET_I386
> +            .type = QEMU_OPT_ENUM,
> +            .validate = {
> +                .optEnum = {
> +                    .to_string = qemu_rtc_clock_to_string,
> +                    .to_string_list = qemu_rtc_clock_to_string_list,
> +                    .from_string = qemu_rtc_clock_from_string,
> +                    .last = QEMU_RTC_CLOCK_LAST,
> +                },
> +            },
>          },{
>              .name = "driftfix",
> -            .type = QEMU_OPT_STRING,
> -#endif
> +            .type = QEMU_OPT_ENUM,
> +            .validate = {
> +                .optEnum = {
> +                    .to_string = qemu_rtc_driftfix_to_string,
> +                    .to_string_list = qemu_rtc_driftfix_to_string_list,
> +                    .from_string = qemu_rtc_driftfix_from_string,
> +                    .last = QEMU_RTC_DRIFTFIX_LAST,
> +                },
> +            },
>          },
>          { /* end if list */ }
>      },
> diff --git a/sysemu.h b/sysemu.h
> index f0c5eb8..4d39566 100644
> --- a/sysemu.h
> +++ b/sysemu.h
> @@ -120,7 +120,6 @@ extern uint8_t irq0override;
>  extern DisplayType display_type;
>  extern const char *keyboard_layout;
>  extern int win2k_install_hack;
> -extern int rtc_td_hack;
>  extern int alt_grab;
>  extern int ctrl_grab;
>  extern int usb_enabled;
> @@ -133,7 +132,26 @@ extern int no_shutdown;
>  extern int semihosting_enabled;
>  extern int old_param;
>  extern int boot_menu;
> +
>  extern QEMUClock *rtc_clock;
> +extern int rtc_driftfix;
> +
> +enum {
> +    QEMU_RTC_CLOCK_HOST,
> +    QEMU_RTC_CLOCK_GUEST,
> +
> +    QEMU_RTC_CLOCK_LAST
> +};
> +QEMU_ENUM_DECL(qemu_rtc_clock);
> +
> +enum {
> +    QEMU_RTC_DRIFTFIX_NONE,
> +    QEMU_RTC_DRIFTFIX_SLEW,
> +
> +    QEMU_RTC_DRIFTFIX_LAST
> +};
> +QEMU_ENUM_DECL(qemu_rtc_driftfix);
> +
>  
>  #define MAX_NODES 64
>  extern int nb_numa_nodes;
> diff --git a/vl.c b/vl.c
> index 16491c4..0b38d62 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -201,7 +201,7 @@ CharDriverState *serial_hds[MAX_SERIAL_PORTS];
>  CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
>  CharDriverState *virtcon_hds[MAX_VIRTIO_CONSOLES];
>  int win2k_install_hack = 0;
> -int rtc_td_hack = 0;
> +int rtc_driftfix = QEMU_RTC_DRIFTFIX_NONE;
>  int usb_enabled = 0;
>  int singlestep = 0;
>  int smp_cpus = 1;
> @@ -418,6 +418,9 @@ static void configure_rtc_date_offset(const char *startdate, int legacy)
>  static void configure_rtc(QemuOpts *opts)
>  {
>      const char *value;
> +    QEMUClock *clocks[] = { host_clock, vm_clock };
> +    verify_true(ARRAY_SIZE(clocks) == QEMU_RTC_CLOCK_LAST);

 This and the other verify_true() usage are generating the following
build error for me when debug is enabled:

cc1: warnings being treated as errors
/home/lcapitulino/src/qmp-unstable/vl.c: In function ‘configure_rtc’:
/home/lcapitulino/src/qmp-unstable/vl.c:422: error: statement with no effect
/home/lcapitulino/src/qmp-unstable/vl.c: In function ‘drive_init’:
/home/lcapitulino/src/qmp-unstable/vl.c:847: error: statement with no effect
make[1]: *** [vl.o] Error 1
make: *** [subdir-libhw64] Error 2


> +    int clock;
>  
>      value = qemu_opt_get(opts, "base");
>      if (value) {
> @@ -429,28 +432,11 @@ static void configure_rtc(QemuOpts *opts)
>              configure_rtc_date_offset(value, 0);
>          }
>      }
> -    value = qemu_opt_get(opts, "clock");
> -    if (value) {
> -        if (!strcmp(value, "host")) {
> -            rtc_clock = host_clock;
> -        } else if (!strcmp(value, "vm")) {
> -            rtc_clock = vm_clock;
> -        } else {
> -            fprintf(stderr, "qemu: invalid option value '%s'\n", value);
> -            exit(1);
> -        }
> -    }
> -    value = qemu_opt_get(opts, "driftfix");
> -    if (value) {
> -        if (!strcmp(value, "slew")) {
> -            rtc_td_hack = 1;
> -        } else if (!strcmp(value, "none")) {
> -            rtc_td_hack = 0;
> -        } else {
> -            fprintf(stderr, "qemu: invalid option value '%s'\n", value);
> -            exit(1);
> -        }
> -    }
> +
> +    clock = qemu_opt_get_enum(opts, "clock", QEMU_RTC_CLOCK_HOST);
> +    rtc_clock = clocks[clock];
> +
> +    rtc_driftfix = qemu_opt_get_enum(opts, "driftfix", QEMU_RTC_DRIFTFIX_NONE);
>  }
>  
>  /***********************************************************/
> @@ -3149,7 +3135,7 @@ int main(int argc, char **argv, char **envp)
>                  win2k_install_hack = 1;
>                  break;
>              case QEMU_OPTION_rtc_td_hack:
> -                rtc_td_hack = 1;
> +                rtc_driftfix = QEMU_RTC_DRIFTFIX_SLEW;
>                  break;
>              case QEMU_OPTION_acpitable:
>                  do_acpitable_option(optarg);

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [Qemu-devel] [PATCH 09/19] Change 'query-version' to output broken down version string
  2010-06-07 15:11   ` Anthony Liguori
@ 2010-06-09 20:04     ` Luiz Capitulino
  0 siblings, 0 replies; 62+ messages in thread
From: Luiz Capitulino @ 2010-06-09 20:04 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: qemu-devel

On Mon, 07 Jun 2010 10:11:28 -0500
Anthony Liguori <anthony@codemonkey.ws> wrote:

> On 06/07/2010 09:42 AM, Daniel P. Berrange wrote:
> > A previous discussion brought up the fact that clients should
> > not have to parse version string from QMP, it should be given
> > to them pre-split.
> >
> > Change query-version output format from:
> >
> >    { "qemu": "0.11.50", "package": "" }
> >
> > to:
> >
> >    { qemu: { "major": 0, "minor": 11, "micro": 5 }, "package": "" }
> >    
> 
> We need to drop package entirely.

 Why? It's something that shouldn't be in the greeting message, but it's
a component of the version, so the only way to query it from QMP is by
using query-version.

> Instead vendors should use the vendor specific namespace to extend the 
> version.

 IMHO, vendor in QMP's terminology is someone adding extensions to
the protocol. Most distros won't do that, but they may carry not
upstream merged patches.

> I'd suggest changing the version output to:
> 
> { 'major': 0, 'minor': 11, 'micro': 5 }
> 
> For something like kvm, it can introduce a '__org.linux-kvm.release', 2 
> to that main dictionary.

 I think we need both, 'vendor' and 'package' keys and maybe 'vendor'
should be part of the greeting message so that clients can identify they
are talking to a non standard version.

> 
> Regards,
> 
> Anthony Liguori
> 
> > The major, minor&  micro keys are all integer values. package is
> > an arbitrary string whose format is defined by the OS package
> > maintainer.
> >
> > There is no need to preserve the existing string format of the 'qemu'
> > key, since QMP is not yet declared stable.
> >
> > Signed-off-by: Daniel P. Berrange<berrange@redhat.com>
> > ---
> >   monitor.c |   47 +++++++++++++++++++++++++++++++++++++++++++----
> >   1 files changed, 43 insertions(+), 4 deletions(-)
> >
> > diff --git a/monitor.c b/monitor.c
> > index 15b53b9..f0406e8 100644
> > --- a/monitor.c
> > +++ b/monitor.c
> > @@ -670,17 +670,56 @@ help:
> >   static void do_info_version_print(Monitor *mon, const QObject *data)
> >   {
> >       QDict *qdict;
> > +    QDict *qemu;
> >
> >       qdict = qobject_to_qdict(data);
> > +    qemu = qdict_get_qdict(qdict, "qemu");
> >
> > -    monitor_printf(mon, "%s%s\n", qdict_get_str(qdict, "qemu"),
> > -                                  qdict_get_str(qdict, "package"));
> > +    monitor_printf(mon, "%" PRId64 ".%" PRId64 ".%" PRId64 "%s\n",
> > +		   qdict_get_int(qemu, "major"),
> > +		   qdict_get_int(qemu, "minor"),
> > +		   qdict_get_int(qemu, "micro"),
> > +		   qdict_get_str(qdict, "package"));
> >   }
> >
> > +
> > +/**
> > + * do_info_version(): Show QEMU version
> > + *
> > + * Return a QDict with the following information:
> > + *
> > + * - "qemu": QEMU upstream version
> > + * - "package": QEMU packager's version
> > + *
> > + * The 'qemu' key value is a QDict containing three
> > + * integer values
> > + *
> > + * - "major": QEMU's major version
> > + * - "minor": QEMU's minor version
> > + * - "micro": QEMU's micro version
> > + *
> > + * The 'package' key value is a string in an format
> > + * defined by the OS distributor to reflect their
> > + * packaging of QEMU.
> > + *
> > + * Example:
> > + *
> > + * { qemu: { "major": 0, "minor": 11, "micro": 5 }, "package": "" }
> > + */
> >   static void do_info_version(Monitor *mon, QObject **ret_data)
> >   {
> > -    *ret_data = qobject_from_jsonf("{ 'qemu': %s, 'package': %s }",
> > -                                   QEMU_VERSION, QEMU_PKGVERSION);
> > +    const char *version = QEMU_VERSION;
> > +    int major = 0, minor = 0, micro = 0;
> > +    char *tmp;
> > +
> > +    major = strtol(version,&tmp, 10);
> > +    tmp++;
> > +    minor = strtol(tmp,&tmp, 10);
> > +    tmp++;
> > +    micro = strtol(tmp,&tmp, 10);
> > +
> > +    *ret_data = qobject_from_jsonf("{ 'qemu': { 'major': %d, 'minor': %d, 'micro': %d }, 'package': %s }",
> > +                                   major, minor, micro, QEMU_PKGVERSION);
> >   }
> >
> >   static void do_info_name_print(Monitor *mon, const QObject *data)
> >    
> 
> 

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [Qemu-devel] [PATCH 10/19] Add a query-machines command to QMP
  2010-06-07 17:07       ` Anthony Liguori
  2010-06-07 17:14         ` Daniel P. Berrange
@ 2010-06-09 20:06         ` Luiz Capitulino
  1 sibling, 0 replies; 62+ messages in thread
From: Luiz Capitulino @ 2010-06-09 20:06 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: qemu-devel

On Mon, 07 Jun 2010 12:07:56 -0500
Anthony Liguori <anthony@codemonkey.ws> wrote:

> On 06/07/2010 11:44 AM, Daniel P. Berrange wrote:
> > On Mon, Jun 07, 2010 at 10:13:27AM -0500, Anthony Liguori wrote:
> >    
> >> On 06/07/2010 09:42 AM, Daniel P. Berrange wrote:
> >>      
> >>> Add a new QMP monitor command 'query-machines' to discover what
> >>> machines are defined in the QEMU binary. This is an easily
> >>> parsable replacement for 'qemu -M ?'
> >>>
> >>>      [
> >>>          {
> >>>              "name": "pc-0.13",
> >>>              "description": "Standard PC",
> >>>              "default": 0
> >>>          },
> >>>          {
> >>>              "name": "pc",
> >>>              "description": "Standard PC",
> >>>              "canonical": "pc-0.13",
> >>>              "default": 1
> >>>          },
> >>>          {
> >>>              "name": "pc-0.12",
> >>>              "description": "Standard PC",
> >>>              "default": 0
> >>>          },
> >>>          ....
> >>>      ]
> >>>
> >>> No legacy readline monitor output is provided.
> >>>
> >>> In the future it would be desirable for each machine's QDict to
> >>> also include details of any qdev devices that are included by
> >>> default in the machine type.
> >>>
> >>> Signed-off-by: Daniel P. Berrange<berrange@redhat.com>
> >>> ---
> >>>   hw/boards.h |    1 +
> >>>   monitor.c   |    9 +++++++
> >>>   vl.c        |   70
> >>>   +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> >>>   3 files changed, 80 insertions(+), 0 deletions(-)
> >>>
> >>> diff --git a/hw/boards.h b/hw/boards.h
> >>> index 6f0f0d7..2f6003d 100644
> >>> --- a/hw/boards.h
> >>> +++ b/hw/boards.h
> >>> @@ -32,6 +32,7 @@ typedef struct QEMUMachine {
> >>>   } QEMUMachine;
> >>>
> >>>   int qemu_register_machine(QEMUMachine *m);
> >>> +void do_info_machines(Monitor *mon, QObject **data);
> >>>
> >>>   extern QEMUMachine *current_machine;
> >>>
> >>> diff --git a/monitor.c b/monitor.c
> >>> index f0406e8..b6aa2b4 100644
> >>> --- a/monitor.c
> >>> +++ b/monitor.c
> >>> @@ -55,6 +55,7 @@
> >>>   #include "json-streamer.h"
> >>>   #include "json-parser.h"
> >>>   #include "osdep.h"
> >>> +#include "hw/boards.h"
> >>>
> >>>   //#define DEBUG
> >>>   //#define DEBUG_COMPLETION
> >>> @@ -2449,6 +2450,14 @@ static const mon_cmd_t info_cmds[] = {
> >>>           .mhandler.info_new = do_info_version,
> >>>       },
> >>>       {
> >>> +        .name       = "machines",
> >>> +        .args_type  = "",
> >>> +        .params     = "",
> >>> +        .help       = "show the machine boards",
> >>> +        .user_print = monitor_user_noop,
> >>> +        .mhandler.info_new = do_info_machines,
> >>> +    },
> >>> +    {
> >>>           .name       = "commands",
> >>>           .args_type  = "",
> >>>           .params     = "",
> >>> diff --git a/vl.c b/vl.c
> >>> index 0b38d62..8043fac 100644
> >>> --- a/vl.c
> >>> +++ b/vl.c
> >>> @@ -1537,6 +1537,76 @@ static QEMUMachine *find_default_machine(void)
> >>>       return NULL;
> >>>   }
> >>>
> >>> +
> >>> +/**
> >>> + * do_info_machines(): Show machine boards
> >>> + *
> >>> + * Returns a QList object listing all machine boards
> >>> + * available with this QEMU target. Each element in
> >>> + * the list is a QDict object containing the following
> >>> + * keys
> >>> + *
> >>> + *  - "name": short name for the machine board
> >>> + *  - "description": long description of the board
> >>> + *  - "alias": name of an alias
> >>> + *
> >>> + * Example:
> >>> + *
> >>> + *  [
> >>> + *     {
> >>> + *       "name": "pc-0.13",
> >>> + *        "description": "Standard PC",
> >>> + *        "default": 0
> >>> + *     },
> >>> + *     {
> >>> + *       "name": "pc",
> >>> + *       "description": "Standard PC",
> >>> + *       "canonical": "pc-0.13",
> >>> + *       "default": 1
> >>> + *     },
> >>> + *     {
> >>> + *       "name": "pc-0.12",
> >>> + *       "description": "Standard PC",
> >>> + *       "default": 0
> >>> + *     },
> >>> + *     ....
> >>> + *  ]
> >>> + *
> >>> + */
> >>>
> >>>        
> >> My only suggestion would be to:
> >>
> >> { 'default-machine': 'pc',
> >>     'machines': [{
> >>       'name': 'pc',
> >>       'description': 'Standard PC',
> >>     },...]
> >> }
> >>
> >> I'd drop 'canonical' too.  Aliasing is an implementation detail and
> >> should not be exposed via the ABI.
> >>      
> > The alias/canonical mapping is something that libvirt needs to know in
> > order guarentee stable guest ABI for all configs it has.
> >
> > What happens is that an app using libvirt will request a guest config
> > with machine type 'pc',
> 
> Does the guest config encode the machine type?  Does that mean that I 
> can't specify pc-0.12 or pc-0.13?

 What about this string format 'pc-0.12', do we really want that kind
of string in QMP? Shouldn't it be broken into 'machine_type' and
'machine_version'?

> 
> Since most guests don't specify an explicit machine, can't libvirt just 
> use pc-<version> and be done with it?
> 
> Regards,
> 
> Anthony Liguori
> 
> >   and libvirt resolves that to the canonical
> > type 'pc-0.12', and then launches QEMU with '-M pc-0.12' instead of
> > the '-M pc'. If libvirt passed '-M pc' and let QEMU do the canonicalization,
> > the guest ABI would no longer be stable across QEMU upgrades because the
> > canonicalization changes to point to the newer version.
> >
> > Regards,
> > Daniel
> >    
> 
> 

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [Qemu-devel] [PATCH 00/19] RFC: Reporting QEMU binary capabilities
  2010-06-07 16:07 ` [Qemu-devel] " Anthony Liguori
@ 2010-06-09 20:25   ` Luiz Capitulino
  0 siblings, 0 replies; 62+ messages in thread
From: Luiz Capitulino @ 2010-06-09 20:25 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: qemu-devel

On Mon, 07 Jun 2010 11:07:14 -0500
Anthony Liguori <anthony@codemonkey.ws> wrote:

> Hi Daniel,
> 
> On 06/07/2010 09:42 AM, Daniel P. Berrange wrote:
> > As everyone here agrees, having management apps parse -help output
> > to determine the QEMU capabilities is not at all nice, because it
> > is an ill-defined&  fragile data format. Looking more broadly these
> > same issues apply to all the other command line options that accept
> > a '?' flag for querying capabilities.
> >
> > We have a very nice structured data format we could be using for
> > this: JSON. What's lacking is code to output all this information
> > in the JSON format. This patch series can thus be summarized as
> > 'JSON for everything'
> >    
> 
> For the most part, this series looks pretty nice.

 For me too, some comments though:

  - All protocol visible changes must be documented in qemu-monitor.hx and
    as there's a lot of stuff being exposed, would be good to get more ACKs
    on them (maybe from Avi, Markus etc)

  - This series overlaps a bit with self-description support, specially if
    you're willing to work on a really useful version of query-commands. It's
    worth reading the following thread:

       http://lists.gnu.org/archive/html/qemu-devel/2010-01/msg00852.html

  - As the series is going to change, I've skipped some implementation details
    while reviewing. Will do a deeper review in the non-rfc version
> 
> I think my only real objection is the query-argv bits.  The enums are a 
> bit awkward to define but I understand the value of it and I can't think 
> of a better way to do it.
> 
> Regards,
> 
> Anthony Liguori
> 
> > For reference, here is the full list of information libvirt currently
> > queries from QEMU:
> >
> >    * Detection of command line flags (-help parsing)
> >
> >      -no-kqemu, -no-kvm, -enable-kvm, -no-reboot
> >      -name, -uuid, -xen-domid, -domid, -drive
> >      -vga, -std-vga, -pcidevice, -mem-path
> >      -chardev, -balloon, -device, -rtc, -rtc-td-hack
> >      -no-hpet, -no-kvm-pit-reinjection, -tdf
> >      -fsdev -sdl
> >
> >    * Detection of parameters (-help parsing)
> >
> >       -drive format=
> >       -drive boot=
> >       -drive serial=
> >       -drive cache=
> >       -cpu cores=, threads=, sockets=
> >       -netdev vhost=
> >
> >    * Detection of parameter values (-help parsing)
> >
> >       -drive cache=writethrough|writeback|none
> >         vs
> >       -drive cache=default|on|off
> >
> >    * Version number  (-help parsing)
> >
> >      -netdev  + 0.13.0
> >
> >      0.9.0  for VNC syntax
> >
> >      0.10.0 for vnet hdr
> >
> >    * Parse -M ?  output to get list of machine types + aliases
> >
> >    * Parse -device pci-assign,? to check for 'configfd' parameter
> >
> >    * Parse -cpu ?  to get list of named CPU types
> >
> >    * Parse binary name (qemu-system-XXXX) to guess arch of target
> >
> >
> > This isn't an 100% exhaustive list of things that we would like
> > to be able to get access to though. It can likely cover all of
> > the following:
> >
> >   * Version
> >
> >        QEMU major, minor, micro numbers. KVM version. Package
> >        version
> >
> >   * Devices
> >
> >        List of device names. Parameter names. Parameter value
> >        data types. Allowed strings for enums
> >
> >   * Arguments
> >
> >        List of command line arguments. Parameter names. Parameter
> >        value data types. Allowed strings for enums
> >
> >   * Machine types
> >
> >        List of names + aliases
> >        List of default devices in machine
> >
> >   * CPU types
> >
> >        List of names, associated feature flags, all allowed
> >        feature flags
> >
> >   * Target info
> >
> >        Arch name, wordsize
> >
> >   * Monitor commands
> >
> >        List of all monitor commands. Parameter names. Parameter
> >        value data types. Allowed strings for enums
> >
> >   * Block device backends
> >
> >        List of all block device backends. Parameter names.
> >        Parameter value data types. Allowed strings for enums
> >
> >   * Netdev device backends
> >
> >        List of all netdev device backends. Parameter names.
> >        Parameter value data types. Allowed strings for enums
> >
> >   * Chardev device backends
> >
> >        List of all chardev device backends. Parameter names.
> >        Parameter value data types. Allowed strings for enums
> >
> >
> > This patch series attempts to satisfy as much of this as is
> > feasible with the current QEMU codebase structure. The series
> > comprises four stages
> >
> >   * Some basic infrastructure. Support for JSON pretty printing.
> >     Introduction of standardized helpers for converting enums
> >     to/from strings. Introduction of an 'enum' data type for
> >     QemuOpt to expose a formal list of valid values&  simplify
> >     config handling / parsing. Compile time assertion checking
> >
> >   * Convert driver, netdev&  rtc config options to use the new
> >     enum data type for all appropriate args
> >
> >   * Add new QMP monitor commands exposing data for machine
> >     types, devices, cpu types, arch target, argv, config params,
> >     and netdev backends.
> >
> >   * Add a new '-capabilities' command line arg as syntactic
> >     sugar for the monitor commands that just report on static
> >     info about the QEMU binary.
> >
> > The main problem encountered with this patch series is the
> > split between argv and config parameters. The qemu-config.c
> > file provides the information is a good data format, allowing
> > programatic access to the list of parameters for each config
> > option (eg, the 'cache', 'file', 'aio', etc bits for -drive).
> > There are some issues with it though
> >
> >   - It lacks a huge amount of coverage wrt to the full argv
> >     available, even simple things like the '-m' argument
> >     don't exist.
> >
> >   - It is inconsistent in handling parameters. eg it  hands
> >     off validation of netdev backends to other code, to allow
> >     for handling of different parameters for tap vs user vs
> >     socket backends.  For chardev backends though, it directly
> >     includes a union of all possible parameters.
> >
> > Ideally the 'query-argv' command would not be required, but
> > unless those problems with the qemu-config are resolved, it
> > is the only way to access alot of the information. This is
> > sub-optimal because although it lets apps easily determine
> > whether an arg like '-smp' is present, it still leaves them
> > parsing that args' help string to discover parameters.
> >
> > This series is lacking a 'query-blockdev' and 'query-chardev'
> > commands to report on availability of backends for -blockdev
> > and '-chardev' commands.
> >
> > Finally the existing 'query-commands' output is lacking any
> > information about the parameters associated with each command.
> > This needs to be addressed somehow.
> >
> > In summary though, IMHO, this patch series provides a good
> > base for providing information about static QEMU binary
> > capabilities to applications. It should ensure apps never
> > again need to go anywhere near -help, -M ?, -cpu ?, -device ?,
> > -soundhw ? and other such ill defined output formats.
> >
> > NB, I know this patch series will probably clash horribly
> > with other patch series recently posted for review, in
> > particular Jes' cleanup of vl.c   I will rebase as required
> > if any of those get merged.
> >
> > This series is currently based on GIT master as of:
> >
> >    commit fd1dc858370d9a9ac7ea2512812c3a152ee6484b
> >    Author: Edgar E. Iglesias<edgar.iglesias@gmail.com>
> >    Date:   Mon Jun 7 11:54:27 2010 +0200
> >
> > Regards,
> > Daniel
> >
> >   Makefile.objs                |    2
> >   block.c                      |   32 +-
> >   block.h                      |   55 ++++
> >   cpus.c                       |   78 ++++++
> >   cpus.h                       |    1
> >   hw/boards.h                  |    2
> >   hw/mc146818rtc.c             |    8
> >   hw/qdev.c                    |  148 +++++++++++++
> >   hw/qdev.h                    |    2
> >   monitor.c                    |  167 ++++++++++++++
> >   monitor.h                    |    5
> >   net.c                        |  173 ++++++++++-----
> >   net.h                        |    2
> >   qemu-config.c                |  228 +++++++++++++++++++-
> >   qemu-config.h                |    2
> >   qemu-enum.c                  |   44 +++
> >   qemu-enum.h                  |   45 ++++
> >   qemu-option.c                |   35 +++
> >   qemu-option.h                |   14 +
> >   qemu-options.hx              |    9
> >   qjson.c                      |   55 ++++
> >   qjson.h                      |    1
> >   sysemu.h                     |   43 +++
> >   target-arm/cpu.h             |    7
> >   target-arm/helper.c          |   21 +
> >   target-cris/cpu.h            |    7
> >   target-cris/translate.c      |   22 +
> >   target-i386/cpu.h            |    7
> >   target-i386/cpuid.c          |   79 +++++++
> >   target-m68k/cpu.h            |    9
> >   target-m68k/helper.c         |   23 ++
> >   target-mips/cpu.h            |    7
> >   target-mips/translate.c      |    4
> >   target-mips/translate_init.c |   19 +
> >   target-ppc/cpu.h             |    7
> >   target-ppc/translate.c       |    4
> >   target-ppc/translate_init.c  |   17 +
> >   target-sh4/cpu.h             |    8
> >   target-sh4/translate.c       |   23 ++
> >   target-sparc/cpu.h           |    9
> >   target-sparc/helper.c        |   60 +++++
> >   verify.h                     |  164 ++++++++++++++
> >   vl.c                         |  482 +++++++++++++++++++++++++++++--------------
> >   43 files changed, 1869 insertions(+), 261 deletions(-)
> >
> >
> >
> >    
> 
> 

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [Qemu-devel] Re: [PATCH 14/19] Add a query-argv command to QMP
  2010-06-07 15:01   ` Anthony Liguori
@ 2010-06-10 15:34     ` Paolo Bonzini
  2010-06-26  7:30     ` [Qemu-devel] " Markus Armbruster
  1 sibling, 0 replies; 62+ messages in thread
From: Paolo Bonzini @ 2010-06-10 15:34 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: qemu-devel

On 06/07/2010 05:01 PM, Anthony Liguori wrote:
> On 06/07/2010 09:42 AM, Daniel P. Berrange wrote:
>> Add a new QMP command called 'query-argv' to information about the
>> command
>> line arguments supported by the QEMU binary. This is intended to
>> remove the
>> need for apps to parse '-help' output.
>
> This is just as bad as parsing -help output IMHO.
>
> The problem with something like this is that it discourages people from
> using proper APIs to get at capabilities information.

What about a query-qemuopts instead?  This has a well-defined schema 
and, while it won't let you get all arguments, going forward libvirt is 
going to try and use more qemuopts options and only the bare minimum 
legacy options (-incoming, -S).

Paolo

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [Qemu-devel] [PATCH 00/19] RFC: Reporting QEMU binary capabilities
  2010-06-07 14:42 [Qemu-devel] [PATCH 00/19] RFC: Reporting QEMU binary capabilities Daniel P. Berrange
                   ` (20 preceding siblings ...)
  2010-06-07 16:07 ` [Qemu-devel] " Anthony Liguori
@ 2010-06-26  6:45 ` Markus Armbruster
  21 siblings, 0 replies; 62+ messages in thread
From: Markus Armbruster @ 2010-06-26  6:45 UTC (permalink / raw)
  To: Daniel P. Berrange; +Cc: qemu-devel

"Daniel P. Berrange" <berrange@redhat.com> writes:

[...]
> The main problem encountered with this patch series is the
> split between argv and config parameters. The qemu-config.c
> file provides the information is a good data format, allowing
> programatic access to the list of parameters for each config
> option (eg, the 'cache', 'file', 'aio', etc bits for -drive).
> There are some issues with it though
>
>  - It lacks a huge amount of coverage wrt to the full argv
>    available, even simple things like the '-m' argument
>    don't exist.
>
>  - It is inconsistent in handling parameters. eg it  hands
>    off validation of netdev backends to other code, to allow
>    for handling of different parameters for tap vs user vs
>    socket backends.  For chardev backends though, it directly
>    includes a union of all possible parameters.

The problem behind this "inconsistency" (first order approximation):
there are fixed options, and several sets of variable options.  One of
the fixed options is the discriminator, and its value determines which
set of variable options applies.

You can ignore this and put all variable options right into the
QemuOptsList.desc[].  qemu-option still catches "alway-invalid" options,
but application code needs to check again.  If the variable sets
conflict, we're reduced to QEMU_OPT_STRING type, and have to leave
type-checking to application code.

We can also have an empty desc[], and simply leave all of the validation
job to application code.  Typical way to do it: get discriminator value,
look up its desc[], pass it to qemu_opts_validate().  This is how
-netdev works.  Drawbacks: duplicates fixed options in every desc[],
even fixed options are hidden fairly deep in application code.

It's easy to do better for fixed options: put them in
QemuOptsList.desc[], use qemu_opts_validate() only for the variable
options.  I hope to post a patch for that soon.

Pulling the variable options out of application code is a bit harder.
More so for -device than for -netdev.

[...]

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [Qemu-devel] [PATCH 03/19] Add enum handlers for easy & efficient string <-> int conversion
  2010-06-07 14:42 ` [Qemu-devel] [PATCH 03/19] Add enum handlers for easy & efficient string <-> int conversion Daniel P. Berrange
  2010-06-09 19:52   ` Luiz Capitulino
@ 2010-06-26  6:52   ` Markus Armbruster
  1 sibling, 0 replies; 62+ messages in thread
From: Markus Armbruster @ 2010-06-26  6:52 UTC (permalink / raw)
  To: Daniel P. Berrange; +Cc: qemu-devel

"Daniel P. Berrange" <berrange@redhat.com> writes:

> There is quite alot of code using an enumeration of possible
> values, which also needs todo conversions to/from a string
> representation of enum values. These string <-> int conversions
> have been repeated in an adhoc manner throughout the code.
>
> This makes it hard to report on the list of valid strings,
> eg in help output, or todo proper validation in the qemu
> config/option parsing routines.

Correct.

> This addresses the first problem by introducing a standard
> set of routines for performing string <-> int conversions
> for enums. There are two restrictions on using these helpers,
> the first enum value must be 0, and there must be a sentinal
> in the enum to provide the max value.
>
> For each enumeration, three functions will be made available
>
>  - string to int convertor:
>
>    int XXXX_from_string(const char *value);
>
>    Returns -1 if the value was not an allowed string for the
>    enumeration. Returns >= 0 for a valid value
>
>  - int to string convertor
>
>    const char * XXXX_to_string(int value);
>
>    Returns NULL if the value was not a member of the
>    enumeration. Returns a non-NULL sstring for valid value
>
>  - string list generator
>
>    char * XXXX_to_string_list(void);
>
>    Returns a malloc'd string containing all valid values,
>    separated by commas. Caller must free the string.

Make the separator an argument?

Return a malloc'ed char **, NULL terminated?

> The general usage pattern is as follows.
[...]

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [Qemu-devel] [PATCH 04/19] Add support for a option parameter as an enum
  2010-06-07 14:42 ` [Qemu-devel] [PATCH 04/19] Add support for a option parameter as an enum Daniel P. Berrange
@ 2010-06-26  6:59   ` Markus Armbruster
  0 siblings, 0 replies; 62+ messages in thread
From: Markus Armbruster @ 2010-06-26  6:59 UTC (permalink / raw)
  To: Daniel P. Berrange; +Cc: qemu-devel

"Daniel P. Berrange" <berrange@redhat.com> writes:

> This adds a new option parameter QEMU_OPT_ENUM. The user
> provides the value in its string representation. The parser
> validates this and converts it to integer representation
> for internal use. If the user supplies an invalid value
> it will report the precise allowed list of values.
>
> Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
> ---
>  qemu-option.c |   31 +++++++++++++++++++++++++++++++
>  qemu-option.h |   10 ++++++++++
>  2 files changed, 41 insertions(+), 0 deletions(-)
>
> diff --git a/qemu-option.c b/qemu-option.c
> index acd74f9..bb9cc43 100644
> --- a/qemu-option.c
> +++ b/qemu-option.c
> @@ -238,6 +238,24 @@ static int parse_option_size(const char *name, const char *value, uint64_t *ret)
>      return 0;
>  }
>  
> +static int parse_option_enum(const char *name, const char *value, int *ret, const QemuOptDesc *desc)
> +{
> +    if (!value) {
> +        qerror_report(QERR_INVALID_PARAMETER_VALUE, name, "a enumerated string");
> +        return -1;
> +    }
> +
> +    *ret = (desc->validate.optEnum.from_string)(value);
> +    if (*ret < 0) {
> +        char *valid = (desc->validate.optEnum.to_string_list)();
> +        qerror_report(QERR_INVALID_PARAMETER_VALUE, name, valid);
> +        qemu_free(valid);
> +        return -1;
> +    }
> +    return 0;
> +}
> +
> +
>  /*
>   * Sets the value of a parameter in a given option list. The parsing of the
>   * value depends on the type of option:
> @@ -516,6 +534,7 @@ struct QemuOpt {
>      union {
>          int      boolean;
>          uint64_t uint;
> +        int      enumVal;
>      } value;
>  
>      QemuOpts     *opts;
> @@ -578,6 +597,16 @@ uint64_t qemu_opt_get_size(QemuOpts *opts, const char *name, uint64_t defval)
>      return opt->value.uint;
>  }
>  
> +int qemu_opt_get_enum(QemuOpts *opts, const char *name, int defval)
> +{
> +    QemuOpt *opt = qemu_opt_find(opts, name);
> +
> +    if (opt == NULL)
> +        return defval;
> +    assert(opt->desc && opt->desc->type == QEMU_OPT_ENUM);
> +    return opt->value.enumVal;
> +}
> +
>  static int qemu_opt_parse(QemuOpt *opt)
>  {
>      if (opt->desc == NULL)
> @@ -592,6 +621,8 @@ static int qemu_opt_parse(QemuOpt *opt)
>          return parse_option_number(opt->name, opt->str, &opt->value.uint);
>      case QEMU_OPT_SIZE:
>          return parse_option_size(opt->name, opt->str, &opt->value.uint);
> +    case QEMU_OPT_ENUM:
> +        return parse_option_enum(opt->name, opt->str, &opt->value.enumVal, opt->desc);
>      default:
>          abort();
>      }
> diff --git a/qemu-option.h b/qemu-option.h
> index 4823219..3540a9b 100644
> --- a/qemu-option.h
> +++ b/qemu-option.h
> @@ -89,12 +89,21 @@ enum QemuOptType {
>      QEMU_OPT_BOOL,        /* on/off                                               */
>      QEMU_OPT_NUMBER,      /* simple number                                        */
>      QEMU_OPT_SIZE,        /* size, accepts (K)ilo, (M)ega, (G)iga, (T)era postfix */
> +    QEMU_OPT_ENUM,        /* int, from user string validated against an enum      */
>  };

Could replace QEMU_OPT_BOOL by QEMU_OPT_ENUM.

>  
>  typedef struct QemuOptDesc {
>      const char *name;
>      enum QemuOptType type;
>      const char *help;
> +    union {
> +        struct {
> +            int (*from_string)(const char *);
> +            const char *(*to_string)(int);
> +            char *(*to_string_list)(void);
> +            int last;
> +        } optEnum;
> +    } validate;
>  } QemuOptDesc;
>  
>  struct QemuOptsList {

I think this enum stuff would be useful for qdev's PropertyInfo as well.
Maybe we should try to share more conversions to and from strings with
it.

> @@ -108,6 +117,7 @@ const char *qemu_opt_get(QemuOpts *opts, const char *name);
>  int qemu_opt_get_bool(QemuOpts *opts, const char *name, int defval);
>  uint64_t qemu_opt_get_number(QemuOpts *opts, const char *name, uint64_t defval);
>  uint64_t qemu_opt_get_size(QemuOpts *opts, const char *name, uint64_t defval);
> +int qemu_opt_get_enum(QemuOpts *opts, const char *name, int defval);
>  int qemu_opt_set(QemuOpts *opts, const char *name, const char *value);
>  typedef int (*qemu_opt_loopfunc)(const char *name, const char *value, void *opaque);
>  int qemu_opt_foreach(QemuOpts *opts, qemu_opt_loopfunc func, void *opaque,

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [Qemu-devel] [PATCH 05/19] Ensure that QEMU exits if drive_add parsing fails
  2010-06-07 14:42 ` [Qemu-devel] [PATCH 05/19] Ensure that QEMU exits if drive_add parsing fails Daniel P. Berrange
@ 2010-06-26  7:04   ` Markus Armbruster
  0 siblings, 0 replies; 62+ messages in thread
From: Markus Armbruster @ 2010-06-26  7:04 UTC (permalink / raw)
  To: Daniel P. Berrange; +Cc: qemu-devel

"Daniel P. Berrange" <berrange@redhat.com> writes:

> The drive_add() method returns NULL if it failed to parse the
> parameter values for any reason. All callers must check this
> and exit if failure occurred. Annotate the method so that the
> compiler validates this.

Good move.  Need more of that.

> Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
> ---
>  vl.c |   38 ++++++++++++++++++++++++++------------
>  1 files changed, 26 insertions(+), 12 deletions(-)
>
> diff --git a/vl.c b/vl.c
> index 7121cd0..3d08a44 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -654,6 +654,7 @@ static int bt_parse(const char *opt)
>  #define MTD_ALIAS "if=mtd"
>  #define SD_ALIAS "index=0,if=sd"
>  
> +QEMU_WARN_UNUSED_RESULT
>  QemuOpts *drive_add(const char *file, const char *fmt, ...)

The *declaration* needs QEMU_WARN_UNUSED_RESULT.  Tacking it onto the
definition only protects this compilation unit.

[...]

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [Qemu-devel] [PATCH 06/19] Convert drive options to use enumeration data type
  2010-06-07 14:42 ` [Qemu-devel] [PATCH 06/19] Convert drive options to use enumeration data type Daniel P. Berrange
  2010-06-09 19:52   ` Luiz Capitulino
@ 2010-06-26  7:07   ` Markus Armbruster
  1 sibling, 0 replies; 62+ messages in thread
From: Markus Armbruster @ 2010-06-26  7:07 UTC (permalink / raw)
  To: Daniel P. Berrange; +Cc: qemu-devel

"Daniel P. Berrange" <berrange@redhat.com> writes:

> This converts the drive options if, trans, media, cache, aio,
> rerror and werror to use the QEMU_OPT_ENUM datatype. This
> standardizes the string parsing and error reporting
>
>   $ qemu  -drive file=foo,werror=stop3
>   qemu: -drive file=foo,if=mtd,werror=stop3: Parameter 'werror' expects report, ignore, enospc, stop
>
>   $ qemu  -readconfig bar.cfg
>   qemu:bar.cfg:6: Parameter 'werror' expects report, ignore, enospc, stop
>   read config bar.cfg: Invalid argument
>
> * block.c: Implementations for all enumerations
> * block.h, sysemu.h: Declare enumerations
> * qemu-config.c: Convert if, trans, media, cache, aio,
>   rerror and werror to use the QEMU_OPT_ENUM
> * vl.c: Remove handcrafted string -> int conversions in drive_init
>
> Signed-off-by: Daniel P. Berrange <berrange@redhat.com>

Conflicts mightily with my work, but I love it anyway :)

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [Qemu-devel] [PATCH 11/19] Add a query-devices command to QMP
  2010-06-07 16:03     ` Daniel P. Berrange
@ 2010-06-26  7:12       ` Markus Armbruster
  0 siblings, 0 replies; 62+ messages in thread
From: Markus Armbruster @ 2010-06-26  7:12 UTC (permalink / raw)
  To: Daniel P. Berrange; +Cc: qemu-devel

"Daniel P. Berrange" <berrange@redhat.com> writes:

> On Mon, Jun 07, 2010 at 10:14:00AM -0500, Anthony Liguori wrote:
>> On 06/07/2010 09:42 AM, Daniel P. Berrange wrote:
>> >Adds a command to QMP called 'query-devices' to allow for discovery
>> >of all devices known to the QEMU binary. THis is inteded to replace
>> >use of the '-device ?' and '-device devtype,?' command line args
>> >
>> >The data format is designed to allow easy extension to support more
>> >data:
>> >   
>> 
>> query-qdm?
>
> Ahh, I missed that because it is not ported to QMP yet. This patch 
> should nicely dovetail with that command.

info qdm should be implemented as pretty-printer on top of query-qdm.

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [Qemu-devel] [PATCH 12/19] Add a query-cputypes command to QMP
  2010-06-07 14:42 ` [Qemu-devel] [PATCH 12/19] Add a query-cputypes " Daniel P. Berrange
@ 2010-06-26  7:18   ` Markus Armbruster
  0 siblings, 0 replies; 62+ messages in thread
From: Markus Armbruster @ 2010-06-26  7:18 UTC (permalink / raw)
  To: Daniel P. Berrange; +Cc: qemu-devel

"Daniel P. Berrange" <berrange@redhat.com> writes:

> This adds a new QMP command called 'query-cputypes' to allow
> for discovery of CPU types known to the QEMU binary. This is
> intended to relpace the need to parse '-cpu ?', '-cpu ?model'
> and '-cpu ?dump'
>
> Most targets have a simple structure listing just the CPU
> model names (and optionally a 'description'), with room for
> future expansion of extra attributes against each model
>
>   {
>       "cputypes": {
>           "models": [
>               {
>                   "name": "arm926"
>               },
>               {
>                   "name": "arm946"
>               },
>               {
>                   "name": "arm1026"
>               },
>               ....
>           ]
>       }
>   }
>
> The sparc and x86 targets have extra architecture specific
> metatadata. These are in keys 'x86info' and 'sparcinfo'
> against each CPU model dict. These keys are repeated at the
> top level to give data about all allowed feature names
>
> A trimmed example:
>
> {
>     "cputypes": {
>         "models": [
>             {
>                 "name": "n270",
>                 "description": "Intel(R) Atom(TM) CPU N270   @ 1.60GHz",
>                 "x86info": {
>                     "xlevel": 2147483658,
>                     "family": 6,
>                     "vendor": "",
>                     "level": 5,
>                     "model": 28,
>                     "stepping": 2,
>                     "features": {
>                         "ext_edx": [
>                             "lahf_lm"
>                         ],
>                         "edx": [
>                             "pbe",
>                             "tm",
>                             "ht",
>                             "ss",
>                             "sse2",
>                             ...
>                         ]
>                     }
>                 }
>             }
>         ],
>         "x86info": {
>             "features": {
>                 "ext_edx": [
>                     21,
>                     20,
>                     "nodeid_msr",
>                     "cvt16",
>                     17,
>                     "fma4",
>                     15,
>                     14,
>                     "wdt",
>                     ....
>                 ]
>             }
>         }
>     }
> }
>
> No mapping to the legacy readline monitor is provided


An alternative to arch-specific keys with equally arch-specific values
would be a arch-independent key with a discriminated union value.

  {
      "cputypes": {
          "models": [
              {
                  "name": "n270",
                  "description": "Intel(R) Atom(TM) CPU N270   @ 1.60GHz",
                  "arch-info": {
                      "arch": "x86",
                      "xlevel": 2147483658,
                      "family": 6,
                      ...

Dunno.

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [Qemu-devel] [PATCH 14/19] Add a query-argv command to QMP
  2010-06-07 15:01   ` Anthony Liguori
  2010-06-10 15:34     ` [Qemu-devel] " Paolo Bonzini
@ 2010-06-26  7:30     ` Markus Armbruster
  1 sibling, 0 replies; 62+ messages in thread
From: Markus Armbruster @ 2010-06-26  7:30 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: qemu-devel

Anthony Liguori <anthony@codemonkey.ws> writes:

> On 06/07/2010 09:42 AM, Daniel P. Berrange wrote:
>> Add a new QMP command called 'query-argv' to information about the command
>> line arguments supported by the QEMU binary. This is intended to remove the
>> need for apps to parse '-help' output.
>>    
>
> This is just as bad as parsing -help output IMHO.
>
> The problem with something like this is that it discourages people
> from using proper APIs to get at capabilities information.

The interfaces to be used by management software should be
self-documenting, i.e. the client should be able to examine the
available interface over that interface.

This applies to QMP.  It equally applies to those parts of command line
we want management software to use.

Example: We don't need to provide machine-readable descriptions for all
the various options to configure devices, because management software
should use -device.  We do need to provide a description for -device.
Note: if we make device_add fully cold-plug capable, we could point
management software to QMP instead.

Such command-line self-documentation would also guide management
software to "proper" use of the command line.

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [Qemu-devel] [PATCH 16/19] Add a query-netdev command to QMP
  2010-06-07 15:15   ` Anthony Liguori
@ 2010-06-26  7:32     ` Markus Armbruster
  0 siblings, 0 replies; 62+ messages in thread
From: Markus Armbruster @ 2010-06-26  7:32 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: qemu-devel

Anthony Liguori <anthony@codemonkey.ws> writes:

> On 06/07/2010 09:42 AM, Daniel P. Berrange wrote:
>> This adds a new QMP command called query-netdev to provide information
>> about the available netdev backends in the QEMU binary. There is no
>> existing '-netdev ?' support, but if there was, this would obsolete it
>>
>> The data format looks like
>>
>>      [
>>          {
>>              "name": "user",
>>              "props": [
>>                  {
>>                      "name": "type",
>>                      "help": "net client type (nic, tap etc.)",
>>                      "type": "string"
>>                  },
>>    
>
> I'm not sure it's a good idea to expose the help text.  That bakes it
> into the ABI which seems bad.

Bah.  Tell clients "this part is informative and not ABI, and you'll die
a horrible death if you parse it", then change it a couple of times to
drive the point home.

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [Qemu-devel] [PATCH 17/19] Add a query-config command to QMP
  2010-06-07 14:42 ` [Qemu-devel] [PATCH 17/19] Add a query-config " Daniel P. Berrange
@ 2010-06-26  7:34   ` Markus Armbruster
  0 siblings, 0 replies; 62+ messages in thread
From: Markus Armbruster @ 2010-06-26  7:34 UTC (permalink / raw)
  To: Daniel P. Berrange; +Cc: qemu-devel

"Daniel P. Berrange" <berrange@redhat.com> writes:

> Add a new command to QMP called 'query-config' that provides
> information about the allowed configuration file entries for
> the binary.

The config file is really just another syntax for the command-line
options using QemuOptsList.  Not sure we want to describe them entirely
separately.

^ permalink raw reply	[flat|nested] 62+ messages in thread

end of thread, other threads:[~2010-06-26  7:35 UTC | newest]

Thread overview: 62+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-06-07 14:42 [Qemu-devel] [PATCH 00/19] RFC: Reporting QEMU binary capabilities Daniel P. Berrange
2010-06-07 14:42 ` [Qemu-devel] [PATCH 01/19] Add support for JSON pretty printing Daniel P. Berrange
2010-06-09 19:51   ` Luiz Capitulino
2010-06-07 14:42 ` [Qemu-devel] [PATCH 02/19] Add support for compile time assertions Daniel P. Berrange
2010-06-07 15:35   ` [Qemu-devel] " Paolo Bonzini
2010-06-07 14:42 ` [Qemu-devel] [PATCH 03/19] Add enum handlers for easy & efficient string <-> int conversion Daniel P. Berrange
2010-06-09 19:52   ` Luiz Capitulino
2010-06-26  6:52   ` Markus Armbruster
2010-06-07 14:42 ` [Qemu-devel] [PATCH 04/19] Add support for a option parameter as an enum Daniel P. Berrange
2010-06-26  6:59   ` Markus Armbruster
2010-06-07 14:42 ` [Qemu-devel] [PATCH 05/19] Ensure that QEMU exits if drive_add parsing fails Daniel P. Berrange
2010-06-26  7:04   ` Markus Armbruster
2010-06-07 14:42 ` [Qemu-devel] [PATCH 06/19] Convert drive options to use enumeration data type Daniel P. Berrange
2010-06-09 19:52   ` Luiz Capitulino
2010-06-26  7:07   ` Markus Armbruster
2010-06-07 14:42 ` [Qemu-devel] [PATCH 07/19] Convert netdev client types to use an enumeration Daniel P. Berrange
2010-06-07 15:09   ` Anthony Liguori
2010-06-07 15:13     ` Daniel P. Berrange
2010-06-07 14:42 ` [Qemu-devel] [PATCH 08/19] Convert RTC to use enumerations for configuration parameters Daniel P. Berrange
2010-06-09 19:54   ` Luiz Capitulino
2010-06-07 14:42 ` [Qemu-devel] [PATCH 09/19] Change 'query-version' to output broken down version string Daniel P. Berrange
2010-06-07 15:11   ` Anthony Liguori
2010-06-09 20:04     ` Luiz Capitulino
2010-06-07 14:42 ` [Qemu-devel] [PATCH 10/19] Add a query-machines command to QMP Daniel P. Berrange
2010-06-07 15:13   ` Anthony Liguori
2010-06-07 16:44     ` Daniel P. Berrange
2010-06-07 17:07       ` Anthony Liguori
2010-06-07 17:14         ` Daniel P. Berrange
2010-06-09 20:06         ` Luiz Capitulino
2010-06-07 14:42 ` [Qemu-devel] [PATCH 11/19] Add a query-devices " Daniel P. Berrange
2010-06-07 15:14   ` Anthony Liguori
2010-06-07 16:03     ` Daniel P. Berrange
2010-06-26  7:12       ` Markus Armbruster
2010-06-07 14:42 ` [Qemu-devel] [PATCH 12/19] Add a query-cputypes " Daniel P. Berrange
2010-06-26  7:18   ` Markus Armbruster
2010-06-07 14:42 ` [Qemu-devel] [PATCH 13/19] Add a query-target " Daniel P. Berrange
2010-06-07 15:43   ` [Qemu-devel] " Paolo Bonzini
2010-06-07 14:42 ` [Qemu-devel] [PATCH 14/19] Add a query-argv " Daniel P. Berrange
2010-06-07 15:01   ` Anthony Liguori
2010-06-10 15:34     ` [Qemu-devel] " Paolo Bonzini
2010-06-26  7:30     ` [Qemu-devel] " Markus Armbruster
2010-06-07 14:42 ` [Qemu-devel] [PATCH 15/19] Expand query-argv to include help string Daniel P. Berrange
2010-06-07 14:42 ` [Qemu-devel] [PATCH 16/19] Add a query-netdev command to QMP Daniel P. Berrange
2010-06-07 15:15   ` Anthony Liguori
2010-06-26  7:32     ` Markus Armbruster
2010-06-07 19:13   ` Miguel Di Ciurcio Filho
2010-06-08  8:38     ` Daniel P. Berrange
2010-06-07 14:42 ` [Qemu-devel] [PATCH 17/19] Add a query-config " Daniel P. Berrange
2010-06-26  7:34   ` Markus Armbruster
2010-06-07 14:42 ` [Qemu-devel] [PATCH 18/19] Add option to turn on JSON pretty printing in monitor Daniel P. Berrange
2010-06-07 14:42 ` [Qemu-devel] [PATCH 19/19] Add a -capabilities argument to allow easy query for static QEMU info Daniel P. Berrange
2010-06-07 16:04   ` [Qemu-devel] " Paolo Bonzini
2010-06-07 16:09     ` Daniel P. Berrange
2010-06-07 16:04   ` [Qemu-devel] " Anthony Liguori
2010-06-07 14:58 ` [Qemu-devel] [PATCH 00/19] RFC: Reporting QEMU binary capabilities Anthony Liguori
2010-06-07 15:10   ` Daniel P. Berrange
2010-06-07 15:18     ` Anthony Liguori
2010-06-07 16:02   ` [Qemu-devel] " Paolo Bonzini
2010-06-07 16:03     ` Anthony Liguori
2010-06-07 16:07 ` [Qemu-devel] " Anthony Liguori
2010-06-09 20:25   ` Luiz Capitulino
2010-06-26  6:45 ` Markus Armbruster

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.