All of lore.kernel.org
 help / color / mirror / Atom feed
From: Markus Armbruster <armbru@redhat.com>
To: "Daniel P. Berrange" <berrange@redhat.com>
Cc: "Paolo Bonzini" <pbonzini@redhat.com>,
	"Andreas Färber" <afaerber@suse.de>,
	qemu-devel@nongnu.org, qemu-block@nongnu.org,
	"Max Reitz" <mreitz@redhat.com>
Subject: Re: [Qemu-devel] [PATCH v14 09/21] qapi: permit auto-creating single element lists
Date: Fri, 21 Oct 2016 13:58:08 +0200	[thread overview]
Message-ID: <87vawl29tb.fsf@dusky.pond.sub.org> (raw)
In-Reply-To: <20161020142333.GB27909@redhat.com> (Daniel P. Berrange's message of "Thu, 20 Oct 2016 15:23:33 +0100")

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

> On Wed, Oct 12, 2016 at 11:18:21AM +0200, Markus Armbruster wrote:
>> "Daniel P. Berrange" <berrange@redhat.com> writes:
>> 
>> > When converting QemuOpts to a QObject, there is no information
>> > about compound types available,
>> 
>> Yes, that's a drawback of splitting the conversion into a QemuOpts ->
>> QObject part that is oblivious of types, and a QObject -> QAPI object
>> part that knows the types.
>> 
>> >                                 so when visiting a list, the
>> > corresponding QObject is not guaranteed to be a QList. We
>> > therefore need to be able to auto-create a single element QList
>> > from whatever type we find.
>> >
>> > This mode should only be enabled if you have compatibility
>> > requirements for
>> >
>> >    -arg foo=hello,foo=world
>> >
>> > to be treated as equivalent to the preferred syntax:
>> >
>> >    -arg foo.0=hello,foo.1=world
>> 
>> Not sure this is "preferred".  "More powerfully warty" is probably
>> closer to the truth ;)
>
> Well, I call it "preferred" in the sense that that option syntax
> directly maps to the QAPI syntax in an unambigous manner. ie
> given the arg value alone "foo.0=hello,foo.1=world" you can clearly
> determine that "foo" is a list. With the compat syntax you cannot
> distinguish list from scalar, without knowing the QAPI schema.
>
>> How is "-arg foo=hello,foo=world" treated if this mode isn't enabled?
>
> The default behaviour would be that only the last key is present in
> the dict, eg foo=world, and then if you tried to visit a list, the
> visitor would complain that its got a QString instead of QList for
> the key 'foo'.
>
> This is related to patch 14
>
>> What would be the drawbacks of doing this always instead of only when we
>> "have compatibility requirements"?
>
> Essentially we'd be permanently allowing 2 distinct syntaxes for
> dealing with lists, for all options. I felt it desirable that we
> have only a single syntax and only allow this alt syntax in the
> backcompat cases.

Fair point.

The bolted-on extensions (options visitor's integer list syntax, block
layer's dotted key convention) have only ever worked in the places that
choose to use them.  Even the integrated support for repeated keys is
only used for lists in the places that choose to use it that way.

>> > diff --git a/qapi/qobject-input-visitor.c b/qapi/qobject-input-visitor.c
>> > index d9269c9..d88e9f9 100644
>> > --- a/qapi/qobject-input-visitor.c
>> > +++ b/qapi/qobject-input-visitor.c
>> > @@ -48,6 +48,10 @@ struct QObjectInputVisitor
>> >  
>> >      /* True to reject parse in visit_end_struct() if unvisited keys remain. */
>> >      bool strict;
>> > +
>> > +    /* Whether we can auto-create single element lists when
>> > +     * encountering a non-QList type */
>> > +    bool autocreate_list;
>> >  };
>> >  
>> >  static QObjectInputVisitor *to_qiv(Visitor *v)
>> > @@ -108,6 +112,7 @@ static const QListEntry *qobject_input_push(QObjectInputVisitor *qiv,
>> >      assert(obj);
>> >      tos->obj = obj;
>> >      tos->qapi = qapi;
>> > +    qobject_incref(obj);
>> >  
>> >      if (qiv->strict && qobject_type(obj) == QTYPE_QDICT) {
>> >          h = g_hash_table_new(g_str_hash, g_str_equal);
>> > @@ -147,6 +152,7 @@ static void qobject_input_stack_object_free(StackObject *tos)
>> >      if (tos->h) {
>> >          g_hash_table_unref(tos->h);
>> >      }
>> > +    qobject_decref(tos->obj);
>> >  
>> >      g_free(tos);
>> >  }
>> 
>> Can you explain the reference counting change?
>
> Previously the stack stored a borrowed reference, since it didn't
> ever need responsibility for free'ing the object when popping the
> stack. This is no longer the case if you look a few lines later....
>
>
>> 
>> > @@ -197,7 +203,7 @@ static void qobject_input_start_list(Visitor *v, const char *name,
>> >      QObject *qobj = qobject_input_get_object(qiv, name, true);
>> >      const QListEntry *entry;
>> >  
>> > -    if (!qobj || qobject_type(qobj) != QTYPE_QLIST) {
>> > +    if (!qobj || (!qiv->autocreate_list && qobject_type(qobj) != QTYPE_QLIST)) {
>> 
>> Long line, but I believe it'll go away when you rebase for commit
>> 1382d4a.
>> 
>> >          if (list) {
>> >              *list = NULL;
>> >          }
>> > @@ -206,7 +212,16 @@ static void qobject_input_start_list(Visitor *v, const char *name,
>> >          return;
>> >      }
>> >  
>> > -    entry = qobject_input_push(qiv, qobj, list, errp);
>> > +    if (qobject_type(qobj) != QTYPE_QLIST) {
>> > +        QList *tmplist = qlist_new();
>> > +        qlist_append_obj(tmplist, qobj);
>> > +        qobject_incref(qobj);
>> > +        entry = qobject_input_push(qiv, QOBJECT(tmplist), list, errp);
>> > +        QDECREF(tmplist);
>
> ... here we are storing the 'qmplist' in the stack, and so when
> popping the stack, we must free that object. We thus need
> the stack to always hold its own reference, so when popping
> it can decref and (potentially) release the last reference.

Aha.

Manual reference counting is a PITA.

>> > +    } else {
>> > +        entry = qobject_input_push(qiv, qobj, list, errp);
>> > +    }
>> > +
>> >      if (list) {
>> >          if (entry) {
>> >              *list = g_malloc0(size);
>> 
>> Buries autolist behavior in the middle of things.  What about doing it
>> first, so it's more separate?
>
> I'm not sure I understand what you mean here ?

I'm suggesting a structure like this:

    1. Map special case to normal case
    2. Deal with normal case

Keeping the normal case and the special case separate like that can make
it easier to understand either.

Here's my attempt to do it:

>>        QObjectInputVisitor *qiv = to_qiv(v);
>>        QObject *qobj = qobject_input_get_object_(qiv, name, true, errp);
>>        const QListEntry *entry;
>> 
>>        if (!qobj) {
>>            return;
>>        }
>>    
>>   +    if (qiv->autocreate_list && qobject_type(qobj) != QTYPE_QLIST) {
>>   +        QList *auto_list = qlist_new();
>>   +        qlist_append_obj(auto_list, qobj);
>>   +        qobj = auto_list;
>>   +    }
>>   +

The new code is the mapping.  The normal case code below remains
unchanged.  It's just a sketch; I didn't spend a single brainwave on the
reference counting.

>>        if (qobject_type(qobj) != QTYPE_QLIST) {
>> 
>> I ignored reference counting here, because I don't yet understand how
>> and why you're changing it.
>> 
>> > @@ -514,7 +529,8 @@ Visitor *qobject_input_visitor_new(QObject *obj, bool strict)
>> >      return &v->visitor;
>> >  }
>> >  
>> > -Visitor *qobject_input_visitor_new_autocast(QObject *obj)
>> > +Visitor *qobject_input_visitor_new_autocast(QObject *obj,
>> > +                                            bool autocreate_list)
>> >  {
>> >      QObjectInputVisitor *v;
>> >  
>> > @@ -539,6 +555,7 @@ Visitor *qobject_input_visitor_new_autocast(QObject *obj)
>> >      v->visitor.optional = qobject_input_optional;
>> >      v->visitor.free = qobject_input_free;
>> >      v->strict = true;
>> > +    v->autocreate_list = autocreate_list;
>> >  
>> >      v->root = obj;
>> >      qobject_incref(obj);
>> > @@ -548,6 +565,7 @@ Visitor *qobject_input_visitor_new_autocast(QObject *obj)
>> >  
>> >  
>> >  Visitor *qobject_input_visitor_new_opts(const QemuOpts *opts,
>> > +                                        bool autocreate_list,
>> >                                          Error **errp)
>> >  {
>> >      QDict *pdict;
>> > @@ -564,7 +582,8 @@ Visitor *qobject_input_visitor_new_opts(const QemuOpts *opts,
>> >          goto cleanup;
>> >      }
>> >  
>> > -    v = qobject_input_visitor_new_autocast(pobj);
>> > +    v = qobject_input_visitor_new_autocast(pobj,
>> > +                                           autocreate_list);
>> >   cleanup:
>> >      qobject_decref(pobj);
>> >      QDECREF(pdict);
>> [Skipping test updates for now...]
>
> Regards,
> Daniel

  reply	other threads:[~2016-10-21 11:58 UTC|newest]

Thread overview: 109+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-09-30 14:45 [Qemu-devel] [PATCH v14 00/21] QAPI/QOM work for non-scalar object properties Daniel P. Berrange
2016-09-30 14:45 ` [Qemu-devel] [PATCH v14 01/21] option: make parse_option_bool/number non-static Daniel P. Berrange
2016-10-21 16:55   ` Markus Armbruster
2016-10-21 17:12     ` Eric Blake
2016-10-21 17:51       ` Markus Armbruster
2016-09-30 14:45 ` [Qemu-devel] [PATCH v14 02/21] qdict: implement a qdict_crumple method for un-flattening a dict Daniel P. Berrange
2016-10-18 14:32   ` Markus Armbruster
2016-10-20 14:11     ` Daniel P. Berrange
2016-10-21  9:58       ` Markus Armbruster
2016-10-21 18:31         ` Max Reitz
2016-10-24  9:18           ` Markus Armbruster
2016-10-24 10:28             ` Daniel P. Berrange
2016-10-24 12:38               ` Markus Armbruster
2016-10-25 10:03           ` Markus Armbruster
2016-10-25 10:20             ` Daniel P. Berrange
2016-10-25 12:29               ` Markus Armbruster
2016-09-30 14:45 ` [Qemu-devel] [PATCH v14 03/21] qapi: add trace events for visitor Daniel P. Berrange
2016-09-30 15:49   ` Eric Blake
2016-10-06 14:39   ` [Qemu-devel] [Qemu-block] " Kevin Wolf
2016-10-07 13:59   ` [Qemu-devel] " Markus Armbruster
2016-10-07 14:16     ` Daniel P. Berrange
2016-10-21 10:52       ` Markus Armbruster
2016-09-30 14:45 ` [Qemu-devel] [PATCH v14 04/21] qapi: rename QmpInputVisitor to QObjectInputVisitor Daniel P. Berrange
2016-10-25 13:41   ` Markus Armbruster
2016-09-30 14:45 ` [Qemu-devel] [PATCH v14 05/21] qapi: rename QmpOutputVisitor to QObjectOutputVisitor Daniel P. Berrange
2016-10-25 13:36   ` Markus Armbruster
2016-09-30 14:45 ` [Qemu-devel] [PATCH v14 06/21] qapi: don't pass two copies of TestInputVisitorData to tests Daniel P. Berrange
2016-09-30 17:43   ` Eric Blake
2016-10-06 14:39   ` [Qemu-devel] [Qemu-block] " Kevin Wolf
2016-09-30 14:45 ` [Qemu-devel] [PATCH v14 07/21] qapi: permit scalar type conversions in QObjectInputVisitor Daniel P. Berrange
2016-09-30 17:48   ` Eric Blake
2016-10-11 16:20   ` Markus Armbruster
2016-10-12 14:51     ` Markus Armbruster
2016-10-12 15:05       ` Markus Armbruster
2016-10-12 15:26         ` Markus Armbruster
2016-09-30 14:45 ` [Qemu-devel] [PATCH v14 08/21] qapi: allow QObjectInputVisitor to be created with QemuOpts Daniel P. Berrange
2016-09-30 17:55   ` Eric Blake
2016-10-06 14:56   ` [Qemu-devel] [Qemu-block] " Kevin Wolf
2016-10-12  8:08   ` [Qemu-devel] " Markus Armbruster
2016-10-13  7:23     ` Markus Armbruster
2016-09-30 14:45 ` [Qemu-devel] [PATCH v14 09/21] qapi: permit auto-creating single element lists Daniel P. Berrange
2016-09-30 17:59   ` Eric Blake
2016-10-12  9:18   ` Markus Armbruster
2016-10-20 14:23     ` Daniel P. Berrange
2016-10-21 11:58       ` Markus Armbruster [this message]
2016-09-30 14:45 ` [Qemu-devel] [PATCH v14 10/21] qapi: permit auto-creating nested structs Daniel P. Berrange
2016-09-30 18:23   ` Eric Blake
2016-10-06 15:10   ` [Qemu-devel] [Qemu-block] " Kevin Wolf
2016-10-06 15:18     ` Daniel P. Berrange
2016-10-06 15:30       ` Kevin Wolf
2016-10-06 15:39         ` Daniel P. Berrange
2016-10-06 15:51           ` Kevin Wolf
2016-10-06 15:57             ` Daniel P. Berrange
2016-10-12 14:00               ` Markus Armbruster
2016-10-06 17:54         ` Eric Blake
2016-10-12 14:12   ` [Qemu-devel] " Markus Armbruster
2016-09-30 14:45 ` [Qemu-devel] [PATCH v14 11/21] qapi: add integer range support for QObjectInputVisitor Daniel P. Berrange
2016-09-30 19:45   ` Eric Blake
2016-10-12 15:50   ` Markus Armbruster
2016-10-12 16:03     ` [Qemu-devel] [Qemu-block] " Kevin Wolf
2016-10-12 18:14       ` Markus Armbruster
2016-10-20 14:28     ` [Qemu-devel] " Daniel P. Berrange
2016-10-21 10:58       ` Markus Armbruster
2016-09-30 14:45 ` [Qemu-devel] [PATCH v14 12/21] option: allow qemu_opts_to_qdict to merge repeated options Daniel P. Berrange
2016-09-30 20:08   ` Eric Blake
2016-10-12 17:46   ` Markus Armbruster
2016-10-13  9:21     ` Markus Armbruster
2016-10-20 14:29     ` Daniel P. Berrange
2016-10-21 11:09       ` Markus Armbruster
2016-10-21 11:14         ` Daniel P. Berrange
2016-10-13  8:31   ` Markus Armbruster
2016-10-20 14:37     ` Daniel P. Berrange
2016-10-21 11:28       ` Markus Armbruster
2016-09-30 14:45 ` [Qemu-devel] [PATCH v14 13/21] qdict: allow qdict_crumple to accept compound types as values Daniel P. Berrange
2016-10-13 12:35   ` Markus Armbruster
2016-10-13 14:46     ` Kevin Wolf
2016-10-17 14:50       ` Markus Armbruster
2016-10-17 15:43         ` Paolo Bonzini
2016-10-17 17:48           ` Markus Armbruster
2016-10-17 17:38         ` Eric Blake
2016-10-18 10:59           ` Markus Armbruster
2016-10-18  9:34         ` Kevin Wolf
2016-10-18 15:35           ` Markus Armbruster
2016-10-19  9:25             ` Kevin Wolf
2016-10-19  9:42               ` Daniel P. Berrange
2016-10-19 13:31             ` [Qemu-devel] [Qemu-block] " Eric Blake
2016-10-20 14:46     ` [Qemu-devel] " Daniel P. Berrange
2016-09-30 14:45 ` [Qemu-devel] [PATCH v14 14/21] qapi: allow repeated opts with qobject_input_visitor_new_opts Daniel P. Berrange
2016-10-18 17:13   ` Markus Armbruster
2016-09-30 14:45 ` [Qemu-devel] [PATCH v14 15/21] qom: support non-scalar properties with -object Daniel P. Berrange
2016-10-19 16:54   ` Markus Armbruster
2017-07-10 19:30   ` Manos Pitsidianakis
2017-07-11  8:10     ` Markus Armbruster
2017-07-11 14:44       ` Markus Armbruster
2017-07-11 14:49         ` Daniel P. Berrange
2017-07-12 17:56           ` Manos Pitsidianakis
2016-09-30 14:45 ` [Qemu-devel] [PATCH v14 16/21] hmp: support non-scalar properties with object_add Daniel P. Berrange
2016-10-20  6:43   ` Markus Armbruster
2016-09-30 14:45 ` [Qemu-devel] [PATCH v14 17/21] numa: convert to use QObjectInputVisitor for -numa Daniel P. Berrange
2016-10-20  6:57   ` Markus Armbruster
2016-09-30 14:45 ` [Qemu-devel] [PATCH v14 18/21] block: convert crypto driver to use QObjectInputVisitor Daniel P. Berrange
2016-09-30 14:45 ` [Qemu-devel] [PATCH v14 19/21] acpi: convert to QObjectInputVisitor for -acpi parsing Daniel P. Berrange
2016-09-30 14:45 ` [Qemu-devel] [PATCH v14 20/21] net: convert to QObjectInputVisitor for -net/-netdev parsing Daniel P. Berrange
2016-10-20  7:38   ` Markus Armbruster
2016-10-20 13:43     ` [Qemu-devel] [Qemu-block] " Eric Blake
2016-09-30 14:45 ` [Qemu-devel] [PATCH v14 21/21] qapi: delete unused OptsVisitor code Daniel P. Berrange
2016-09-30 15:45 ` [Qemu-devel] [PATCH v14 00/21] QAPI/QOM work for non-scalar object properties no-reply
2016-09-30 18:50   ` Eric Blake
2016-10-21 18:30 ` Markus Armbruster

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87vawl29tb.fsf@dusky.pond.sub.org \
    --to=armbru@redhat.com \
    --cc=afaerber@suse.de \
    --cc=berrange@redhat.com \
    --cc=mreitz@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.