[libvirt] [PATCH 2/5] conf: Introduce viremulator_capabilities

Daniel P. Berrange berrange at redhat.com
Mon Jun 23 14:26:10 UTC 2014


On Fri, Jun 20, 2014 at 04:19:07PM +0200, Michal Privoznik wrote:
> ---
>  docs/formatemulatorcaps.html.in                    |  52 ++++++++
>  docs/schemas/Makefile.am                           |   1 +
>  docs/schemas/emulatorcapability.rng                |  26 ++++
>  docs/sitemap.html.in                               |   4 +
>  libvirt.spec.in                                    |   1 +
>  mingw-libvirt.spec.in                              |   2 +
>  src/Makefile.am                                    |   3 +-
>  src/conf/viremulator_capabilities.c                | 139 +++++++++++++++++++++
>  src/conf/viremulator_capabilities.h                |  47 +++++++
>  src/libvirt_private.syms                           |   6 +
>  tests/Makefile.am                                  |  10 +-
>  .../viremulatorcaps-basic.xml                      |   5 +
>  tests/viremulatorcapabilitiesschematest            |  11 ++
>  tests/viremulatorcapabilitiestest.c                | 117 +++++++++++++++++
>  14 files changed, 422 insertions(+), 2 deletions(-)
>  create mode 100644 docs/formatemulatorcaps.html.in
>  create mode 100644 docs/schemas/emulatorcapability.rng
>  create mode 100644 src/conf/viremulator_capabilities.c
>  create mode 100644 src/conf/viremulator_capabilities.h
>  create mode 100644 tests/viremulatorcapabilitiesdata/viremulatorcaps-basic.xml
>  create mode 100755 tests/viremulatorcapabilitiesschematest
>  create mode 100644 tests/viremulatorcapabilitiestest.c

As a nitpick on naming I think I'd call this 'domain capabilities'
since it is about representing metadata about stuff you can put
in the domain conf XML schema. so eg src/conf/domain_capabilties.{c.h}
and virDomainCapsPtr for struct.

> diff --git a/src/conf/viremulator_capabilities.c b/src/conf/viremulator_capabilities.c
> new file mode 100644
> index 0000000..8e7d4af
> --- /dev/null
> +++ b/src/conf/viremulator_capabilities.c
> @@ -0,0 +1,139 @@
> +/*
> + * viremulator_capabilities.c: hypervisor capabilities
> + *
> + * Copyright (C) 2014 Red Hat, Inc.
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library.  If not, see
> + * <http://www.gnu.org/licenses/>.
> + *
> + * Author: Michal Privoznik <mprivozn at redhat.com>
> + */
> +
> +#include <config.h>
> +
> +#include "viremulator_capabilities.h"
> +#include "virobject.h"
> +#include "viralloc.h"
> +#include "virbuffer.h"
> +#include "virstring.h"
> +
> +#define VIR_FROM_THIS VIR_FROM_CAPABILITIES
> +
> +struct _virEmulatorCapabilities {
> +    virObjectLockable parent;
> +
> +    char *path;                     /* path to emulator binary */
> +    char *machine;                  /* machine type */
> +    virDomainVirtType virttype;     /* virtualization type */
> +
> +    void *privateData;
> +    virEmulatorCapabilitiesPrivateDataFormatFunc formatFunc;
> +};


> +static int
> +virEmulatorCapabilitiesFormatInternal(virEmulatorCapabilitiesPtr caps,
> +                                      virBufferPtr buf)
> +{
> +    const char *virttype_str = virDomainVirtTypeToString(caps->virttype);
> +
> +    virBufferAddLit(buf, "<emulatorCapabilities>\n");
> +    virBufferAdjustIndent(buf, 2);
> +    virBufferAsprintf(buf, "<path>%s</path>\n", caps->path);
> +    virBufferAsprintf(buf, "<domain>%s</domain>\n", virttype_str);
> +    virBufferAsprintf(buf, "<machine>%s</machine>\n", caps->machine);
> +    if (caps->formatFunc)
> +        caps->formatFunc(buf, caps->privateData, caps->machine);

I'm really not a fan of this - it lets every virt driver in libvirt invent
its own thing to put in these capabilities, which has bitten us in the
past, since we end up with divergence between drivers

I think we need to spec out some approach to representing the data in
this struct which drivers populate. To start with we're looking for
info on what enum values are supported in each device type. This should
probably be preface with a way to express what device types are actually
supported by the driver. eg so you can discover that <channel> is not
supported by Xen or LXC.

How about something like this:

  typedef const char * (*virDomainCapsEnumFormat)(int va;ue);

  struct _virDomainCapsEnum {
    int values; /* Bitmask of values supported in the corresponding enum */
  };

  struct _virDomainCapsDevice {
     bool supported; /* true if <devtype> is supported by hypervisor */
  };

  struct _virDomainCapsDeviceDisk {
     struct virDomainCapsDevice;
     virDomainCapsEnum device; /* Info about virDomainDiskDevice enum values */
     virDomainCapsEnum bus /* Info about virDomainDiskBus enum values */
     ...rest of enums used in virDomainDiskDef or anything it references...
  };
  
  struct _virDomainCapsDeviceHostdev {
     struct virDomainCapsDevice;
     virDomainCapsEnum mode; /* Info about virDomainHostdevMode */
     virDomainCapsEnum startupPolicy; /* Info about virDomainStartupPolicy */
     virDomainCapsEnum subsysType; /* Info about virDomainHostdevSubsysType */
     virDomainCapsEnum capsType; /* Info about virDomainHostdevCapsType */
     virDomainCapsEnum pciBackend; /* Info about virDomainHostdevSubsysPCIBackend */
  };

And then in virEmulatorCapabilities (well virDomainCaps) have

 virDomainCaps {
   ...

   virDomainCapsDeviceDisk disk;
   virDomainCapsDeviceHostdev hostdev;
   ...other device types...
 }

The virt drivers would then have todo something like this:

    caps.disk.supported = true;
    caps.disk.bus.values = (1 << VIR_DOMAIN_DISK_BUS_IDE) |
                           (1 << VIR_DOMAIN_DISK_BUS_FDC) |
                           (1 << VIR_DOMAIN_DISK_BUS_VIRTIO);
    caps.hostdev.supported = true;
    caps.hostdev.mode.values = (1 << VIR_HOSTDEV_MODE_SUBSYS) |
                               (1 << VIR_HOSTDEV_MODE_CAPS);
    ...etc...

The domain caps code would use the ToString functions from the relevant
VIR_ENUMs to turn the bits in the 'values' into strings when generating
the XML output.

So now any time a virt driver decides to support a new device type,
as well as doing its XML -> ARGV code, it should set the flag
'caps.<devtype>.supported = true' and populate the relevant enum
information.

Regards,
Daniel
-- 
|: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org              -o-             http://virt-manager.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org       -o-       http://live.gnome.org/gtk-vnc :|




More information about the libvir-list mailing list