Re: [Qemu-devel] [PATCH for-1.4 v2 4/6] qemu-option: Disable two helpful messages that got broken recently

2013-02-19 Thread Markus Armbruster
Laszlo Ersek ler...@redhat.com writes:

 On 02/15/13 01:20, Laszlo Ersek wrote:
 On 02/14/13 17:36, Luiz Capitulino wrote:
 On Thu, 14 Feb 2013 14:31:50 +0100
 Markus Armbruster arm...@redhat.com wrote:

 chardev-add: the schema defines an object type for each backend
 (ChardevFile, ChardevSocket, ...), and collects them together in
 discriminated union ChardevBackend.  chardev_add takes that union.
 Thus, the schema accurately describes chardev-add's arguments, and the
 generated marshaller takes care of parsing chardev-add arguments into
 the appropriate objects.

 Yes, it's a nice solution. I don't know why we didn't have that idea
 when discussing netdev_add. Maybe we were biased by the old
 implementation.

 netdev_add: the schema defines an object type for each backend
 (NetdevNoneOptions, NetdevUserOptions, ...).  netdev_add doesn't use
 them, but takes arbitrary parameters instead.  The connection is made in
 code, which stuffs the parameters in a QemuOpts (losing all JSON type
 information), then takes them out again to stuff them into the
 appropriate object type.  A job the marshaller should be able to do for
 us.

 For me, the way chardev-add works makes a whole lot more sense, and I
 think we should clean up netdev_add to work the same way.

 So, regarding netdev_add again,

 --[schema dict]-- qmp_netdev_add()  ---\
 --[QemuOpts]--net_client_init() == opts-visitor ---\
 --[C struct]--specific logic

 (a) I agree that the intermediary QemuOpts representation is
 superfluous, and that we could directly expose the schema over QMP, ie.
 go from schema dict right to C struct. However,

 (b) opts-visitor's primary responsibility remains mangling one QemuOpts
 instance into a C struct. This effectively hamstrings any affected
 schema. You *can* choose to expose/reuse that schema over the wire, but
 you won't have any freedom massaging the schema later on just for the
 QMP caller's sake.

 --[schema dict]-- qmp_netdev_add() --[C struct]-- specific logic
 --[QemuOpts]--opts-visitor --[C struct]-- specific logic

 Obviously, you want to share the [C struct] and the specific logic
 between the two cases. However the C struct (the schema) is hamstrung by
 QemuOpts, thus ultimately the QMP wire format is dictated by the
 QemuOpts format that you accept on the command line.

 At first sight this might come through as a semantic match (same stuff
 available on the command line as over QMP), but:
 - you can't compose the underlying schema just any way you like,
 - what you can't express as a single QemuOpts object (think dictionaries
 in dictionaries), you can't allow over QMP.

Correct in general, but need not be an issue in a specific case.

When it is, I'd suggest to try something like:

* Create a schema appropriate for QMP.  This results in a C data
  structure (generated) and code accepting it.  Let's call the latter
  the interface.

* Create a schema for an opts-visitor, use it to take apart the option
  string.  This results in another C data structure.

* Write glue code to convert the opts-visitor result into the data
  structure accepted by the interface.

Alternatively, if QemuOpts are sufficiently simple, take them apart the
old-fashioned way, without visitors, then call a suitable interface
shared with the QMP case.  Calling the QMP handler requires building a
QDict, so you might be better off aiming lower.  The obvious option is
filling in the QMP schema's C data structure so you can call the
interface.

 With chardev_add, IIUC, first you create a logical schema, and expose it
 over QMP (all dandy), then hand-craft qemu_opt_get_() code, with
 properties encoded as C string literals, in order to shoehorn the
 logical schema into the command line (QemuOpts). I couldn't call this
 approach bad with a straight face (it clearly works in practice!), but
 as I perceived it, opts-visitor had been invented precisely to eliminate
 this.

If I understand you correctly, this is exactly what I just described
under alternatively, if QemuOpts are sufficiently simple.  Except the
options are not really simple.  So maybe we'd be better off doing it the
other way.

 Sorry for ranting...

You call this a rant?  ;)



Re: [Qemu-devel] [PATCH for-1.4 v2 4/6] qemu-option: Disable two helpful messages that got broken recently

2013-02-19 Thread Markus Armbruster
Laszlo Ersek ler...@redhat.com writes:

 Hi,

 sorry for the late answer. I can only address the netdev_add /
 opts-visitor stuff now.

 On 02/14/13 17:36, Luiz Capitulino wrote:
 On Thu, 14 Feb 2013 14:31:50 +0100
 Markus Armbruster arm...@redhat.com wrote:
 Luiz Capitulino lcapitul...@redhat.com writes:
 On Thu, 14 Feb 2013 10:45:22 +0100
 Markus Armbruster arm...@redhat.com wrote:

 netdev_add() uses QAPI wizardry to create the appropriate object from
 the QemuOpts.  The parsing is done by visitors.  Things get foggy for me
 from there on, but it looks like one of them, opts_type_size(), can
 parse size suffixes, which is inappropriate for QMP.  A quick test
 confirms that this is indeed possible:

 {execute: netdev_add,arguments: {type:tap,id:net.1,
 sndbuf: 8k }}

 Sets NetdevTapOptions member sndbuf to 8192.

 Well, I've just tested this with commit 783e9b4, which is before
 netdev_add conversion to the qapi, and the command above just works.

 Didn't check if sndbuf is actually set to 8192, but this shows that
 we've always accepted such a command.

 Plausible.  Nevertheless, we really shouldn't.
 
 Agreed. I would be willing to break compatibility to fix the suffix
 part of the problem, but there's another issue: sndbuf shouldn't be
 a string in QMP, and that's unfixable.

 The main purpose / requirement / guideline of the netdev_add 
 opts-visitor conversion was that the exact same command lines had to
 keep working. The primary source of input was the command line, ie.
 QemuOpts. The qapi-schema was absolutely bastardized for the task, with
 the single goal that the QemuOpts stuff *already gotten from the user*
 would be auto-parsed into C structs -- structs that were generated from
 the json. So, no QMP callers had been in anyone's mind as a priority;
 the qapi/visitor etc. scaffolding was retrofitted to QemuOpts.

 Please read the message on the main commit of the series:

   http://git.qemu.org/?p=qemu.git;a=commitdiff;h=eb7ee2cb

 plus here's the blurb:

   http://lists.nongnu.org/archive/html/qemu-devel/2012-07/msg02102.html

I understand, and it makes sense.  The trouble is it has since bled into
QMP.  I'd like us to clean that up.

 Netdev could be done without this key=value business in the schema.  We
 have just a few backends, and they're well-known, so we could just
 collect them all in a union, like Gerd did for chardev backends.

 The -netdev option centers on [type=]discriminator, and it had to work
 as transparently as possible. I can't recall all the details any longer
 (luckily!), but I remember sweating bullets wrapping the visitor API
 around QemuOpts.

 I honestly don't know if this is a good idea, but should be possible
 to change it if you're willing to.

 chardev-add: the schema defines an object type for each backend
 (ChardevFile, ChardevSocket, ...), and collects them together in
 discriminated union ChardevBackend.  chardev_add takes that union.
 Thus, the schema accurately describes chardev-add's arguments, and the
 generated marshaller takes care of parsing chardev-add arguments into
 the appropriate objects.
 
 Yes, it's a nice solution. I don't know why we didn't have that idea
 when discussing netdev_add. Maybe we were biased by the old
 implementation.
 
 netdev_add: the schema defines an object type for each backend
 (NetdevNoneOptions, NetdevUserOptions, ...).  netdev_add doesn't use
 them, but takes arbitrary parameters instead.  The connection is made in
 code, which stuffs the parameters in a QemuOpts (losing all JSON type
 information), then takes them out again to stuff them into the
 appropriate object type.  A job the marshaller should be able to do for
 us.

 For me, the way chardev-add works makes a whole lot more sense, and I
 think we should clean up netdev_add to work the same way.
 Unfortunately, I can't commit to this cleanup job right now.
 
 Agreed, and I think we won't break compatibility by doing this
 improvement.

 The most important things to compare are qemu_chr_new_from_opts() and
 net_client_init(), if my reading is correct. Each is the corresponding
 iteration callback for the list of chardev/netdev list of QemuOpts.

 (a) qemu_chr_new_from_opts() dives in, fishes out the discriminator
 manually -- backend is encoded as a C string literal, and there's a
 similar access to mux --, and looks up the appropriate open function
 based on backend (with linear search  strcmp()).

 No matter which open function we choose, each one is chock-full of
 qemu_opt_get_() calls with property names hard-coded as C string
 literals. *Killing this* was the exact purpose of opts-visitor. Cf.:

 (b) net_client_init() parses the QemuOpts object into a C struct, based
 on the schema, validating basic syntax simultaneously. Then
 net_client_init1(), rather than a linear, string-based search, uses the
 enum value (kind) as the controlling expression of a switch statement,
 and as immediate offset into the array of function pointers.

 None of those 

Re: [Qemu-devel] [PATCH for-1.4 v2 4/6] qemu-option: Disable two helpful messages that got broken recently

2013-02-19 Thread Laszlo Ersek
On 02/19/13 10:50, Markus Armbruster wrote:

 I suspect the real failure is in patch review.
 
 We can't expect everyone to know every feature, such as repeating
 options.  But we need to catch wheel reinventions in review.

I'd like to agree, but I'm simply unable to review more. On a good day,
if I spend it entirely on review, I can do ~10 patches tops. qemu-devel
gets approx. 200 messages per day (that's my impression anyway).

Laszlo



Re: [Qemu-devel] [PATCH for-1.4 v2 4/6] qemu-option: Disable two helpful messages that got broken recently

2013-02-19 Thread Laszlo Ersek
On 02/19/13 10:29, Markus Armbruster wrote:

 When it is, I'd suggest to try something like:
 
 * Create a schema appropriate for QMP.  This results in a C data
   structure (generated) and code accepting it.  Let's call the latter
   the interface.
 
 * Create a schema for an opts-visitor, use it to take apart the option
   string.  This results in another C data structure.
 
 * Write glue code to convert the opts-visitor result into the data
   structure accepted by the interface.

This is good, I like it.

Thanks,
Laszlo



Re: [Qemu-devel] [PATCH for-1.4 v2 4/6] qemu-option: Disable two helpful messages that got broken recently

2013-02-19 Thread Markus Armbruster
Laszlo Ersek ler...@redhat.com writes:

 On 02/19/13 10:50, Markus Armbruster wrote:

 I suspect the real failure is in patch review.
 
 We can't expect everyone to know every feature, such as repeating
 options.  But we need to catch wheel reinventions in review.

 I'd like to agree, but I'm simply unable to review more. On a good day,
 if I spend it entirely on review, I can do ~10 patches tops. qemu-devel
 gets approx. 200 messages per day (that's my impression anyway).

Note we need to catch, not you should've caught.

If everybody took his review duty as seriously as you do, we'd be in
better shape.



Re: [Qemu-devel] [PATCH for-1.4 v2 4/6] qemu-option: Disable two helpful messages that got broken recently

2013-02-14 Thread Markus Armbruster
[Note cc: +Laszlo, +Anthony, -qemu-trivial]

Luiz Capitulino lcapitul...@redhat.com writes:

 On Fri, 08 Feb 2013 20:34:20 +0100
 Markus Armbruster arm...@redhat.com wrote:

  The real problem here is that the k, M, G suffixes, for example, are not
  good to be reported by QMP. So maybe we should refactor the code in a way
  that we separate what's done in QMP from what is done in HMP/command-line.
 
 Isn't it separated already?  parse_option_size() is used when parsing
 key=value,...  Such strings should not exist in QMP.  If they do, it's a
 design bug.

 No and no. Such strings don't exist in QMP as far as can tell (see bugs
 below though), but parse_option_size() is theoretically present in a
 possible QMP call stack:

 qemu_opts_from_dict_1()
   qemu_opt_set_err()
 opt_set()
   qemu_opt_paser()
 parse_option_size()

 I can't tell if this will ever happen because qemu_opts_from_dict_1()
 restricts the call to qemu_opt_set_err() to certain values, but the
 fact that it's not clear is an indication that a better separation is
 necessary.

Permit me two detours.

One, qemu_opt_set_err() is a confusing name.  I doesn't set an error.
It attempts to set an option value, using the conventional Error **
parameter for error reporting.  Its buddy qemu_opt_set() does the same,
except it reports errors to the user and returns only success/failure.

Two, qemu_opts_from_qdict() should be taken out and shot (I may say
that, because I created it).  I created it because I had to go from
QDicts I get from QMP to internal APIs that want QemuOpts, specifically
qdev_device_add().

qdev_device_add() takes QemuOpts because that's the only tool we had at
the time for passing dictionaries around.  Made enough sense then:
command line gives us QemuOpts already, so why not just pass them on.

Still made sense for the human monitor command: give it an argument just
like -device's option argument, parse it the same way, done.

It became awkward with QMP.  Perhaps I should've switched
qdev_device_add() to QDict then, so the QMP command handler can use it
directly.  Instead, I simply converted from QDict to QemuOpts.

Now, to build hmp_device_add() on top of qmp_device_add(), we'd have to
convert first from QemuOpts to QDict and then back to QemuOpts.  Blech.
Instead, we made do_device_add() go straight to qdev_device_add().  Same
for hmp_netdev_add(): it goes straight to netdev_add().

QemuOpts is a bad fit for general interfaces, because it's really
designed for accumulating command line options for later use.  Features
useful there get in the way, e.g. how QemuOptsList serves both as schema
and as the single list of QemuOpts.  Features not needed there are
missing, e.g. signed and floating-point numbers.

End of detours, back to your questions.

I guess weird things can happen with qemu_opts_from_qdict(), at least in
theory.

For each (key, value) in the QDict, qemu_opts_from_qdict() converts
value to string according to its qtype_code.  The string then gets
parsed according to key's QemuOptType.  Yes, that means you can pass a
QString to QEMU_OPT_SIZE option, and get the suffixes interpreted.

However, we've only used qemu_opts_from_qdict() with QemuOptsLists that
have empty desc[]!  Specifically: qemu_netdev_opts and qemu_device_opts.
Without desc, qemu_opt_parse() does nothing, and QemuOpts holds just
string values.  Actual parsing left to the consumer.

Two consumers: qdev_device_add() and netdev_add().

netdev_add() uses QAPI wizardry to create the appropriate object from
the QemuOpts.  The parsing is done by visitors.  Things get foggy for me
from there on, but it looks like one of them, opts_type_size(), can
parse size suffixes, which is inappropriate for QMP.  A quick test
confirms that this is indeed possible:

{execute: netdev_add,arguments: {type:tap,id:net.1,
sndbuf: 8k }}

Sets NetdevTapOptions member sndbuf to 8192.

To sum up, we go from QDict delivered by the JSON parser via QemuOpts to
QAPI object, with a few cock-ups along the way.  Ugh.

By the way, the JSON schema reads

{ 'command': 'netdev_add',
  'data': {'type': 'str', 'id': 'str', '*props': '**'},
  'gen': 'no' }

I'll be hanged if I know what '**' means.

qdev_device_add() uses a few well-known options itself, and they're all
strings.  The others it passes on to qdev_prop_parse().  This permits
some weirdness like passing PCI device's addr property as number in QMP,
even though it's nominally a string of the form SLOT[.FN].

No JSON schema, because device_add hasn't been qapified (Laszlo's
working on it now).

 Now, I think I've found at least two bugs. The first one is the
 netdev_add doc in the schema, which states that we do accept key=value
 strings. The problem is here is that that's about the C API, on the
 wire we act as before (ie. accepting each key as a separate argument).
 The qapi-schame.json is more or less format-independent, so I'm not
 exactly sure what's the best way to describe commands using 

Re: [Qemu-devel] [PATCH for-1.4 v2 4/6] qemu-option: Disable two helpful messages that got broken recently

2013-02-14 Thread Luiz Capitulino
On Thu, 14 Feb 2013 10:45:22 +0100
Markus Armbruster arm...@redhat.com wrote:

 [Note cc: +Laszlo, +Anthony, -qemu-trivial]
 
 Luiz Capitulino lcapitul...@redhat.com writes:
 
  On Fri, 08 Feb 2013 20:34:20 +0100
  Markus Armbruster arm...@redhat.com wrote:
 
   The real problem here is that the k, M, G suffixes, for example, are not
   good to be reported by QMP. So maybe we should refactor the code in a way
   that we separate what's done in QMP from what is done in 
   HMP/command-line.
  
  Isn't it separated already?  parse_option_size() is used when parsing
  key=value,...  Such strings should not exist in QMP.  If they do, it's a
  design bug.
 
  No and no. Such strings don't exist in QMP as far as can tell (see bugs
  below though), but parse_option_size() is theoretically present in a
  possible QMP call stack:
 
  qemu_opts_from_dict_1()
qemu_opt_set_err()
  opt_set()
qemu_opt_paser()
  parse_option_size()
 
  I can't tell if this will ever happen because qemu_opts_from_dict_1()
  restricts the call to qemu_opt_set_err() to certain values, but the
  fact that it's not clear is an indication that a better separation is
  necessary.
 
 Permit me two detours.
 
 One, qemu_opt_set_err() is a confusing name.  I doesn't set an error.

It takes an Error ** object and it was introduced to avoid having
to convert qemu_opt_set() to take an Error ** object, as this would
multiply the work required to get netdev_add converted to the qapi.

Now, I pass the bikeshed :)

 Now, to build hmp_device_add() on top of qmp_device_add(), we'd have to
 convert first from QemuOpts to QDict and then back to QemuOpts.  Blech.
 Instead, we made do_device_add() go straight to qdev_device_add().  Same
 for hmp_netdev_add(): it goes straight to netdev_add().

Yes, the idea was to have netdev_add() and add frontends to hmp
and qmp. More on this below.

 netdev_add() uses QAPI wizardry to create the appropriate object from
 the QemuOpts.  The parsing is done by visitors.  Things get foggy for me
 from there on, but it looks like one of them, opts_type_size(), can
 parse size suffixes, which is inappropriate for QMP.  A quick test
 confirms that this is indeed possible:
 
 {execute: netdev_add,arguments: {type:tap,id:net.1,
 sndbuf: 8k }}
 
 Sets NetdevTapOptions member sndbuf to 8192.

Well, I've just tested this with commit 783e9b4, which is before
netdev_add conversion to the qapi, and the command above just works.

Didn't check if sndbuf is actually set to 8192, but this shows that
we've always accepted such a command.

 To sum up, we go from QDict delivered by the JSON parser via QemuOpts to
 QAPI object, with a few cock-ups along the way.  Ugh.
 
 By the way, the JSON schema reads
 
 { 'command': 'netdev_add',
   'data': {'type': 'str', 'id': 'str', '*props': '**'},
   'gen': 'no' }
 
 I'll be hanged if I know what '**' means.

For QMP on the wire it means that the command accepts a bunch of
arguments not specified in the schema.

Yes, it's a dirty trick. Long story short: we decide to maintain
QemuOpts usage in both HMP and QMP to speed up netdev_add conversion.

 qdev_device_add() uses a few well-known options itself, and they're all
 strings.  The others it passes on to qdev_prop_parse().  This permits
 some weirdness like passing PCI device's addr property as number in QMP,
 even though it's nominally a string of the form SLOT[.FN].
 
 No JSON schema, because device_add hasn't been qapified (Laszlo's
 working on it now).
 
  Now, I think I've found at least two bugs. The first one is the
  netdev_add doc in the schema, which states that we do accept key=value
  strings. The problem is here is that that's about the C API, on the
  wire we act as before (ie. accepting each key as a separate argument).
  The qapi-schame.json is more or less format-independent, so I'm not
  exactly sure what's the best way to describe commands using QemuOpts
  the way QMP uses it.
 
 Netdev could be done without this key=value business in the schema.  We
 have just a few backends, and they're well-known, so we could just
 collect them all in a union, like Gerd did for chardev backends.

I honestly don't know if this is a good idea, but should be possible
to change it if you're willing to.

 Devices are hairier.  For a union approach, we'd have to include a
 schema for every device model.  Dunno.

IMHO, right now going fast is more important than doing things
with perfection (unless you can do perfection in no time, of course),
because the qapi conversions already took a lot more than expected
and it's delaying very good stuff (like the new qmp server, and dropping
the *.hx files and old QMP code).

So, I wouldn't bother doing old crap commands perfect. Specially when
replacements are on the way.

  The second bug is that I entirely ignored how set_option_paramater()
  handles errors when doing parse_option_size() conversion to Error **
  and also when converting bdrv_img_create(). The end result 

Re: [Qemu-devel] [PATCH for-1.4 v2 4/6] qemu-option: Disable two helpful messages that got broken recently

2013-02-14 Thread Markus Armbruster
[Some quoted material restored]

Luiz Capitulino lcapitul...@redhat.com writes:

 On Thu, 14 Feb 2013 10:45:22 +0100
 Markus Armbruster arm...@redhat.com wrote:

 [Note cc: +Laszlo, +Anthony, -qemu-trivial]
 
 Luiz Capitulino lcapitul...@redhat.com writes:
 
  On Fri, 08 Feb 2013 20:34:20 +0100
  Markus Armbruster arm...@redhat.com wrote:
 
   The real problem here is that the k, M, G suffixes, for example, are not
   good to be reported by QMP. So maybe we should refactor the code in a 
   way
   that we separate what's done in QMP from what is done in
   HMP/command-line.
  
  Isn't it separated already?  parse_option_size() is used when parsing
  key=value,...  Such strings should not exist in QMP.  If they do, it's a
  design bug.
 
  No and no. Such strings don't exist in QMP as far as can tell (see bugs
  below though), but parse_option_size() is theoretically present in a
  possible QMP call stack:
 
  qemu_opts_from_dict_1()
qemu_opt_set_err()
  opt_set()
qemu_opt_paser()
  parse_option_size()
 
  I can't tell if this will ever happen because qemu_opts_from_dict_1()
  restricts the call to qemu_opt_set_err() to certain values, but the
  fact that it's not clear is an indication that a better separation is
  necessary.
 
 Permit me two detours.
 
 One, qemu_opt_set_err() is a confusing name.  I doesn't set an error.

 It takes an Error ** object and it was introduced to avoid having
 to convert qemu_opt_set() to take an Error ** object, as this would
 multiply the work required to get netdev_add converted to the qapi.

 Now, I pass the bikeshed :)

I get why it's there, I just find its name confusing.

 [...]
 Now, to build hmp_device_add() on top of qmp_device_add(), we'd have to
 convert first from QemuOpts to QDict and then back to QemuOpts.  Blech.
 Instead, we made do_device_add() go straight to qdev_device_add().  Same
 for hmp_netdev_add(): it goes straight to netdev_add().

 Yes, the idea was to have netdev_add() and add frontends to hmp
 and qmp. More on this below.

 [...]
 I guess weird things can happen with qemu_opts_from_qdict(), at least in
 theory.
 
 For each (key, value) in the QDict, qemu_opts_from_qdict() converts
 value to string according to its qtype_code.  The string then gets
 parsed according to key's QemuOptType.  Yes, that means you can pass a
 QString to QEMU_OPT_SIZE option, and get the suffixes interpreted.
 
 However, we've only used qemu_opts_from_qdict() with QemuOptsLists that
 have empty desc[]!  Specifically: qemu_netdev_opts and qemu_device_opts.
 Without desc, qemu_opt_parse() does nothing, and QemuOpts holds just
 string values.  Actual parsing left to the consumer.
 
 Two consumers: qdev_device_add() and netdev_add().
 
 netdev_add() uses QAPI wizardry to create the appropriate object from
 the QemuOpts.  The parsing is done by visitors.  Things get foggy for me
 from there on, but it looks like one of them, opts_type_size(), can
 parse size suffixes, which is inappropriate for QMP.  A quick test
 confirms that this is indeed possible:
 
 {execute: netdev_add,arguments: {type:tap,id:net.1,
 sndbuf: 8k }}
 
 Sets NetdevTapOptions member sndbuf to 8192.

 Well, I've just tested this with commit 783e9b4, which is before
 netdev_add conversion to the qapi, and the command above just works.

 Didn't check if sndbuf is actually set to 8192, but this shows that
 we've always accepted such a command.

Plausible.  Nevertheless, we really shouldn't.

 To sum up, we go from QDict delivered by the JSON parser via QemuOpts to
 QAPI object, with a few cock-ups along the way.  Ugh.
 
 By the way, the JSON schema reads
 
 { 'command': 'netdev_add',
   'data': {'type': 'str', 'id': 'str', '*props': '**'},
   'gen': 'no' }
 
 I'll be hanged if I know what '**' means.

 For QMP on the wire it means that the command accepts a bunch of
 arguments not specified in the schema.

Thanks!  Is the schema language documented anywhere?

 Yes, it's a dirty trick. Long story short: we decide to maintain
 QemuOpts usage in both HMP and QMP to speed up netdev_add conversion.

I don't think '**' is as dirty as you make it sound.  It's simply a way
to relax the rigidity of the schema.  I got no problem with that.

 qdev_device_add() uses a few well-known options itself, and they're all
 strings.  The others it passes on to qdev_prop_parse().  This permits
 some weirdness like passing PCI device's addr property as number in QMP,
 even though it's nominally a string of the form SLOT[.FN].
 
 No JSON schema, because device_add hasn't been qapified (Laszlo's
 working on it now).
 
  Now, I think I've found at least two bugs. The first one is the
  netdev_add doc in the schema, which states that we do accept key=value
  strings. The problem is here is that that's about the C API, on the
  wire we act as before (ie. accepting each key as a separate argument).
  The qapi-schame.json is more or less format-independent, so I'm not
  exactly sure what's the 

Re: [Qemu-devel] [PATCH for-1.4 v2 4/6] qemu-option: Disable two helpful messages that got broken recently

2013-02-14 Thread Luiz Capitulino
On Thu, 14 Feb 2013 14:31:50 +0100
Markus Armbruster arm...@redhat.com wrote:

 [Some quoted material restored]
 
 Luiz Capitulino lcapitul...@redhat.com writes:
 
  On Thu, 14 Feb 2013 10:45:22 +0100
  Markus Armbruster arm...@redhat.com wrote:
 
  [Note cc: +Laszlo, +Anthony, -qemu-trivial]
  
  Luiz Capitulino lcapitul...@redhat.com writes:
  
   On Fri, 08 Feb 2013 20:34:20 +0100
   Markus Armbruster arm...@redhat.com wrote:
  
The real problem here is that the k, M, G suffixes, for example, are 
not
good to be reported by QMP. So maybe we should refactor the code in a 
way
that we separate what's done in QMP from what is done in
HMP/command-line.
   
   Isn't it separated already?  parse_option_size() is used when parsing
   key=value,...  Such strings should not exist in QMP.  If they do, it's a
   design bug.
  
   No and no. Such strings don't exist in QMP as far as can tell (see bugs
   below though), but parse_option_size() is theoretically present in a
   possible QMP call stack:
  
   qemu_opts_from_dict_1()
 qemu_opt_set_err()
   opt_set()
 qemu_opt_paser()
   parse_option_size()
  
   I can't tell if this will ever happen because qemu_opts_from_dict_1()
   restricts the call to qemu_opt_set_err() to certain values, but the
   fact that it's not clear is an indication that a better separation is
   necessary.
  
  Permit me two detours.
  
  One, qemu_opt_set_err() is a confusing name.  I doesn't set an error.
 
  It takes an Error ** object and it was introduced to avoid having
  to convert qemu_opt_set() to take an Error ** object, as this would
  multiply the work required to get netdev_add converted to the qapi.
 
  Now, I pass the bikeshed :)
 
 I get why it's there, I just find its name confusing.
 
  [...]
  Now, to build hmp_device_add() on top of qmp_device_add(), we'd have to
  convert first from QemuOpts to QDict and then back to QemuOpts.  Blech.
  Instead, we made do_device_add() go straight to qdev_device_add().  Same
  for hmp_netdev_add(): it goes straight to netdev_add().
 
  Yes, the idea was to have netdev_add() and add frontends to hmp
  and qmp. More on this below.
 
  [...]
  I guess weird things can happen with qemu_opts_from_qdict(), at least in
  theory.
  
  For each (key, value) in the QDict, qemu_opts_from_qdict() converts
  value to string according to its qtype_code.  The string then gets
  parsed according to key's QemuOptType.  Yes, that means you can pass a
  QString to QEMU_OPT_SIZE option, and get the suffixes interpreted.
  
  However, we've only used qemu_opts_from_qdict() with QemuOptsLists that
  have empty desc[]!  Specifically: qemu_netdev_opts and qemu_device_opts.
  Without desc, qemu_opt_parse() does nothing, and QemuOpts holds just
  string values.  Actual parsing left to the consumer.
  
  Two consumers: qdev_device_add() and netdev_add().
  
  netdev_add() uses QAPI wizardry to create the appropriate object from
  the QemuOpts.  The parsing is done by visitors.  Things get foggy for me
  from there on, but it looks like one of them, opts_type_size(), can
  parse size suffixes, which is inappropriate for QMP.  A quick test
  confirms that this is indeed possible:
  
  {execute: netdev_add,arguments: {type:tap,id:net.1,
  sndbuf: 8k }}
  
  Sets NetdevTapOptions member sndbuf to 8192.
 
  Well, I've just tested this with commit 783e9b4, which is before
  netdev_add conversion to the qapi, and the command above just works.
 
  Didn't check if sndbuf is actually set to 8192, but this shows that
  we've always accepted such a command.
 
 Plausible.  Nevertheless, we really shouldn't.

Agreed. I would be willing to break compatibility to fix the suffix
part of the problem, but there's another issue: sndbuf shouldn't be
a string in QMP, and that's unfixable.

  To sum up, we go from QDict delivered by the JSON parser via QemuOpts to
  QAPI object, with a few cock-ups along the way.  Ugh.
  
  By the way, the JSON schema reads
  
  { 'command': 'netdev_add',
'data': {'type': 'str', 'id': 'str', '*props': '**'},
'gen': 'no' }
  
  I'll be hanged if I know what '**' means.
 
  For QMP on the wire it means that the command accepts a bunch of
  arguments not specified in the schema.
 
 Thanks!  Is the schema language documented anywhere?

Unfortunately not.

  Yes, it's a dirty trick. Long story short: we decide to maintain
  QemuOpts usage in both HMP and QMP to speed up netdev_add conversion.
 
 I don't think '**' is as dirty as you make it sound.  It's simply a way
 to relax the rigidity of the schema.  I got no problem with that.

Problem is, I don't know how to make it better if we want to. I think
we could use it for the old commands that depend on QemuOpts so that
we don't make conversions too hard, but we shouldn't use it for new
commands.

  qdev_device_add() uses a few well-known options itself, and they're all
  strings.  The others it passes on to qdev_prop_parse().  This 

Re: [Qemu-devel] [PATCH for-1.4 v2 4/6] qemu-option: Disable two helpful messages that got broken recently

2013-02-14 Thread Laszlo Ersek
Hi,

sorry for the late answer. I can only address the netdev_add /
opts-visitor stuff now.

On 02/14/13 17:36, Luiz Capitulino wrote:
 On Thu, 14 Feb 2013 14:31:50 +0100
 Markus Armbruster arm...@redhat.com wrote:
 Luiz Capitulino lcapitul...@redhat.com writes:
 On Thu, 14 Feb 2013 10:45:22 +0100
 Markus Armbruster arm...@redhat.com wrote:

 netdev_add() uses QAPI wizardry to create the appropriate object from
 the QemuOpts.  The parsing is done by visitors.  Things get foggy for me
 from there on, but it looks like one of them, opts_type_size(), can
 parse size suffixes, which is inappropriate for QMP.  A quick test
 confirms that this is indeed possible:

 {execute: netdev_add,arguments: {type:tap,id:net.1,
 sndbuf: 8k }}

 Sets NetdevTapOptions member sndbuf to 8192.

 Well, I've just tested this with commit 783e9b4, which is before
 netdev_add conversion to the qapi, and the command above just works.

 Didn't check if sndbuf is actually set to 8192, but this shows that
 we've always accepted such a command.

 Plausible.  Nevertheless, we really shouldn't.
 
 Agreed. I would be willing to break compatibility to fix the suffix
 part of the problem, but there's another issue: sndbuf shouldn't be
 a string in QMP, and that's unfixable.

The main purpose / requirement / guideline of the netdev_add 
opts-visitor conversion was that the exact same command lines had to
keep working. The primary source of input was the command line, ie.
QemuOpts. The qapi-schema was absolutely bastardized for the task, with
the single goal that the QemuOpts stuff *already gotten from the user*
would be auto-parsed into C structs -- structs that were generated from
the json. So, no QMP callers had been in anyone's mind as a priority;
the qapi/visitor etc. scaffolding was retrofitted to QemuOpts.

Please read the message on the main commit of the series:

  http://git.qemu.org/?p=qemu.git;a=commitdiff;h=eb7ee2cb

plus here's the blurb:

  http://lists.nongnu.org/archive/html/qemu-devel/2012-07/msg02102.html


 Netdev could be done without this key=value business in the schema.  We
 have just a few backends, and they're well-known, so we could just
 collect them all in a union, like Gerd did for chardev backends.

The -netdev option centers on [type=]discriminator, and it had to work
as transparently as possible. I can't recall all the details any longer
(luckily!), but I remember sweating bullets wrapping the visitor API
around QemuOpts.

 I honestly don't know if this is a good idea, but should be possible
 to change it if you're willing to.

 chardev-add: the schema defines an object type for each backend
 (ChardevFile, ChardevSocket, ...), and collects them together in
 discriminated union ChardevBackend.  chardev_add takes that union.
 Thus, the schema accurately describes chardev-add's arguments, and the
 generated marshaller takes care of parsing chardev-add arguments into
 the appropriate objects.
 
 Yes, it's a nice solution. I don't know why we didn't have that idea
 when discussing netdev_add. Maybe we were biased by the old
 implementation.
 
 netdev_add: the schema defines an object type for each backend
 (NetdevNoneOptions, NetdevUserOptions, ...).  netdev_add doesn't use
 them, but takes arbitrary parameters instead.  The connection is made in
 code, which stuffs the parameters in a QemuOpts (losing all JSON type
 information), then takes them out again to stuff them into the
 appropriate object type.  A job the marshaller should be able to do for
 us.

 For me, the way chardev-add works makes a whole lot more sense, and I
 think we should clean up netdev_add to work the same way.
 Unfortunately, I can't commit to this cleanup job right now.
 
 Agreed, and I think we won't break compatibility by doing this
 improvement.

The most important things to compare are qemu_chr_new_from_opts() and
net_client_init(), if my reading is correct. Each is the corresponding
iteration callback for the list of chardev/netdev list of QemuOpts.

(a) qemu_chr_new_from_opts() dives in, fishes out the discriminator
manually -- backend is encoded as a C string literal, and there's a
similar access to mux --, and looks up the appropriate open function
based on backend (with linear search  strcmp()).

No matter which open function we choose, each one is chock-full of
qemu_opt_get_() calls with property names hard-coded as C string
literals. *Killing this* was the exact purpose of opts-visitor. Cf.:

(b) net_client_init() parses the QemuOpts object into a C struct, based
on the schema, validating basic syntax simultaneously. Then
net_client_init1(), rather than a linear, string-based search, uses the
enum value (kind) as the controlling expression of a switch statement,
and as immediate offset into the array of function pointers.

None of those init functions makes one qemu_opt_get_() call with a
hard-coded property name; they all use *field names* and access the
pre-parsed structs.


Honestly I don't know wheter 

Re: [Qemu-devel] [PATCH for-1.4 v2 4/6] qemu-option: Disable two helpful messages that got broken recently

2013-02-14 Thread Laszlo Ersek
On 02/15/13 01:20, Laszlo Ersek wrote:
 On 02/14/13 17:36, Luiz Capitulino wrote:
 On Thu, 14 Feb 2013 14:31:50 +0100
 Markus Armbruster arm...@redhat.com wrote:

 chardev-add: the schema defines an object type for each backend
 (ChardevFile, ChardevSocket, ...), and collects them together in
 discriminated union ChardevBackend.  chardev_add takes that union.
 Thus, the schema accurately describes chardev-add's arguments, and the
 generated marshaller takes care of parsing chardev-add arguments into
 the appropriate objects.

 Yes, it's a nice solution. I don't know why we didn't have that idea
 when discussing netdev_add. Maybe we were biased by the old
 implementation.

 netdev_add: the schema defines an object type for each backend
 (NetdevNoneOptions, NetdevUserOptions, ...).  netdev_add doesn't use
 them, but takes arbitrary parameters instead.  The connection is made in
 code, which stuffs the parameters in a QemuOpts (losing all JSON type
 information), then takes them out again to stuff them into the
 appropriate object type.  A job the marshaller should be able to do for
 us.

 For me, the way chardev-add works makes a whole lot more sense, and I
 think we should clean up netdev_add to work the same way.

So, regarding netdev_add again,

--[schema dict]-- qmp_netdev_add()  ---\
--[QemuOpts]--net_client_init() == opts-visitor ---\
--[C struct]--specific logic

(a) I agree that the intermediary QemuOpts representation is
superfluous, and that we could directly expose the schema over QMP, ie.
go from schema dict right to C struct. However,

(b) opts-visitor's primary responsibility remains mangling one QemuOpts
instance into a C struct. This effectively hamstrings any affected
schema. You *can* choose to expose/reuse that schema over the wire, but
you won't have any freedom massaging the schema later on just for the
QMP caller's sake.

--[schema dict]-- qmp_netdev_add() --[C struct]-- specific logic
--[QemuOpts]--opts-visitor --[C struct]-- specific logic

Obviously, you want to share the [C struct] and the specific logic
between the two cases. However the C struct (the schema) is hamstrung by
QemuOpts, thus ultimately the QMP wire format is dictated by the
QemuOpts format that you accept on the command line.

At first sight this might come through as a semantic match (same stuff
available on the command line as over QMP), but:
- you can't compose the underlying schema just any way you like,
- what you can't express as a single QemuOpts object (think dictionaries
in dictionaries), you can't allow over QMP.

With chardev_add, IIUC, first you create a logical schema, and expose it
over QMP (all dandy), then hand-craft qemu_opt_get_() code, with
properties encoded as C string literals, in order to shoehorn the
logical schema into the command line (QemuOpts). I couldn't call this
approach bad with a straight face (it clearly works in practice!), but
as I perceived it, opts-visitor had been invented precisely to eliminate
this.

Sorry for ranting...

Laszlo



Re: [Qemu-devel] [PATCH for-1.4 v2 4/6] qemu-option: Disable two helpful messages that got broken recently

2013-02-13 Thread Luiz Capitulino
On Fri, 08 Feb 2013 20:34:20 +0100
Markus Armbruster arm...@redhat.com wrote:

  The real problem here is that the k, M, G suffixes, for example, are not
  good to be reported by QMP. So maybe we should refactor the code in a way
  that we separate what's done in QMP from what is done in HMP/command-line.
 
 Isn't it separated already?  parse_option_size() is used when parsing
 key=value,...  Such strings should not exist in QMP.  If they do, it's a
 design bug.

No and no. Such strings don't exist in QMP as far as can tell (see bugs
below though), but parse_option_size() is theoretically present in a
possible QMP call stack:

qemu_opts_from_dict_1()
  qemu_opt_set_err()
opt_set()
  qemu_opt_paser()
parse_option_size()

I can't tell if this will ever happen because qemu_opts_from_dict_1()
restricts the call to qemu_opt_set_err() to certain values, but the
fact that it's not clear is an indication that a better separation is
necessary.

Now, I think I've found at least two bugs. The first one is the
netdev_add doc in the schema, which states that we do accept key=value
strings. The problem is here is that that's about the C API, on the
wire we act as before (ie. accepting each key as a separate argument).
The qapi-schame.json is more or less format-independent, so I'm not
exactly sure what's the best way to describe commands using QemuOpts
the way QMP uses it.

The second bug is that I entirely ignored how set_option_paramater()
handles errors when doing parse_option_size() conversion to Error **
and also when converting bdrv_img_create(). The end result is that
we can report an error twice, once with error_set() and later with
qerror_report() (or vice-versa). Shouldn't hurt on QMP as it knows
how to deal with this, on HMP and command-line we get complementary
error messages if we're lucky.

I'm very surprised with my mistakes on the second bug (although some
of the mess with fprintf() was already there), but I honestly think we
should defer this to 1.5 (and I can do it myself next week).



[Qemu-devel] [PATCH for-1.4 v2 4/6] qemu-option: Disable two helpful messages that got broken recently

2013-02-08 Thread Markus Armbruster
commit 8be7e7e4 and commit ec7b2ccb messed up the ordering of error
message and the helpful explanation that should follow it, like this:

$ qemu-system-x86_64 --nodefaults -S --vnc :0 --chardev null,id=,
Identifiers consist of letters, digits, '-', '.', '_', starting with a 
letter.
qemu-system-x86_64: -chardev null,id=,: Parameter 'id' expects an identifier

$ qemu-system-x86_64 --nodefaults -S --vnc :0 --machine kvm_shadow_mem=dunno
You may use k, M, G or T suffixes for kilobytes, megabytes, gigabytes and 
terabytes.
qemu-system-x86_64: -machine kvm_shadow_mem=dunno: Parameter 
'kvm_shadow_mem' expects a size

Pity.  Disable them for now.

Signed-off-by: Markus Armbruster arm...@redhat.com
---
 util/qemu-option.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/util/qemu-option.c b/util/qemu-option.c
index c12e724..5a1d03c 100644
--- a/util/qemu-option.c
+++ b/util/qemu-option.c
@@ -231,8 +231,10 @@ static void parse_option_size(const char *name, const char 
*value,
 break;
 default:
 error_set(errp, QERR_INVALID_PARAMETER_VALUE, name, a size);
+#if 0 /* conversion from qerror_report() to error_set() broke this: */
 error_printf_unless_qmp(You may use k, M, G or T suffixes for 
 kilobytes, megabytes, gigabytes and terabytes.\n);
+#endif
 return;
 }
 } else {
@@ -771,7 +773,9 @@ QemuOpts *qemu_opts_create(QemuOptsList *list, const char 
*id,
 if (id) {
 if (!id_wellformed(id)) {
 error_set(errp,QERR_INVALID_PARAMETER_VALUE, id, an 
identifier);
+#if 0 /* conversion from qerror_report() to error_set() broke this: */
 error_printf_unless_qmp(Identifiers consist of letters, digits, 
'-', '.', '_', starting with a letter.\n);
+#endif
 return NULL;
 }
 opts = qemu_opts_find(list, id);
-- 
1.7.11.7




Re: [Qemu-devel] [PATCH for-1.4 v2 4/6] qemu-option: Disable two helpful messages that got broken recently

2013-02-08 Thread Luiz Capitulino
On Fri,  8 Feb 2013 17:17:10 +0100
Markus Armbruster arm...@redhat.com wrote:

 commit 8be7e7e4 and commit ec7b2ccb messed up the ordering of error
 message and the helpful explanation that should follow it, like this:
 
 $ qemu-system-x86_64 --nodefaults -S --vnc :0 --chardev null,id=,
 Identifiers consist of letters, digits, '-', '.', '_', starting with a 
 letter.
 qemu-system-x86_64: -chardev null,id=,: Parameter 'id' expects an 
 identifier
 
 $ qemu-system-x86_64 --nodefaults -S --vnc :0 --machine 
 kvm_shadow_mem=dunno
 You may use k, M, G or T suffixes for kilobytes, megabytes, gigabytes and 
 terabytes.
 qemu-system-x86_64: -machine kvm_shadow_mem=dunno: Parameter 
 'kvm_shadow_mem' expects a size
 
 Pity.  Disable them for now.

Oops, sorry. I think I'd prefer to drop them, but as this fixes the problem:

Reviewed-by: Luiz Capitulino lcapitul...@redhat.com

Also, the real problem here is that general functions like parse_option_size()
should never assume/try to guess in which context they're running. So, the
best solution here is either to have a general enough error message that's
not tied to any context, or let up layers (say vl.c) concatenate the
context-dependent part of the error message.

 
 Signed-off-by: Markus Armbruster arm...@redhat.com
 ---
  util/qemu-option.c | 4 
  1 file changed, 4 insertions(+)
 
 diff --git a/util/qemu-option.c b/util/qemu-option.c
 index c12e724..5a1d03c 100644
 --- a/util/qemu-option.c
 +++ b/util/qemu-option.c
 @@ -231,8 +231,10 @@ static void parse_option_size(const char *name, const 
 char *value,
  break;
  default:
  error_set(errp, QERR_INVALID_PARAMETER_VALUE, name, a size);
 +#if 0 /* conversion from qerror_report() to error_set() broke this: */
  error_printf_unless_qmp(You may use k, M, G or T suffixes for 
  kilobytes, megabytes, gigabytes and terabytes.\n);
 +#endif
  return;
  }
  } else {
 @@ -771,7 +773,9 @@ QemuOpts *qemu_opts_create(QemuOptsList *list, const char 
 *id,
  if (id) {
  if (!id_wellformed(id)) {
  error_set(errp,QERR_INVALID_PARAMETER_VALUE, id, an 
 identifier);
 +#if 0 /* conversion from qerror_report() to error_set() broke this: */
  error_printf_unless_qmp(Identifiers consist of letters, digits, 
 '-', '.', '_', starting with a letter.\n);
 +#endif
  return NULL;
  }
  opts = qemu_opts_find(list, id);




Re: [Qemu-devel] [PATCH for-1.4 v2 4/6] qemu-option: Disable two helpful messages that got broken recently

2013-02-08 Thread Luiz Capitulino
On Fri, 08 Feb 2013 19:58:42 +0100
Markus Armbruster arm...@redhat.com wrote:

 Luiz Capitulino lcapitul...@redhat.com writes:
 
  On Fri,  8 Feb 2013 17:17:10 +0100
  Markus Armbruster arm...@redhat.com wrote:
 
  commit 8be7e7e4 and commit ec7b2ccb messed up the ordering of error
  message and the helpful explanation that should follow it, like this:
  
  $ qemu-system-x86_64 --nodefaults -S --vnc :0 --chardev null,id=,
  Identifiers consist of letters, digits, '-', '.', '_', starting
  with a letter.
  qemu-system-x86_64: -chardev null,id=,: Parameter 'id' expects
  an identifier
  
  $ qemu-system-x86_64 --nodefaults -S --vnc :0 --machine
  kvm_shadow_mem=dunno
  You may use k, M, G or T suffixes for kilobytes, megabytes,
  gigabytes and terabytes.
  qemu-system-x86_64: -machine kvm_shadow_mem=dunno: Parameter
  kvm_shadow_mem' expects a size
  
  Pity.  Disable them for now.
 
  Oops, sorry. I think I'd prefer to drop them, but as this fixes the problem:
 
  Reviewed-by: Luiz Capitulino lcapitul...@redhat.com
 
  Also, the real problem here is that general functions like 
  parse_option_size()
  should never assume/try to guess in which context they're running. So, the
  best solution here is either to have a general enough error message that's
  not tied to any context, or let up layers (say vl.c) concatenate the
  context-dependent part of the error message.
 
 I'm open to suggestions on how to better code the pattern report an
 error (a short string without newlines) together with some explanation
 or hint (possibly longer string, newlines okay).

The real problem here is that the k, M, G suffixes, for example, are not
good to be reported by QMP. So maybe we should refactor the code in a way
that we separate what's done in QMP from what is done in HMP/command-line.



Re: [Qemu-devel] [PATCH for-1.4 v2 4/6] qemu-option: Disable two helpful messages that got broken recently

2013-02-08 Thread Markus Armbruster
Luiz Capitulino lcapitul...@redhat.com writes:

 On Fri,  8 Feb 2013 17:17:10 +0100
 Markus Armbruster arm...@redhat.com wrote:

 commit 8be7e7e4 and commit ec7b2ccb messed up the ordering of error
 message and the helpful explanation that should follow it, like this:
 
 $ qemu-system-x86_64 --nodefaults -S --vnc :0 --chardev null,id=,
 Identifiers consist of letters, digits, '-', '.', '_', starting
 with a letter.
 qemu-system-x86_64: -chardev null,id=,: Parameter 'id' expects
 an identifier
 
 $ qemu-system-x86_64 --nodefaults -S --vnc :0 --machine
 kvm_shadow_mem=dunno
 You may use k, M, G or T suffixes for kilobytes, megabytes,
 gigabytes and terabytes.
 qemu-system-x86_64: -machine kvm_shadow_mem=dunno: Parameter
 kvm_shadow_mem' expects a size
 
 Pity.  Disable them for now.

 Oops, sorry. I think I'd prefer to drop them, but as this fixes the problem:

 Reviewed-by: Luiz Capitulino lcapitul...@redhat.com

 Also, the real problem here is that general functions like parse_option_size()
 should never assume/try to guess in which context they're running. So, the
 best solution here is either to have a general enough error message that's
 not tied to any context, or let up layers (say vl.c) concatenate the
 context-dependent part of the error message.

I'm open to suggestions on how to better code the pattern report an
error (a short string without newlines) together with some explanation
or hint (possibly longer string, newlines okay).



Re: [Qemu-devel] [PATCH for-1.4 v2 4/6] qemu-option: Disable two helpful messages that got broken recently

2013-02-08 Thread Markus Armbruster
Luiz Capitulino lcapitul...@redhat.com writes:

 On Fri, 08 Feb 2013 19:58:42 +0100
 Markus Armbruster arm...@redhat.com wrote:

 Luiz Capitulino lcapitul...@redhat.com writes:
 
  On Fri,  8 Feb 2013 17:17:10 +0100
  Markus Armbruster arm...@redhat.com wrote:
 
  commit 8be7e7e4 and commit ec7b2ccb messed up the ordering of error
  message and the helpful explanation that should follow it, like this:
  
  $ qemu-system-x86_64 --nodefaults -S --vnc :0 --chardev null,id=,
  Identifiers consist of letters, digits, '-', '.', '_', starting
  with a letter.
  qemu-system-x86_64: -chardev null,id=,: Parameter 'id' expects
  an identifier
  
  $ qemu-system-x86_64 --nodefaults -S --vnc :0 --machine
  kvm_shadow_mem=dunno
  You may use k, M, G or T suffixes for kilobytes, megabytes,
  gigabytes and terabytes.
  qemu-system-x86_64: -machine kvm_shadow_mem=dunno: Parameter
  kvm_shadow_mem' expects a size
  
  Pity.  Disable them for now.
 
  Oops, sorry. I think I'd prefer to drop them, but as this fixes the 
  problem:
 
  Reviewed-by: Luiz Capitulino lcapitul...@redhat.com
 
  Also, the real problem here is that general functions like
  parse_option_size()
  should never assume/try to guess in which context they're running. So, the
  best solution here is either to have a general enough error message that's
  not tied to any context, or let up layers (say vl.c) concatenate the
  context-dependent part of the error message.
 
 I'm open to suggestions on how to better code the pattern report an
 error (a short string without newlines) together with some explanation
 or hint (possibly longer string, newlines okay).

 The real problem here is that the k, M, G suffixes, for example, are not
 good to be reported by QMP. So maybe we should refactor the code in a way
 that we separate what's done in QMP from what is done in HMP/command-line.

Isn't it separated already?  parse_option_size() is used when parsing
key=value,...  Such strings should not exist in QMP.  If they do, it's a
design bug.