[Top][All Lists]

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

Re: Making QEMU easier for management tools and applications

From: Christophe de Dinechin
Subject: Re: Making QEMU easier for management tools and applications
Date: Wed, 8 Jan 2020 12:40:03 +0100

> On 8 Jan 2020, at 11:43, Kevin Wolf <address@hidden> wrote:
> Am 07.01.2020 um 18:11 hat Christophe de Dinechin geschrieben:
>> So I think that it might help, in the long run, to start defining the
>> language in question in some abstract way, and then to have rules
>> for how to transform that abstract language into concrete bindings.
> I think this abstract language is QAPI.

Currently, yes, that’s the closest we have to a well-defined language,
I pointed it out in my mail, and there is qapi-code-gen.txt to prove it.

So it would certainly make sense for the language I’m describing to
be a forward evolution of QAPI, or something that is trivially transformed
to / from the existing json schema.

> The problem is that we're not even close to using QAPI for everything.

That’s the symptom of the problem. The problem as I see it is that
we could not. at least not with today’s QAPI (maybe I’m wrong).
A good example is shortcut command-line options. I don’t think
you can, today, derive a user-friendly command-line syntax from
qapi-schema.json, and even less so one that is compatible with what
we have today.

> Adding a new language on top of QAPI instead isn't going to make the
> conversion process any faster.

I fully agree that whatever language we select has to have an easy,
systematic forward path from QAPI, but also from the other
existing meta-languages, like the .def files used for options,
or build configuration (there is a hint of the connection between
the two in the option ‘if’ member in the .json files).

In other words, the language I have in mind would be something
that I could auto-generate from, say, the current qapi-schema.json
and the qemu-options.def. Maybe in the end, that would be simply
by having qemu-options.def being used to build qemu-options.json,
and then add the relevant entries in qemu-options.json. Maybe
there is a better way.

>> This definition itself is not obvious (at least not to me). For
>> example, do we have, anywhere but in the C code, the specification
>> of how one can add a disk to qemu, and what it means?
>> Say, looking at qemu-options.def, how do I tell that -hda has
>> anything to do with -device or -blockdev or -help?
> BlockdevOptions in the QAPI schema is what tells you how it _really_
> works.

Not really, IMO, in the sense that it gives me no clue as to how -hda
or -device relate to it.

An important point that you raise through your response, though, is
that the QAPI schema is only an IDL (interface definition language).
In other words, it can tell me what a BlockdevOptions look like on
the wire, but at least in the current state, it cannot tell me what happens
with it.

This is probably a good thing (it’s already complicated enough as is),
but it’s worth pointing out that, even sticking to a declarative language,
one could add constraints, as hinted by HAS_ARG in the .def file
(but we could have a richer constraints language, e.g. describing
-m option so that there can be at most one, the arg is a number,
can’t be negative or floating-point, and so on.

And of course, we could decide to not stick to a declarative language,
but to have a way to have some, possibly limited, processing
described in the language. I’m thinking notably of what is called
“desugaring” in other threads.

> The connection to the various command line syntaxes isn't defined
> in a declarative way because we don't have a QAPIfied command line yet.
> I know that Markus wants to work on this, but I don't know how much time
> he actually has to invest in it.

Agreed. As I said, that’s a symptom that QAPI is not the language
I am talking about, but at best a subset of it.

>> I think that the following piece of code from vl.c is revealing:
>>            case QEMU_OPTION_hda:
>>            case QEMU_OPTION_hdb:
>>            case QEMU_OPTION_hdc:
>>            case QEMU_OPTION_hdd:
>>                drive_add(IF_DEFAULT, popt->index - QEMU_OPTION_hda, optarg,
>>                          HD_OPTS);
>>                break;
>>            case QEMU_OPTION_blockdev:
>>                {
>>                    Visitor *v;
>>                    BlockdevOptionsQueueEntry *bdo;
>>                    v = qobject_input_visitor_new_str(optarg, "driver",
>>                                                      &error_fatal);
>>                    bdo = g_new(BlockdevOptionsQueueEntry, 1);
>>                    visit_type_BlockdevOptions(v, NULL, &bdo->bdo,
>>                                               &error_fatal);
>>                    visit_free(v);
>>                    loc_save(&bdo->loc);
>>                    QSIMPLEQ_INSERT_TAIL(&bdo_queue, bdo, entry);
>>                    break;
>>                }
>>            case QEMU_OPTION_drive:
>>                if (drive_def(optarg) == NULL) {
>>                    exit(1);
>>                }
>>                break;
>> Here, we have three cases related to disks in a way or another,
>> and three entirely different ways of doing things.
> I would say two different ways because drive_add() is just a small
> wrapper around drive_def() that overrides a few options.

Well, I stick to three, because one option has a test and an exit(1),
and the other does not. Which is the kind of inconsistencies a
well-defined language would get rid of.

> Describing the semantics of the -drive way is hard. This is one of the
> reasons why I would love to get rid of it and replace it with a new
> user-friendly option that has a more direct mapping to the -blockdev
> way, which in turn just is BlockdevOptions mapped 1:1 to the command
> line.

I would love that too :-)

>> AFAICT, qemu already created several meta-languages to define
>> several aspects of the API, from qemu-options.def to qapi-schema.json.
>> But maybe at some point we need to go meta once more, and define
>> a language defining the API from which we could automatically
>> derive the various bindings, including FFI-style bindings for Rust and Go,
>> as well as some internal data structures. Ideally, that meta-definition
>> is something that could be shared between libvirt and qemu so that they
>> literally speak the same language. Or that could be used to automatically
>> build a REST interface.
> I think adding an output for additional languages to the QAPI generator
> shouldn't be too hard. It already creates multiple things from a single
> schema (C data structures and command wrappers, schema introspection
> data, documentation, and probably other things that I forgot).


> libvirt already speaks QAPI, however without reusing the schema and the
> generator from QEMU.

That’s another thread ;-)

>> A big issue, though, is that of compatibility. Doing the above starting
>> from scratch does not seem that complicated. Doing it in a way that
>> preserves a minimum of interoperability with earlier-generation
>> software is another ordeal.
> Indeed, this is the major reason why QAPI isn't as pervasive as it
> should be.

Probably, but also because QAPI does not address the needs of
some of the things a slightly more general language could do.

>> So I think that Daniel is right. We may need at some point to start
>> a NEMU-style offshoot that does not attempt to be compatible,
>> but explores describing an increasing surface of the API using a
>> new meta-language from which we can generate, in a consistent
>> way, at least:
>> - C bindings
>> - Command-line options
>> - Shell bindings (or “HMP”)
>> - JSON schema or qom description
>> - Bindings in other languages (Rust, Go, Python)
>> - Networked versions of the API (socket, REST)
>> - Client-side code e.g. for libvirt.
>> - Serialization / deserialization, e.g. for configuration files
>> - Documentation, including man page and API docs
>> - Command-line help
> I think the only thing in this list that can't obviously be covered
> easily by QAPI is QOM. Or rather, it's covered by passing through
> key=value lists without describing their structure

That’s close enough to me. (In my mind, that part was already “done”
by QAPI, even if in the convoluted way you describe)

> - which, as far as I
> understand, is mainly because QOM properties aren't necessarily static,
> so we can't provide a statically defined interface for them. Probably
> solvable in QEMU, but not without a major effort.

Or maybe extend the language so that it’s internal semantics
knows about this aspect of QOM?

> In a fork that doesn’t care about compatibility, it should be easier.
>> At the most fundamental level, I think we need to describe:
>> - Values, e.g. how we represent names, sizes, paths, etc, possibly
>> with some user-friendly aspects, e.g. path shortcuts, memory units,
>> spelling shortcuts (e.g. being able to consistently say -blo for -blockdev
>> if that’s the shortest option that matches)
> I don't think user-friendly shortcuts on the command line are "most
> fundamental".

I agree, my phrasing was poor. What I meant is that the language in
question should include a user-convenience dimension that is
not necessary (and not present) in QAPI. Agree the details are not
fundamental, I meant them as an illustration.

> Whether to accept -blo is an implementation detail of the
> command line parser which translates a bunch of strings into QAPI
> objects.


>> - Relations, e.g. how we represent “contains”, “derives from”, “needs”,
>> “one of”, “one or several”, “attaches to”…
>> - States, e.g. how do we represent the machine configuration,
>> or the desired new disk setting
>> - Verbs, e.g. how we represent “add”, “connect”, “remove”, “find”,
>> “start”, “notify”, etc. and how we describe the kind of input they need.
>> - Possibly more subtle things like support for transactions, commit/rollback,
>> i.e. “I want to add connect a virtual nic to some host vf, but if anything
>> along the way fails, I’d like all the cleanup to happen automatically)
> This sounds like a different approach from our current QAPI command set

Well, except for purposefully trying to use a different wording to avoid
the risk of getting your mind stuck in one of the particular existing
meta-languages in QEMU, the approach is not very different.

- Relations already exist in QAPI for example: ’struct’, ‘union’, ‘alternate’

- States exist, today represented using JSON

- Verbs are called “commands” in the QAPI json files, and are what
follows DEF( in the .def file

- Transactions do not exist today that I know of, although we see
signs of them in discussions about the fact that this options destroys
that back end but that option does not.

> (use a smaller set of operations that can work with a greater variety of
> objects).

More like trying to find terminology that lets you reason about it
without being too mind-constrainted by existing stuff.

> Does it actually provide more functionality, though?

It’s not intended to provide more, but to require less to do the same thing.


reply via email to

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