qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] QMP interface for drive-add (or even blockdev-add)


From: Kevin Wolf
Subject: [Qemu-devel] QMP interface for drive-add (or even blockdev-add)
Date: Thu, 16 May 2013 10:24:41 +0200
User-agent: Mutt/1.5.21 (2010-09-15)

[ CCed qemu-devel, Stefan and Luiz ]

Am 15.05.2013 um 19:43 hat Eric Blake geschrieben:
> On 05/15/2013 09:58 AM, Kevin Wolf wrote:
> > 
> > Not really. Basically what I have in mind is the obvious mapping of the
> > command line arguments (using the downstream command here because
> > upstream doesn't even have a QMP drive_add yet):
> > 
> >     -drive format=qcow2,id=some_disk,file.driver=nbd,\
> >         file.host=localhost,lazy_refcounts=on
> > 
> > would become something like:
> > 
> >     {
> >         "execute": "__com.redhat_drive_add",
> >         "arguments": {
> >             "format": "qcow2",
> >             "id": "some_disk",
> >             "file": {
> >                 "driver": "nbd",
> >                 "host": "localhost"
> >             }
> >             "lazy_refcounts": true,
> >         }
> >     }
> 
> Yeah, that might work.  More interesting, like you say, would be
> learning how to know what options are available, and figuring out how to
> write that into a maintainable JSON spec.

Actually, there is one important point to note in this proposal: It's
that driver-specific and generic options are mixed in the same
namespace. This allows a conversion of one option after another and the
API doesn't change after each step.

On the other hand, they behave somewhat different (only converted
options can be overridden for backing files), so maybe we actually have
to switch everything within one release.

> > I'm not sure how well that works with the existing implementation of
> > QAPI etc. but it's what I think makes the most sense from a protocol
> > level perspective. And that should take precedence.
> > 
> > By the way, if you have any ideas about how to make driver-specific
> > options discoverable for libvirt, I'd be glad to hear them. Should it be
> > a QMP query command that returns a list of all drivers and what options
> > they support? Or can we somehow handle it with (dynamic) schema
> > introspection? Or would a command line option similar to '-device help'
> > be more helpful than a monitor command because you need to know the
> > valid values before starting qemu?
> 
> Introspection would work, although having a dedicated command might make
> the information easier to get at.  Libvirt would prefer to get
> information through QMP, not a command-line option.  But don't worry
> about timing - when libvirt starts, we spawn a dummy qemu just to do QMP
> queries of everything we need to know (and cache those results), so that
> when we finally spawn qemu command lines for real, we've already learned
> from the earlier QMP calls what is available on the command line. 

Okay, that's already a very helpful information to have. I believe
exposing things over QMP is more convenient for qemu as well.

> Also,
> the recent addition of query-command-line-options might be extensible -
> right now, the QAPI type CommandLineParameterType is hard-coded to one
> of four basic types; but we could extend it to list a fifth type, maybe
> named 'qapi', and where we can then expose an additional argument
> stating what QAPI type to introspect for further details.  That is,
> something like:
> 
> ->{"execute":"query-command-line-options",
>    "arguments":{"option":"drive"} }
> <-{"return":[
>    {"option":"drive", "parameters":[
>     {"name":"file", "type":"qapi", "qapi":"BlockFile"},
>     {"name":"backing", "type":"qapi", "BlockBackingFile"}
>    ]}]}

Here you're assuming a different layout than I outlined above. I guess
we'd have to directly make "parameters" the union...

> ->{"execute":"query-qapi-type", "arguments":{"type":"BlockFile"} }
> <-{"return":{"union":"BlockFile", "data":{
>     "nbd":"BlockFileNBD",
>     "qcow2":"BlockFileQcow2"} }
> ->{"execute":"query-qapi-type", "arguments":{"type":"BlockFileNBD"} }
> <-{"return":{"type","BlockFileNBD", "data":{
>     "port":"int", "host":"str", ...
>    } }
> 
> which would be enough to know that if I want to open an NBD disk, I can
> use -drive file=nbd:,file.port=1234,file.host=::1, because the 'file'
> option to -drive has a union type that I can introspect to learn what
> additional file.suboptions I can specify when using a given arm of the
> union.

...but I agree that using a union here may be workable. However, it
brings us back to the question asked in a different thread: How to
expose which drivers are actually available? I still think we need a
dynamic schema for introspection. (But how should doing this dynmically
work if QAPI maps this to a C union?)

Another thing that we'll probably want from QAPI is some kind of
inheritance, like this:

{ "type": "BlockFileBase", data: { "driver": "str", "cache": "CacheEnum",
  ... }

{ "type": "BlockFileNBD", "extends": "BlockFileBase", "data": {
    "port": "*int", "host": "str", ... }}

> In working all of this out upstream, we may decide to tweak the command
> line syntax (after all, how do I know that file.driver controls which
> arm of the union to take, and therefore which other file.FOO sub-options
> are available?), so I'm glad we disabled sub-maps in qemu 1.5 until we
> can match the QMP exposure of submaps.

Okay, let's take a step back here. The idea was more or less that you
can specify each BlockDriverState by itself in the end, like this:

{ "execute": "blockdev-add", "data": {
    "id": "my_file", "driver": "file", "filename": "test.qcow2" }}

{ "execute": "blockdev-add", "data": {
    "id": "my_qcow2", "driver": "qcow2", "file": "my_file" }}

But at least as an interface for human users this would become very
tedious, so "file" became inlined and you specify only the qcow2 image
and reference the options of the underlying raw-posix driver by using
its file option:

{
    "execute": "blockdev-add",
    "data": {
        "id": "my_qcow2",
        "driver": "qcow2",
        "file": {
            "id": "my_file",
            "driver": "file",
            "filename": "test.qcow2"
        }
    }
}

So far I've neglected the option to refer to an existing
BlockDriverState using its ID instead of specifying a new BDS inline.
I'm not even sure yet how we can make it an option to use either a string
or an embedded struct, but we'll need both options.

In this example, you can also see that "file.driver" doesn't specify
which arm of the union "my_qcow2" takes, but it's the type of "my_file"
that it influences.

Anyway, I hope this makes it a bit clearer what my thoughts behind this
system were and where I was planning to go with it.

> But I'm definitely interested in
> helping get the design off the ground; should we move this to the
> upstream qemu list?

Yes, definitely. Done. :-)

Kevin



reply via email to

[Prev in Thread] Current Thread [Next in Thread]