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

Marek Marczykowski marmarek at invisiblethingslab.com
Wed May 22 23:32:09 UTC 2013


On 22.05.2013 16:36, Jim Fehlig wrote:
> 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?

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 */
>>   


-- 
Best Regards,
Marek Marczykowski
Invisible Things Lab

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 555 bytes
Desc: OpenPGP digital signature
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20130523/f476c788/attachment-0001.sig>


More information about the libvir-list mailing list