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