qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] Re: Should QMP be RPC to internal C interfaces?


From: Anthony Liguori
Subject: [Qemu-devel] Re: Should QMP be RPC to internal C interfaces?
Date: Tue, 31 Aug 2010 08:03:15 -0500
User-agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.11) Gecko/20100713 Lightning/1.0b1 Thunderbird/3.0.6

On 08/31/2010 03:47 AM, Markus Armbruster wrote:
Anthony Liguori<address@hidden>  writes:

On 08/30/2010 09:52 AM, Markus Armbruster wrote:
Because it's too easy to get it wrong in QEMU.  Here's the rationale.

If I can't trivially call a QMP function in C, then I'm not going to
use QMP functions within QEMU.  I'm not going to create an embedded
JSON string just to call a function with three integer arguments.

Yes, an internal interface is better done in idiomatic C, not with JSON
strings.


Yes, if we need to do that, we can create a C API that both the QMP
interface uses and we also use internally but why?  All that does is
introduce the chance that the C API will have more features than the
QMP interface.

Why is that bad?

Internal and external interfaces have very different tradeoffs.

An internal interface should eschew backward compatibility and embrace
change.

An external interface needs to be stable, yet extensible.

Nope.
Which part(s) do you disagree with?

(1) Internal and external interfaces have very different tradeoffs.

(2) An internal interface should eschew backward compatibility and
     embrace change.

(3) An external interface needs to be stable, yet extensible.

If none of the above, then how do you propose to resolve the tension
between external and internal interfaces?

What's the different between an internal an external interface?

You're "external" interface at some point needs code in QEMU that implements the interface. Why can't that interface be used by another part of QEMU? Why is it then not an internal interface?

A big part of my argument here, is that we should be eating our own dog food with respect to QMP.We need to simplify. We simplify by reducing scope. Of the things

that are important, a useful API is more important than whether it
maps to your favorite dynamic language in an elegant way.
So you do propose we go back to square one and reargue the basics of
QMP.

I don't even know what you mean by that. Very, very, concretely, I'm suggesting that we:

1) Declare what we have supported

2) Design useful interfaces in C that we can consume internally (see above comment about eating our dog food)

3) Bridge those useful interfaces via QMP. Ideally, we would make the QMP code dead simple such that it could be generated. If ya'll want to pretty-ify it by making things have default values or whatever type of syntactic sugar you want, that's fine.

4) I'm specifically suggesting that we don't start at the QMP level when defining new interfaces.

What does that even mean? How do you describe the external interface
properly?

It's a hell of a lot simpler to design the external interface as a C
API, and then to implement the external interface as a C API.  Why
make life harder than that?
You define the external interace the same how you define any interface:
you specify operations, arguments, returns and so forth.

C declarations are not a specification.  For instance, a C prototype is
only a part of a function's specification.  It says too little about
possible values, nothing about error conditions, semantics and so forth.

Well here's how I've attempted to address it:

http://repo.or.cz/w/qemu/aliguori-queue.git/blob/refs/heads/qpi:/qpi-migration.h

We need our internal interfaces to be just as well specified as we need QMP to.

I think it's a vitally important requirement that all future QMP
functions have direct mappings to a C interface.

Why?
So that we can consume those APIs within QEMU.
QMP functions should consume the internal APIs.

A QMP function is concerned with interfacing and compatibility, and
leaves the actual work to the internal APIs.  Separation of concerns.

I don't think you can separate the two. I'd be happy to be proven wrong but so far, such an existence proof doesn't exist.

                                            What's the separation
between internal and external?  Is qdev internal or external?
qdev is the device model, i.e. a generic interface to devices.  qdev.h
is an internal interface.  It has a part facing generic code: the
generic interface to devices.  And it has a part facing devices: the
abstract interface the devices need to implement, plus stuff to help
with that.

The external interface is layered onto the internal interface.  -device
/ device_add expose a selected part of qdev externally.  info qtree
exposes some more.

device_add is intimately tied into qdev. If you don't believe me, look at http://repo.or.cz/w/qemu/aliguori.git/shortlog/refs/heads/features/qdev-refactor to see how much work it took to separate the two.

Concretely, I'm looking at doing some significant modelling changes. To consider virtio, we have virtio-net-pci today but I'd like to move to having a virtio-pci and adding virtio-net to virtio-pci. This would totally change the -device interface and break backwards compatibility.

So how am I going to address that? I don't know yet but I'm come to believe that -device as an interface is going to be a PITA to maintain and that we should have thought much harder about compatibility.

We could do a better job specifying either of the interfaces.  But
removing the distinction between internal and external interface doesn't
improve the specification of the external interface one bit.

The internal interface is much richer.  It contains things that are of
no interest remotely, including but not limited to the part facing
devices.

Really, you're argument boils down to: if we separate 'internal' and 'external' interfaces, we can totally ignore compatibility in the 'internal' interface and implement compatibility solely in the 'external' part of the interface.

I'm calling B.S. on that. Compatibility is a hard problem and we need to think about it when introducing any interfaces.

It's designed for local, not remote use.  In particular, it makes
liberal use of pointers.  How would you handle those over RPC?

A boxed type.  We discussed this as KVM Forum.  It would look like:

QBoxed *qboxed_new(const char *type, void *pointer);
void *qboxed_get_ptr(QBoxed *obj);

It marshals to a token. Internally, there's a static global map that associates a tuple of (type, token) with pointer.

A QPI operation like:

MigrationState *qpi_migration_create(Error **err);

Maps to QMP like:

string: token qmp_migration_create(void)

Or we could use a special QMP type for handles, it's really just a detail.

Regards,

Anthony Liguori

It can be changed easily, because the impact is limited to QEMU itself.
We don't do compatibility there, we just change it and fix up the users.




reply via email to

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