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  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-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 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 Markus Armbruster
Laszlo Ersek  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  wrote:
>>> Luiz Capitulino  writes:
 On Thu, 14 Feb 2013 10:45:22 +0100
 Markus Armbruster  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 tha

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  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  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-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  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-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  wrote:
>> Luiz Capitulino  writes:
>>> On Thu, 14 Feb 2013 10:45:22 +0100
>>> Markus Armbruster  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 na

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  wrote:

> [Some quoted material restored]
> 
> Luiz Capitulino  writes:
> 
> > On Thu, 14 Feb 2013 10:45:22 +0100
> > Markus Armbruster  wrote:
> >
> >> [Note cc: +Laszlo, +Anthony, -qemu-trivial]
> >> 
> >> Luiz Capitulino  writes:
> >> 
> >> > On Fri, 08 Feb 2013 20:34:20 +0100
> >> > Markus Armbruster  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 ol

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  writes:

> On Thu, 14 Feb 2013 10:45:22 +0100
> Markus Armbruster  wrote:
>
>> [Note cc: +Laszlo, +Anthony, -qemu-trivial]
>> 
>> Luiz Capitulino  writes:
>> 
>> > On Fri, 08 Feb 2013 20:34:20 +0100
>> > Markus Armbruster  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 A

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  wrote:

> [Note cc: +Laszlo, +Anthony, -qemu-trivial]
> 
> Luiz Capitulino  writes:
> 
> > On Fri, 08 Feb 2013 20:34:20 +0100
> > Markus Armbruster  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

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  writes:

> On Fri, 08 Feb 2013 20:34:20 +0100
> Markus Armbruster  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 c

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  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).



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  writes:

> On Fri, 08 Feb 2013 19:58:42 +0100
> Markus Armbruster  wrote:
>
>> Luiz Capitulino  writes:
>> 
>> > On Fri,  8 Feb 2013 17:17:10 +0100
>> > Markus Armbruster  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 
>> >
>> > 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.



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  writes:

> On Fri,  8 Feb 2013 17:17:10 +0100
> Markus Armbruster  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 
>
> 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 Luiz Capitulino
On Fri, 08 Feb 2013 19:58:42 +0100
Markus Armbruster  wrote:

> Luiz Capitulino  writes:
> 
> > On Fri,  8 Feb 2013 17:17:10 +0100
> > Markus Armbruster  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 
> >
> > 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 Luiz Capitulino
On Fri,  8 Feb 2013 17:17:10 +0100
Markus Armbruster  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 

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 
> ---
>  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);