[libvirt] PATCH: Don't reset / detach host PCI devices in test scripts !

Daniel P. Berrange berrange at redhat.com
Mon Mar 2 20:51:01 UTC 2009


The PCI passthrough patches made it so that qemudBuildCommandLine() would
actually try to detach your host devices & reset them. Most definitely not
what you want when running this via a test case!

This patch moves the host device management out into a separate method,
so that qemudBuildCommandLine() doesn't do anything except safely build
the command line.

Daniel

 qemu_conf.c   |   46 -----------------------------------
 qemu_driver.c |   76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 76 insertions(+), 46 deletions(-)

Index: src/qemu_conf.c
===================================================================
RCS file: /data/cvs/libvirt/src/qemu_conf.c,v
retrieving revision 1.133
diff -u -p -u -p -r1.133 qemu_conf.c
--- src/qemu_conf.c	2 Mar 2009 20:22:35 -0000	1.133
+++ src/qemu_conf.c	2 Mar 2009 20:47:36 -0000
@@ -47,7 +47,6 @@
 #include "datatypes.h"
 #include "xml.h"
 #include "nodeinfo.h"
-#include "pci.h"
 
 #define VIR_FROM_THIS VIR_FROM_QEMU
 
@@ -1395,52 +1394,7 @@ int qemudBuildCommandLine(virConnectPtr 
             ADD_ARG_LIT("-pcidevice");
             ADD_ARG_LIT(pcidev);
             VIR_FREE(pcidev);
-
-            if (hostdev->managed) {
-                pciDevice *dev = pciGetDevice(conn,
-                                              hostdev->source.subsys.u.pci.domain,
-                                              hostdev->source.subsys.u.pci.bus,
-                                              hostdev->source.subsys.u.pci.slot,
-                                              hostdev->source.subsys.u.pci.function);
-                if (!dev)
-                    goto error;
-
-                if (pciDettachDevice(conn, dev) < 0) {
-                    pciFreeDevice(conn, dev);
-                    goto error;
-                }
-
-                pciFreeDevice(conn, dev);
-            } /* else {
-                XXX validate that non-managed device isn't in use, eg
-                by checking that device is either un-bound, or bound
-                to pci-stub.ko
-            } */
         }
-
-    }
-
-    /* Now that all the PCI hostdevs have be dettached, we can reset them */
-    for (i = 0 ; i < vm->def->nhostdevs ; i++) {
-        virDomainHostdevDefPtr hostdev = vm->def->hostdevs[i];
-        pciDevice *dev;
-
-        if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS ||
-            hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI)
-            continue;
-
-        dev = pciGetDevice(conn,
-                           hostdev->source.subsys.u.pci.domain,
-                           hostdev->source.subsys.u.pci.bus,
-                           hostdev->source.subsys.u.pci.slot,
-                           hostdev->source.subsys.u.pci.function);
-        if (!dev)
-            goto error;
-
-        if (pciResetDevice(conn, dev) < 0)
-            goto error;
-
-        pciFreeDevice(conn, dev);
     }
 
     if (migrateFrom) {
Index: src/qemu_driver.c
===================================================================
RCS file: /data/cvs/libvirt/src/qemu_driver.c,v
retrieving revision 1.208
diff -u -p -u -p -r1.208 qemu_driver.c
--- src/qemu_driver.c	2 Mar 2009 17:39:43 -0000	1.208
+++ src/qemu_driver.c	2 Mar 2009 20:47:36 -0000
@@ -1133,6 +1133,79 @@ static int qemudNextFreeVNCPort(struct q
     return -1;
 }
 
+static int qemuPrepareHostDevices(virConnectPtr conn,
+                                  virDomainDefPtr def) {
+    int i;
+
+    /* We have to use 2 loops here. *All* devices must
+     * be detached before we reset any of them, because
+     * in some cases you have to reset the whole PCI bus,
+     * which impacts all devices on it
+     */
+
+    for (i = 0 ; i < def->nhostdevs ; i++) {
+        virDomainHostdevDefPtr hostdev = def->hostdevs[i];
+
+        if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
+            continue;
+        if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI)
+            continue;
+
+        if (!hostdev->managed) {
+            pciDevice *dev = pciGetDevice(conn,
+                                          hostdev->source.subsys.u.pci.domain,
+                                          hostdev->source.subsys.u.pci.bus,
+                                          hostdev->source.subsys.u.pci.slot,
+                                          hostdev->source.subsys.u.pci.function);
+            if (!dev)
+                goto error;
+
+            if (pciDettachDevice(conn, dev) < 0) {
+                pciFreeDevice(conn, dev);
+                goto error;
+            }
+
+            pciFreeDevice(conn, dev);
+        } /* else {
+             XXX validate that non-managed device isn't in use, eg
+             by checking that device is either un-bound, or bound
+             to pci-stub.ko
+        } */
+    }
+
+    /* Now that all the PCI hostdevs have be dettached, we can safely
+     * reset them */
+    for (i = 0 ; i < def->nhostdevs ; i++) {
+        virDomainHostdevDefPtr hostdev = def->hostdevs[i];
+        pciDevice *dev;
+
+        if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
+            continue;
+        if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI)
+            continue;
+
+        dev = pciGetDevice(conn,
+                           hostdev->source.subsys.u.pci.domain,
+                           hostdev->source.subsys.u.pci.bus,
+                           hostdev->source.subsys.u.pci.slot,
+                           hostdev->source.subsys.u.pci.function);
+        if (!dev)
+            goto error;
+
+        if (pciResetDevice(conn, dev) < 0) {
+            pciFreeDevice(conn, dev);
+            goto error;
+        }
+
+        pciFreeDevice(conn, dev);
+    }
+
+    return 0;
+
+error:
+    return -1;
+}
+
 static virDomainPtr qemudDomainLookupByName(virConnectPtr conn,
                                             const char *name);
 
@@ -1210,6 +1283,9 @@ static int qemudStartVMDaemon(virConnect
         return -1;
     }
 
+    if (qemuPrepareHostDevices(conn, vm->def) < 0)
+        return -1;
+
     vm->def->id = driver->nextvmid++;
     if (qemudBuildCommandLine(conn, driver, vm,
                               qemuCmdFlags, &argv, &progenv,


-- 
|: Red Hat, Engineering, London   -o-   http://people.redhat.com/berrange/ :|
|: http://libvirt.org  -o-  http://virt-manager.org  -o-  http://ovirt.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505  -o-  F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|




More information about the libvir-list mailing list