* src/qemu_driver.c: add qemu dettach/reattach/reset implementation

patch by Mark McLoughlin.
Daniel
This commit is contained in:
Daniel Veillard 2009-03-02 16:32:52 +00:00
parent 0231102863
commit 34d23b0b01
2 changed files with 125 additions and 3 deletions

View File

@ -1,3 +1,8 @@
Mon Mar 2 17:31:48 CET 2009 Daniel Veillard <veillard@redhat.com>
* src/qemu_driver.c: add qemu dettach/reattach/reset implementation
patch by Mark McLoughlin.
Mon Mar 2 17:28:42 CET 2009 Daniel Veillard <veillard@redhat.com> Mon Mar 2 17:28:42 CET 2009 Daniel Veillard <veillard@redhat.com>
* qemud/remote.c qemud/remote_dispatch_args.h * qemud/remote.c qemud/remote_dispatch_args.h

View File

@ -68,6 +68,8 @@
#include "memory.h" #include "memory.h"
#include "uuid.h" #include "uuid.h"
#include "domain_conf.h" #include "domain_conf.h"
#include "node_device_conf.h"
#include "pci.h"
#define VIR_FROM_THIS VIR_FROM_QEMU #define VIR_FROM_THIS VIR_FROM_QEMU
@ -4500,6 +4502,121 @@ cleanup:
return dom; return dom;
} }
static int
qemudNodeDeviceGetPciInfo (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(dev->conn, xml);
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) {
qemudReportError(dev->conn, NULL, NULL, 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
qemudNodeDeviceDettach (virNodeDevicePtr dev)
{
pciDevice *pci;
unsigned domain, bus, slot, function;
int ret = -1;
if (qemudNodeDeviceGetPciInfo(dev, &domain, &bus, &slot, &function) < 0)
return -1;
pci = pciGetDevice(dev->conn, domain, bus, slot, function);
if (!pci)
return -1;
if (pciDettachDevice(dev->conn, pci) < 0)
goto out;
ret = 0;
out:
pciFreeDevice(dev->conn, pci);
return ret;
}
static int
qemudNodeDeviceReAttach (virNodeDevicePtr dev)
{
pciDevice *pci;
unsigned domain, bus, slot, function;
int ret = -1;
if (qemudNodeDeviceGetPciInfo(dev, &domain, &bus, &slot, &function) < 0)
return -1;
pci = pciGetDevice(dev->conn, domain, bus, slot, function);
if (!pci)
return -1;
if (pciReAttachDevice(dev->conn, pci) < 0)
goto out;
ret = 0;
out:
pciFreeDevice(dev->conn, pci);
return ret;
}
static int
qemudNodeDeviceReset (virNodeDevicePtr dev)
{
pciDevice *pci;
unsigned domain, bus, slot, function;
int ret = -1;
if (qemudNodeDeviceGetPciInfo(dev, &domain, &bus, &slot, &function) < 0)
return -1;
pci = pciGetDevice(dev->conn, domain, bus, slot, function);
if (!pci)
return -1;
if (pciResetDevice(dev->conn, pci) < 0)
goto out;
ret = 0;
out:
pciFreeDevice(dev->conn, pci);
return ret;
}
static virDriver qemuDriver = { static virDriver qemuDriver = {
VIR_DRV_QEMU, VIR_DRV_QEMU,
"QEMU", "QEMU",
@ -4572,9 +4689,9 @@ static virDriver qemuDriver = {
qemudDomainEventDeregister, /* domainEventDeregister */ qemudDomainEventDeregister, /* domainEventDeregister */
qemudDomainMigratePrepare2, /* domainMigratePrepare2 */ qemudDomainMigratePrepare2, /* domainMigratePrepare2 */
qemudDomainMigrateFinish2, /* domainMigrateFinish2 */ qemudDomainMigrateFinish2, /* domainMigrateFinish2 */
NULL, /* nodeDeviceDettach */ qemudNodeDeviceDettach, /* nodeDeviceDettach */
NULL, /* nodeDeviceReAttach */ qemudNodeDeviceReAttach, /* nodeDeviceReAttach */
NULL, /* nodeDeviceReset */ qemudNodeDeviceReset, /* nodeDeviceReset */
}; };