[libvirt] Libvirt debug API

Daniel P. Berrange berrange at redhat.com
Fri Apr 9 14:27:17 UTC 2010

On Fri, Apr 09, 2010 at 09:41:39AM -0400, Chris Lalancette wrote:
> Hello,
>      In response to a lot of the talk of qemud lately on qemu-devel, the
> libvirt community would like to put forward a proposal to help enable
> debug/advanced options when using various hypervisors.  The goals of
> this API are:
> 1)  To enable more rapid access to hypervisor features before proper
> libvirt API's are designed around them.
> 2)  To facilitate debugging and access to advanced features that may
> not fit into the normal libvirt world-view.
> Caveats:
> 1)  Unlike other libvirt API's, this one will explicitly *not* be
> guaranteed ABI/API compatible between libvirt updates.

I think we'd still aim to keep the public API stable. The bit that we
can't guarentee is the interactions with QEMU & the libvirt driver. 
eg, if someone was using the API to send text monitor commands to
QEMU, and the next libvirt release switched to JSON mode, that use
would break. The API would still be valid, but the way they use it
might not be. Similarly if they add some custom extra command line
argument, this could potentially conflict with an extra command line
arg a subsquent libvirt release used. eg, they used -device to add
a PCI card with a specific PCI address. Then next libvirt release
specifies this same PCI address and then you get a clash. 

So in both cases the API and XML format can be reasonably guarenteed
between releases. What we can't guarentee is that usage  of these
features will be reliable across releases of libvirt.

> 2)  Again unlike other libvirt API's, access and configuration of
> the debug section of a domain will be highly hypervisor dependent.
> 3)  Application developers will be strongly discouraged from using
> this API because of the above 2 issues.  To help in this, the
> API's will be in a separate library that developers will explicitly
> have to link to, and it will have a different (but largely compatible)
> wire protocol.

In terms of wire protocol, this would still have to run over the same
existing data channel, because we don't want apps to have to open up
multiple connections. Fortunately our protocol is designed to allow
this kind of extension

  struct remote_message_header {
      unsigned prog;              /* REMOTE_PROGRAM */
      unsigned vers;              /* REMOTE_PROTOCOL_VERSION */
      remote_procedure proc;      /* REMOTE_PROC_x */
      remote_message_type type;
      unsigned serial;            /* Serial number of message. */
      remote_message_status status;

We currently have a single program 'REMOTE_PROGRAM' and its associated
'vers' and 'proc' numbers. What we would be doing is to define a new 
program, say QEMU_PROGRAM. The 'remote_procedure proc' numbers can thus
start again from '1' without clashing with any of the existing APIs. 
All the RPC marshalling/demarshalling code should work more or less
unchanged. We just hook in a different function dispatch table in the
daemon for that program.

> 4)  We don't expect this API to solve all of the issues brought up
> during the qemud discussion.  Our initial goal is just to give
> ready access of the qemu command-line and monitor to developers.
> With that being said, our initial proposal follows.  We expect this
> to evolve over time as we get more feedback, but we think this
> proposal addresses at least 2 of the major pain points qemu developers
> have while trying to use libvirt.
> The initial debug XML for qemu would be:

I wouldn't call them 'debug' options, since that's just one of possible
use cases for this. What we're really doing there is exposing hypervisor
specific features, so we should just be upfront about that in our 
description / naming.

> <domain type='kvm'>
>   <name>myguest</name>
>   ...
>   <debug>
>     <monitorpassthrough/>
>     <commandline>
>       <extra>qemu arguments</extra>
>       <alter option="optname">
>         <rename>newname</rename>
>         <match>REGEXP</match>
>         <modify>foo=on</modify>
>         <extra>-bar</extra>
>       </alter>
>     </commandline>
>   </debug>
> </domain>

The concept of command line & monitor is something that is QEMU specific
and thus is not suitable for the primary XML schema. IMHO, this needs to be
done as a separate schema, linked in via an XML namespace. For example

  <domain type='kvm' xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0">

> Raw access to the qemu monitor will be disabled by default; the
> <monitorpassthrough/> tag enables the ability to send QMP (or
> text, if you are using older qemu) messages straight through to the
> monitor.  To do this there will be an additional API entry point
> named virDomainDebugCommand() which takes an arbitrary string
> and passes it to the monitor, and returns an arbitrary string as
> a result.  Thus you could pass in either "info cpus" if using the
> text monitor or '{ "execute": "query-cpus" }' if using QMP.

Again the idea of a 'virDomainDebugCommand' API is QEMU specific, with
other hypervisors have different approaches for low level extension/
debug. For example, Xen would involve XenStore access, or XenD XMLRPC,
etc. So this should really live in a separate API namespace which is
specific to a hypervisor. For example, as a header file

  #include <libvirt/libvirt-qemu.h>

Containing APIs like

  int virDomainQEMUInvokeMonitor(virDomainPtr dom,
                                 const char *command,
                                 char **reply);

  typedef virConnectQEMUDomainEventCallback(virConnectPtr conn,
                                            virDomainPtr dom, 
                                            const char *eventname,
                                            const char *data,
                                            void *opaque)
  int virConnectQEMUDomainEventRegister(virConnectPtr conn,
                                        virDomainPtr dom,
                                        const char *eventname,
                                        virDomainQEMUMonitorCallback cb,
                                        void *opaque);

For an add-on library


I don't think there's much to be gained from having an XML element to
turn on/off use of these APIs. If an app doesn't want to use them, it
can simply not link to libvirt-qemu.so

> The <commandline><extra> tag does exactly what you might expect; appends
> the exact string to the qemu command-line.

Allowing many args at once in the <extra> blob means that libvirt will
need to parse & split this up into individual args which than then be
safely passed to 'exec'. It is better to specify one arg per element
to avoid this fragile parsing problem.

> The <alter> tag gets more interesting.  The idea is that <alter> would
> allow you to modify the libvirt-generated qemu command-line in arbitrary
> ways.  How this would work is probably best explained with some examples:
> <commandline>
>   <alter option="-net">
>     <rename>-netdev</rename>
>   </alter>
> </commandline>
> In this example, all options named -net on the qemu command-line are
> renamed to -netdev.
> In this example, if (and only if) a -net option is seen, then -usbtablet is
> appended to the qemu command-line.
> <commandline>
>   <alter option="-net">
>     <match>\(.*name=hostnet0.*\)</match>
>     <modify>\1,tap</modify>
>   </alter>
> </commandline>
> This gets more complicated (but also more powerful).  In this case, any -net

I think this alteration of existing args is faaaar too complex & fragile,
and way overkill. If the arg that libvirt generates isn't what someone 
needs, then remove the bit of the guest config responsible for that and
add a complete extra arg, rather than munging the existing one.

|: Red Hat, Engineering, London    -o-   http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://deltacloud.org :|
|: http://autobuild.org        -o-         http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505  -o-   F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

More information about the libvir-list mailing list