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 :| -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list