[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[libvirt] [PATCH 4/5] Add qemu dettach/reattach/reset implementation



Implement the new methods in the QEMU driver by parsing
the node device XML to obtain the PCI device details
and then calling the appropriate PCI utility function.

Signed-off-by: Mark McLoughlin <markmc redhat com>
---
 ChangeLog         |    5 ++
 src/qemu_driver.c |  130 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 132 insertions(+), 3 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index dd8241d..62a286f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Tue Feb 24 22:08:15 GMT 2009 Mark McLoughlin <markmc redhat com>
+
+	* src/qemu_driver.c: implement the new methods in the
+	QEMU driver.
+
 Tue Feb 24 22:02:32 GMT 2009 Mark McLoughlin <markmc redhat com>
 
 	* qemud/remote*, src/remote_internal.c: plumb the new
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index c2dfc71..7b13c5e 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -68,6 +68,8 @@
 #include "memory.h"
 #include "uuid.h"
 #include "domain_conf.h"
+#include "node_device_conf.h"
+#include "pci.h"
 
 #define VIR_FROM_THIS VIR_FROM_QEMU
 
@@ -4470,6 +4472,128 @@ cleanup:
     return dom;
 }
 
+static int
+qemudNodeDeviceGetPciInfo (virNodeDevicePtr dev,
+                           unsigned *vendor,
+                           unsigned *product,
+                           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) {
+            *vendor   = cap->data.pci_dev.vendor;
+            *product  = cap->data.pci_dev.product;
+            *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 vendor, product, domain, bus, slot, function;
+    int ret = -1;
+
+    if (qemudNodeDeviceGetPciInfo(dev, &vendor, &product,
+                                  &domain, &bus, &slot, &function) < 0)
+        return -1;
+
+    pci = pciGetDevice(dev->conn, vendor, product, domain, bus, slot, function);
+    if (!pci)
+        return -1;
+
+    if (pciDettachDevice(pci) < 0)
+        goto out;
+
+    ret = 0;
+out:
+    pciFreeDevice(pci);
+    return ret;
+}
+
+static int
+qemudNodeDeviceReAttach (virNodeDevicePtr dev)
+{
+    pciDevice *pci;
+    unsigned vendor, product, domain, bus, slot, function;
+    int ret = -1;
+
+    if (qemudNodeDeviceGetPciInfo(dev, &vendor, &product,
+                                  &domain, &bus, &slot, &function) < 0)
+        return -1;
+
+    pci = pciGetDevice(dev->conn, vendor, product, domain, bus, slot, function);
+    if (!pci)
+        return -1;
+
+    if (pciReAttachDevice(pci) < 0)
+        goto out;
+
+    ret = 0;
+out:
+    pciFreeDevice(pci);
+    return ret;
+}
+
+static int
+qemudNodeDeviceReset (virNodeDevicePtr dev)
+{
+    pciDevice *pci;
+    unsigned vendor, product, domain, bus, slot, function;
+    int ret = -1;
+
+    if (qemudNodeDeviceGetPciInfo(dev, &vendor, &product,
+                                  &domain, &bus, &slot, &function) < 0)
+        return -1;
+
+    pci = pciGetDevice(dev->conn, vendor, product, domain, bus, slot, function);
+    if (!pci)
+        return -1;
+
+    if (pciResetDevice(pci) < 0)
+        goto out;
+
+    ret = 0;
+out:
+    pciFreeDevice(pci);
+    return ret;
+}
+
 static virDriver qemuDriver = {
     VIR_DRV_QEMU,
     "QEMU",
@@ -4542,9 +4666,9 @@ static virDriver qemuDriver = {
     qemudDomainEventDeregister, /* domainEventDeregister */
     qemudDomainMigratePrepare2, /* domainMigratePrepare2 */
     qemudDomainMigrateFinish2, /* domainMigrateFinish2 */
-    NULL, /* nodeDeviceDettach */
-    NULL, /* nodeDeviceReAttach */
-    NULL, /* nodeDeviceReset */
+    qemudNodeDeviceDettach, /* nodeDeviceDettach */
+    qemudNodeDeviceReAttach, /* nodeDeviceReAttach */
+    qemudNodeDeviceReset, /* nodeDeviceReset */
 };
 
 
-- 
1.6.0.6


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]