[libvirt] PATCH: Don't reset / detach host PCI devices in test scripts !
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 :|
On Mon, Mar 02, 2009 at 08:51:01PM +0000, Daniel P. Berrange wrote:
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.
Oops, ACK ! Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/
On Mon, Mar 02, 2009 at 09:56:04PM +0100, Daniel Veillard wrote:
On Mon, Mar 02, 2009 at 08:51:01PM +0000, Daniel P. Berrange wrote:
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.
Oops, ACK !
ok, committed this since it was breaking the test suite Daniel -- |: 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 :|
Daniel P. Berrange wrote:
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.
Ah. This fixes the failure I just reported. Looks good.
+ /* Now that all the PCI hostdevs have be dettached, we can safely
Obviously this is just "moved" code, but might as well fix the comment: s/be/been/
+ * 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);
You can remove a duplicate free and save two lines by replacing the above with this: int err = pciResetDevice(conn, dev); pciFreeDevice(conn, dev); if (err < 0) goto error;
+ } + + return 0; + +error: + return -1; +}
This change: Tue Mar 3 08:55:13 GMT 2009 Daniel P. Berrange <berrange@redhat.com> Don't try to detach & reset PCI devices while running test suite for XML-> ARGV conversion. * src/qemu_driver.c: Add qemuPrepareHostDevices() helper to detach and reset PCI devices. * src/qemu_conf.c: Don't detach & reset PCI devices while building the command line argv accidentally did this: - if (hostdev->managed) { + if (!hostdev->managed) { Which results in managed='yes' not causing the device to be detached when the guest is starting. Signed-off-by: Mark McLoughlin <markmc@redhat.com> --- src/qemu_driver.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/src/qemu_driver.c b/src/qemu_driver.c index 5898026..59312c0 100644 --- a/src/qemu_driver.c +++ b/src/qemu_driver.c @@ -1215,7 +1215,7 @@ static int qemuPrepareHostDevices(virConnectPtr conn, if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) continue; - if (!hostdev->managed) { + if (hostdev->managed) { pciDevice *dev = pciGetDevice(conn, hostdev->source.subsys.u.pci.domain, hostdev->source.subsys.u.pci.bus, -- 1.6.0.6
On Wed, May 06, 2009 at 04:39:05PM +0100, Mark McLoughlin wrote:
This change:
Tue Mar 3 08:55:13 GMT 2009 Daniel P. Berrange <berrange@redhat.com>
Don't try to detach & reset PCI devices while running test suite for XML-> ARGV conversion. * src/qemu_driver.c: Add qemuPrepareHostDevices() helper to detach and reset PCI devices. * src/qemu_conf.c: Don't detach & reset PCI devices while building the command line argv
accidentally did this:
- if (hostdev->managed) { + if (!hostdev->managed) {
Which results in managed='yes' not causing the device to be detached when the guest is starting.
ACK Daniel -- |: 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 :|
participants (4)
-
Daniel P. Berrange -
Daniel Veillard -
Jim Meyering -
Mark McLoughlin