
On 03/22/2010 03:10 PM, Daniel P. Berrange wrote:
This isn't necessarily libvirt's problem if it's mission is to provide a common hypervisor API that covers the most commonly used features.
That is more or less our current mission. If this mission leads to QEMU creating a non-libvirt based API& telling people to use that instead, then I'd say libvirt's mission needs to change to avoid that scenario ! I strongly believe that libvirt's strategy is good for application developers over the medium to long term. We need to figure out how to get rid of the short term pain from the feature timelag, rather than inventing a new library API for them to use.
Well that's certainly a good thing :-)
However, for qemu, we need an API that covers all of our features that people can develop against. The ultimate question we need to figure out is, should we encourage our users to always use libvirt or should we build our own API for people (and libvirt) to consume.
I don't think it's necessarily a big technical challenge for libvirt to support qemu more completely. I think it amounts to introducing a series of virQemuXXXX APIs that implement qemu specific functions. Over time, qemu specific APIs can be deprecated in favour of more generic virDomain APIs.
Stepping back a bit first, there are the two core areas in which people can be limited by libvirt currently.
1. Monitor commands 2. Command line flags
Ultimately, IIUC, you are suggesting we need to allow arbitrary passthrough for both of these in libvirt.
At the libvirt level, we have 3 core requirements
1. The XML format is extend only (new elements allowed, or add attributes or children to existing elements) 2. The C library API is append only (new symbols only) 3. The RPC wire protocol is append only (maps 1-1 to the C API generally)
We have a slightly different mentality within QEMU I think. Here's roughly how I'd characterize our guarantees. 1. For any two versions of QEMU, we try to guarantee that the same VM, as far as the guest sees it, can be created. 2. We tend to avoid changing command line syntax unless the syntax was previously undefined. 3. QMP supports enumeration and feature negotiation. This enables a client to discover which functions are supported. 4. We try to maintain monitor interfaces but provide no guarantees of compatibility.
The core question for us as libvirt developers is how we could support QEMU specific features that may change arbitrarily, without it impacting on our ability to maintain these 3 requirements for the non-hypervisor specific APIs.
We don't ever want to be in a situation where a QEMU specific API will require us to change the soname of the main libvirt library, or introduce incompatible wire protocol changes. If we were to introduce QEMU specific APIs, we also need a way to easily remove those over time, as& when we have them available as generic APIs.
At the C API level, this to me suggests that we'd want to introduce a separate libvirt-qemu.so library for the QEMU specific APIs. This library would not have the same requirements of fixed long term ABI that the main libvirt.so did. We'd add QEMU APIs to libvirt-qemu.so any time needed, but remove them when the equivalent functionality were in libvirt.so, and increment the soname of libvirt-qemu.so at that point.
How different is having a libvirt-qemu.so from having a libqemu.so that libvirt.so uses? Practically speaking, if libvirt-qemu.so uses a separate XML namespace, does the fact that we use a different config format matter since you can transform our config format to XML and vice versa? I think the problem is, if libvirt.so introduces a common API, removing it from libvirt-qemu.so is burdensome to an end-user. For someone designing a QEMU specific management application, why should they have to update their implementation to a common API that they'll never use?
At the wire protocol level, the protocol allows us to support multiple versioned protocols in parallel over the same data stream. So again there, we could define a sub-protocol for QEMU specific features for which we don't provide the indefinite ABI compatability.
Finally the XML format is "easy" - just have a versioned XML namespace for extra pieces, that's distinct from the default namespace, again without the permanent long term compatability guarentees.
There are, however, some bits that are unlikely to work when QEMU is under libvirt. Specifically any of the device backends that use stdio (eg, -serial stdio, or the ncurses graphics), simply because all libvirt spawned VMs are fully daemonized& so stdio is /dev/null
This seems fixable with //session.
Other items are hard, but not entirely impossible to solve. eg, any use of the 'script=' arg for -net devices doesn't work, because libvirt clears all capabilities from the QEMU process so it'll be lacking CAP_NET_ADMIN which most TAP device setup scripts in fact need.
Some parts of the C library/wire protocol here are related to another feature I'd like to introduce for libvirt, namely a administrative library. eg a API to configure and manage the libvirtd daemon itself on the fly. This could easily hook into the wire protocol, but live as a separate libvirt-daemon.so library API in similar way to what I suggest for QEMU specific API
What's the feeling about this from the libvirt side of things? Is there interest in support hypervisor specific interfaces should we be looking to provide our own management interface for libvirt to consume?
Adding yet another library in the stack isn't really going to solve the problem from the POV of libvirt users, but rather fork the community effort which I imagine we'd all rather avoid. Having to tell people to switch to a different library API to get access to a specific feature is a short term win, but with a significant long term cost/burden. This means we really do need to figure out how to better/fully support QEMU's features in libvirt, removing the feature timelag pain.
I think what we need to do is find a way to more tightly integrate the QEMU and libvirt communities in such a way that when a patch was submitted against QEMU adding a new feature, we could ask that that feature was implemented in libvirt. I see two ways to do this. One would be for libvirt to have a libvirt.so and libvirt-qemu.so. The QEMU community would have to be much more heavily involved in libvirt-qemu.so and it probably suggests that libvirt-qemu.so should follow our release cycle. libvirt would have to support using either libvirt.so or libvirt-qemu.so for it's users. The alternative would be for the QEMU community to produce a libqemu.so and for libvirt.so to consume libqemu.so. The libvirt community ought to be heavily engaged in the development of libqemu.so and certainly, shared maintainership would be appropriate. A user using libvirt.so should see guests created with either libqemu.so or libvirt.so although libqemu.so would provide weaker long term compatibility guarantees (but more features). I think both approaches are technically workable. The question is which is the most appealing to both communities and which requires the least development effort. At a high level, I think libqemu.so would require a heavy refactoring of the qemu libvirt driver. Guest enumeration would have to be handled by qemu and libvirt would need to support translating qemu's config format to an XML format. It would also need to translate the qemu XML format into it's own XML format relying on an xmlns to support the features that are not currently supported by the common hypervisor API. The advantage though would be that any qemu instance launched would be visible to libvirt and libvirt tooling. libvirt-qemu.so would require less change to the qemu driver in libvirt but would require some awkwardness in terms of translating a guest config to an XML config. Some of the concepts that qemu supports (like running a guest as non-privileged user using stdio) would be difficult to support. Regards, Anthony Liguori Regards, Anthony Liguori
Regards, Daniel