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

Mark McLoughlin markmc at redhat.com
Tue Feb 24 22:21:50 UTC 2009


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 at 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 at 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 at 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




More information about the libvir-list mailing list