[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