[libvirt] [PATCH RESENT 03/12] libxl: nodeDevice* support for PCI devices

Jim Fehlig jfehlig at suse.com
Wed May 22 14:36:15 UTC 2013


Marek Marczykowski wrote:
> For now only for PCI devices. Mostly copy-paste from old xen driver.
>   

This one is (or will be) covered by Chanyan's work as well right?

Regards,
Jim

> ---
>  src/libxl/libxl_driver.c | 193 +++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 193 insertions(+)
>
> diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
> index 40a7a6b..011edf8 100644
> --- a/src/libxl/libxl_driver.c
> +++ b/src/libxl/libxl_driver.c
> @@ -42,6 +42,7 @@
>  #include "libxl.h"
>  #include "libxl_driver.h"
>  #include "libxl_conf.h"
> +#include "node_device_conf.h"
>  #include "xen_xm.h"
>  #include "virtypedparam.h"
>  #include "viruri.h"
> @@ -3666,6 +3667,195 @@ libxlDomainUpdateDeviceFlags(virDomainPtr dom, const char *xml,
>      return libxlDomainModifyDeviceFlags(dom, xml, flags, LIBXL_DEVICE_UPDATE);
>  }
>  
> +static int
> +libxlNodeDeviceGetPciInfo(virNodeDevicePtr dev,
> +                               unsigned *domain,
> +                               unsigned *bus,
> +                               unsigned *slot,
> +                               unsigned *function)
> +{
> +    virNodeDeviceDefPtr def = NULL;
> +    virNodeDevCapsDefPtr cap;
> +    char *xml = NULL;
> +    int ret = -1;
> +
> +    xml = virNodeDeviceGetXMLDesc(dev, 0);
> +    if (!xml)
> +        goto out;
> +
> +    def = virNodeDeviceDefParseString(xml, EXISTING_DEVICE, NULL);
> +    if (!def)
> +        goto out;
> +
> +    cap = def->caps;
> +    while (cap) {
> +        if (cap->type == VIR_NODE_DEV_CAP_PCI_DEV) {
> +            *domain   = cap->data.pci_dev.domain;
> +            *bus      = cap->data.pci_dev.bus;
> +            *slot     = cap->data.pci_dev.slot;
> +            *function = cap->data.pci_dev.function;
> +            break;
> +        }
> +
> +        cap = cap->next;
> +    }
> +
> +    if (!cap) {
> +        virReportError(VIR_ERR_INVALID_ARG,
> +                       _("device %s is not a PCI device"), dev->name);
> +        goto out;
> +    }
> +
> +    ret = 0;
> +out:
> +    virNodeDeviceDefFree(def);
> +    VIR_FREE(xml);
> +    return ret;
> +}
> +
> +static int
> +libxlNodeDeviceDettach(virNodeDevicePtr dev)
> +{
> +    virPCIDevicePtr pci;
> +    unsigned domain, bus, slot, function;
> +    int ret = -1;
> +
> +    if (libxlNodeDeviceGetPciInfo(dev, &domain, &bus, &slot, &function) < 0)
> +        return -1;
> +
> +    pci = virPCIDeviceNew(domain, bus, slot, function);
> +    if (!pci)
> +        return -1;
> +
> +    if (virPCIDeviceDetach(pci, NULL, NULL, "pciback") < 0)
> +        goto out;
> +
> +    ret = 0;
> +out:
> +    virPCIDeviceFree(pci);
> +    return ret;
> +}
> +
> +static int
> +libxlNodeDeviceAssignedDomainId(virNodeDevicePtr dev)
> +{
> +    int numdomains;
> +    int numpcidevs;
> +    int ret = -1, i, j;
> +    int *ids = NULL;
> +    char *bdf = NULL;
> +    char *xref = NULL;
> +    unsigned int domain, bus, slot, function;
> +    libxl_device_pci *pcidevs = NULL;
> +    virConnectPtr conn = dev->conn;
> +    libxlDriverPrivatePtr driver = conn->privateData;
> +
> +    /* Get active domains */
> +    numdomains = libxlNumDomains(conn);
> +    if (numdomains < 0) {
> +        return ret;
> +    }
> +    if (numdomains > 0){
> +        if (VIR_ALLOC_N(ids, numdomains) < 0) {
> +            virReportOOMError();
> +            goto out;
> +        }
> +        if ((numdomains = libxlListDomains(conn, &ids[0], numdomains)) < 0) {
> +            goto out;
> +        }
> +    }
> +
> +    /* Get pci bdf */
> +    if (libxlNodeDeviceGetPciInfo(dev, &domain, &bus, &slot, &function) < 0)
> +        goto out;
> +
> +    if (virAsprintf(&bdf, "%04x:%02x:%02x.%0x",
> +                    domain, bus, slot, function) < 0) {
> +        virReportOOMError();
> +        goto out;
> +    }
> +
> +    libxlDriverLock(driver);
> +    /* Check if bdf is assigned to one of active domains */
> +    for (i = 0; i < numdomains; i++) {
> +        pcidevs = libxl_device_pci_list(driver->ctx, ids[i], &numpcidevs);
> +        if (pcidevs == NULL) {
> +            continue;
> +        } else {
> +            for (j = 0; j < numpcidevs; j++) {
> +                if (pcidevs[j].bus == bus && pcidevs[j].dev == slot && pcidevs[j].func == function) {
> +                    ret = ids[i];
> +                    break;
> +                }
> +            }
> +            VIR_FREE(pcidevs);
> +        }
> +    }
> +    libxlDriverUnlock(driver);
> +
> +    VIR_FREE(xref);
> +    VIR_FREE(bdf);
> +out:
> +    VIR_FREE(ids);
> +
> +    return ret;
> +}
> +
> +static int
> +libxlNodeDeviceReAttach(virNodeDevicePtr dev)
> +{
> +    virPCIDevicePtr pci;
> +    unsigned domain, bus, slot, function;
> +    int ret = -1;
> +    int domid;
> +
> +    if (libxlNodeDeviceGetPciInfo(dev, &domain, &bus, &slot, &function) < 0)
> +        return -1;
> +
> +    pci = virPCIDeviceNew(domain, bus, slot, function);
> +    if (!pci)
> +        return -1;
> +
> +    /* Check if device is assigned to an active guest */
> +    if ((domid = libxlNodeDeviceAssignedDomainId(dev)) >= 0) {
> +        virReportError(VIR_ERR_INTERNAL_ERROR,
> +                       _("Device %s has been assigned to guest %d"),
> +                       dev->name, domid);
> +        goto out;
> +    }
> +
> +    if (virPCIDeviceReattach(pci, NULL, NULL, "pciback") < 0)
> +        goto out;
> +
> +    ret = 0;
> +out:
> +    virPCIDeviceFree(pci);
> +    return ret;
> +}
> +
> +static int
> +libxlNodeDeviceReset(virNodeDevicePtr dev)
> +{
> +    virPCIDevicePtr pci;
> +    unsigned domain, bus, slot, function;
> +    int ret = -1;
> +
> +    if (libxlNodeDeviceGetPciInfo(dev, &domain, &bus, &slot, &function) < 0)
> +        return -1;
> +
> +    pci = virPCIDeviceNew(domain, bus, slot, function);
> +    if (!pci)
> +        return -1;
> +
> +    if (virPCIDeviceReset(pci, NULL, NULL) < 0)
> +        goto out;
> +
> +    ret = 0;
> +out:
> +    virPCIDeviceFree(pci);
> +    return ret;
> +}
> +
>  static unsigned long long
>  libxlNodeGetFreeMemory(virConnectPtr conn)
>  {
> @@ -4233,6 +4423,9 @@ static virDriver libxlDriver = {
>      .nodeGetFreeMemory = libxlNodeGetFreeMemory, /* 0.9.0 */
>      .domainEventRegister = libxlDomainEventRegister, /* 0.9.0 */
>      .domainEventDeregister = libxlDomainEventDeregister, /* 0.9.0 */
> +    .nodeDeviceDettach = libxlNodeDeviceDettach, /* 1.0.4 */
> +    .nodeDeviceReAttach = libxlNodeDeviceReAttach, /* 1.0.4 */
> +    .nodeDeviceReset = libxlNodeDeviceReset, /* 1.0.4 */
>      .domainManagedSave = libxlDomainManagedSave, /* 0.9.2 */
>      .domainHasManagedSaveImage = libxlDomainHasManagedSaveImage, /* 0.9.2 */
>      .domainManagedSaveRemove = libxlDomainManagedSaveRemove, /* 0.9.2 */
>   




More information about the libvir-list mailing list