[libvirt] [PATCH RFC 4/4] qemu: Implement virConnectGetDomainCapabilities

Daniel P. Berrange berrange at redhat.com
Thu Jun 26 10:42:42 UTC 2014


On Thu, Jun 26, 2014 at 12:18:28PM +0200, Michal Privoznik wrote:
> Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
> ---
>  src/libvirt_private.syms     |   1 +
>  src/qemu/qemu_capabilities.c |  82 ++++++++++++++++++++++++++++++++++
>  src/qemu/qemu_capabilities.h |   4 ++
>  src/qemu/qemu_driver.c       | 102 +++++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 189 insertions(+)
> 
> diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> index 6c583b0..4bf57a4 100644
> --- a/src/libvirt_private.syms
> +++ b/src/libvirt_private.syms
> @@ -437,6 +437,7 @@ virDomainVideoTypeFromString;
>  virDomainVideoTypeToString;
>  virDomainVirtioEventIdxTypeFromString;
>  virDomainVirtioEventIdxTypeToString;
> +virDomainVirtTypeFromString;
>  virDomainVirtTypeToString;
>  virDomainWatchdogActionTypeFromString;
>  virDomainWatchdogActionTypeToString;
> diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
> index 8e0a550..0a1f6fc 100644
> --- a/src/qemu/qemu_capabilities.c
> +++ b/src/qemu/qemu_capabilities.c
> @@ -39,6 +39,7 @@
>  #include "virnodesuspend.h"
>  #include "qemu_monitor.h"
>  #include "virstring.h"
> +#include "qemu_hostdev.h"
>  
>  #include <fcntl.h>
>  #include <sys/stat.h>
> @@ -3509,3 +3510,84 @@ virQEMUCapsSupportsChardev(virDomainDefPtr def,
>              (chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE &&
>               chr->targetType == VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_VIRTIO));
>  }
> +
> +
> +static void
> +virQEMUCapsFillDomainDeviceDiskCaps(virQEMUCapsPtr qemuCaps,
> +                                    virDomainCapsDeviceDiskPtr disk)
> +{
> +    disk->device.supported = true;
> +    /* QEMU supports all of these */
> +    disk->diskDevice.values = (1 << VIR_DOMAIN_DISK_DEVICE_DISK) |
> +                              (1 << VIR_DOMAIN_DISK_DEVICE_CDROM) |
> +                              (1 << VIR_DOMAIN_DISK_DEVICE_FLOPPY) |
> +                              (1 << VIR_DOMAIN_DISK_DEVICE_LUN);

IIRC, LUN required a specific version of QEMU, but can't remember
which.

> +
> +    disk->bus.values = (1 << VIR_DOMAIN_DISK_BUS_IDE) |
> +                       (1 << VIR_DOMAIN_DISK_BUS_FDC) |
> +                       (1 << VIR_DOMAIN_DISK_BUS_SCSI) |
> +                       (1 << VIR_DOMAIN_DISK_BUS_VIRTIO) |
> +                       (1 << VIR_DOMAIN_DISK_BUS_XEN) |
> +                       (1 << VIR_DOMAIN_DISK_BUS_SD);

I think  'SD' requires a particular QEMU version.

Also, don't think we support 'XEN' any more actually - that was
probably left over from the Xenner support we ripped out a while
ago.

> +
> +    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_USB_STORAGE))
> +        disk->bus.values |= (1 << VIR_DOMAIN_DISK_BUS_USB);
> +}
> +
> +
> +static void
> +virQEMUCapsFillDomainDeviceHostdevCaps(virQEMUCapsPtr qemuCaps,
> +                                       virDomainCapsDeviceHostdevPtr hostdev)
> +{
> +    bool supportsPassthroughKVM = qemuHostdevHostSupportsPassthroughLegacy();
> +    bool supportsPassthroughVFIO = qemuHostdevHostSupportsPassthroughVFIO();
> +
> +    hostdev->device.supported = true;
> +    /* VIR_DOMAIN_HOSTDEV_MODE_CAPABILITIES is for containers only */
> +    hostdev->subsysType.values = (1 << VIR_DOMAIN_HOSTDEV_MODE_SUBSYS);
> +
> +    hostdev->startupPolicy.values = (1 << VIR_DOMAIN_STARTUP_POLICY_DEFAULT) |
> +        (1 << VIR_DOMAIN_STARTUP_POLICY_MANDATORY) |
> +        (1 << VIR_DOMAIN_STARTUP_POLICY_REQUISITE) |
> +        (1 << VIR_DOMAIN_STARTUP_POLICY_OPTIONAL);
> +
> +    hostdev->subsysType.values = (1 << VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) |
> +        (1 << VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI);
> +    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE) &&
> +        virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE) &&
> +        virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_SCSI_GENERIC))
> +        hostdev->subsysType.values |= 1 << VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI;
> +
> +    /* No virDomainHostdevCapsType for QEMU */
> +    hostdev->capsType.values = 0;
> +
> +    hostdev->pciBackend.values = 0;
> +    if (supportsPassthroughVFIO &&
> +        virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VFIO_PCI)) {
> +        hostdev->pciBackend.values |= (1 << VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT) |
> +                                      (1 << VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO);
> +
> +    }
> +
> +    if (supportsPassthroughKVM &&
> +        (virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCIDEVICE) ||
> +         virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE))) {
> +        hostdev->pciBackend.values |= (1 << VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT) |
> +                                      (1 << VIR_DOMAIN_HOSTDEV_PCI_BACKEND_KVM);
> +    }
> +}


> +static char *
> +qemuConnectGetDomainCapabilities(virConnectPtr conn,
> +                                 const char *emulatorbin,
> +                                 const char *arch_str,
> +                                 const char *machine,
> +                                 const char *virttype_str,
> +                                 unsigned int flags)
> +{
> +    char *ret = NULL;
> +    virQEMUDriverPtr driver = conn->privateData;
> +    virQEMUCapsPtr qemuCaps = NULL;
> +    int virttype; /* virDomainVirtType */
> +    size_t ncanonicalMachine, i;
> +    const char **canonicalMachine;
> +    virDomainCapsPtr domCaps = NULL;
> +    int arch; /* virArch */
> +
> +    virCheckFlags(0, ret);
> +    virCheckNonNullArgReturn(emulatorbin, ret);
> +    virCheckNonNullArgReturn(virttype_str, ret);

I think virttype is the only thing we must have as mandatory.

At least one of emulator or arch must be given. eg given one
we can lookup the other.

Machine we can pick the default if NULL so that's fine.

> +
> +    if (virConnectGetDomainCapabilitiesEnsureACL(conn) < 0)
> +        return ret;
> +
> +    if ((virttype = virDomainVirtTypeFromString(virttype_str)) < 0) {
> +        virReportError(VIR_ERR_INVALID_ARG,
> +                       _("unknown virttype: %s"), virttype_str);
> +        goto cleanup;
> +    }
> +
> +    if (!(qemuCaps = virQEMUCapsCacheLookup(driver->qemuCapsCache,
> +                                            emulatorbin)))
> +        goto cleanup;
> +
> +    if (machine) {
> +        const char *machine_tmp;
> +
> +        if (!(machine_tmp = virQEMUCapsGetCanonicalMachine(qemuCaps,
> +                                                           machine))) {
> +            /* This should never ever happen (TM) */
> +            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> +                           _("an error that should never "
> +                             "ever happen just occurred"));
> +            goto cleanup;
> +        }
> +        machine = machine_tmp;
> +    }
> +
> +    /* The virQEMUCapsGetMachineTypes expects char *** but we want to stress
> +     * the fact that we are not going to change machine types array, so we are
> +     * using const char *** */
> +    if (!(ncanonicalMachine = virQEMUCapsGetMachineTypes(qemuCaps,
> +                                                         (char ***) &canonicalMachine))) {
> +        virReportError(VIR_ERR_INVALID_ARG,
> +                       _(" emulator doesn't support any machines: %s"),
> +                       emulatorbin);
> +        goto cleanup;
> +    }
> +
> +    if (machine) {
> +        for (i = 0; i < ncanonicalMachine; i++) {
> +            if (STREQ(machine, canonicalMachine[i]))
> +                break;
> +        }
> +
> +        if (i == ncanonicalMachine) {
> +            virReportError(VIR_ERR_INVALID_ARG,
> +                           _("the machine '%s' is not supported by emulator '%s'"),
> +                           machine, emulatorbin);
> +            goto cleanup;
> +        }
> +    } else {
> +        /* The default machine type is at the first position */
> +        machine = canonicalMachine[0];
> +    }

Probably worth defining a 'virQEMUCapsIsMachineSupported" method and a
virQEMUCapsGetDefaultMachine method 


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