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

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

 



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@xxxxxxxxxx>
---
 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@xxxxxxxxxx>
+
+	* src/qemu_driver.c: implement the new methods in the
+	QEMU driver.
+
 Tue Feb 24 22:02:32 GMT 2009 Mark McLoughlin <markmc@xxxxxxxxxx>
 
 	* 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

--
Libvir-list mailing list
Libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list

[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]