<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">2014-02-17 23:26 GMT+08:00 Laine Stump <span dir="ltr"><<a href="mailto:laine@laine.org" target="_blank">laine@laine.org</a>></span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="HOEnZb"><div class="h5">On 02/17/2014 11:38 AM, Cedric Bosdonnat wrote:<br>
> On Mon, 2014-02-17 at 14:32 +0800, Chunyan Liu wrote:<br>
>> For extracting hostdev codes from qemu_hostdev.c to common library, change<br>
>> original paring VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT in hostdev function to<br>
>> qemuDomainDeviceDefPostParse.<br>
> typo: paring -> parsing.<br>
><br>
>> Signed-off-by: Chunyan Liu <<a href="mailto:cyliu@suse.com">cyliu@suse.com</a>><br>
>> ---<br>
>> src/qemu/qemu_domain.c | 22 +++++++++++++++<br>
>> src/qemu/qemu_hostdev.c | 28 +++-----------------<br>
>> src/qemu/qemu_hostdev.h | 2 -<br>
>> src/qemu/qemu_hotplug.c | 2 +-<br>
>> src/qemu/qemu_process.c | 3 +-<br>
>> .../qemuxml2argv-hostdev-pci-address.xml | 1 +<br>
>> .../qemuxml2argvdata/qemuxml2argv-net-hostdev.xml | 1 +<br>
>> tests/qemuxml2argvdata/qemuxml2argv-pci-rom.xml | 2 +<br>
>> 8 files changed, 32 insertions(+), 29 deletions(-)<br>
>><br>
>> diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c<br>
>> index a665061..55e707e 100644<br>
>> --- a/src/qemu/qemu_domain.c<br>
>> +++ b/src/qemu/qemu_domain.c<br>
>> @@ -38,6 +38,7 @@<br>
>> #include "virtime.h"<br>
>> #include "virstoragefile.h"<br>
>> #include "virstring.h"<br>
>> +#include "qemu_hostdev.h"<br>
>><br>
>> #include <sys/time.h><br>
>> #include <fcntl.h><br>
>> @@ -821,6 +822,7 @@ qemuDomainDeviceDefPostParse(virDomainDeviceDefPtr dev,<br>
>> int ret = -1;<br>
>> virQEMUDriverPtr driver = opaque;<br>
>> virQEMUDriverConfigPtr cfg = NULL;<br>
>> + virQEMUCapsPtr qemuCaps = NULL;<br>
>><br>
>> if (dev->type == VIR_DOMAIN_DEVICE_NET &&<br>
>> dev->data.net->type != VIR_DOMAIN_NET_TYPE_HOSTDEV &&<br>
>> @@ -899,6 +901,26 @@ qemuDomainDeviceDefPostParse(virDomainDeviceDefPtr dev,<br>
>> dev->data.chr->source.data.nix.listen = true;<br>
>> }<br>
>><br>
>> + if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV) {<br>
>> + virDomainHostdevDefPtr hostdev = dev->data.hostdev;<br>
>> + if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&<br>
>> + hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI &&<br>
>> + hostdev->source.subsys.u.pci.backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT) {<br>
>> +<br>
>> + hostdev->source.subsys.u.pci.backend = VIR_DOMAIN_HOSTDEV_PCI_BACKEND_KVM;<br>
>> + if (driver && driver->qemuCapsCache) {<br>
>> + bool supportsPassthroughVFIO = qemuHostdevHostSupportsPassthroughVFIO();<br>
>> + qemuCaps = virQEMUCapsCacheLookupCopy(driver->qemuCapsCache,<br>
>> + def->emulator);<br>
>> + if (supportsPassthroughVFIO && qemuCaps &&<br>
>> + virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VFIO_PCI))<br>
>> + hostdev->source.subsys.u.pci.backend = VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO;<br>
>> +<br>
>> + virObjectUnref(qemuCaps);<br>
>> + }<br>
>> + }<br>
>> + }<br>
>> +<br>
>> ret = 0;<br>
> KVM passthrough support isn't checked here but was checked in the<br>
> removed code, is that intended?<br>
<br>
</div></div>The fact that the code doing the KVM check is fairly new, suggests to me<br>
that this omission *wasn't* intentional. I'm really glad that you're<br>
looking at that in detail, because it's the potential omission of recent<br>
bugfixes that has me nervous.<br>
<br>
Beyond that, this isn't the proper place to be moving this to - anything<br>
that is done by the PostParse callback function ends up being written to<br>
persistent config and is there effectively forever, but the<br>
interpretation of the hostdev driver "default" backend is something that<br>
must be re-done exactly at the moment the device it going to be<br>
attached. This patch instead causes that decision to be made when the<br>
domain is defined, and forever encoded in the config.<br>
<br>
I think that instead you need to either call it from<br>
qemuPrepareHostDevices() and qemuDomainAttachHostPciDevice(), OR send a<br>
callback function pointer into your new virHostdevPreparePciHostdevs(),<br>
with that function returning the "backend to use this time" based on the<br>
config setting and current system state.<br>
<div><div class="h5"><br></div></div></blockquote><div> </div><div>Thanks for explanation. Will correct that.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div><div class="h5">
<br>
>> cleanup:<br>
>> diff --git a/src/qemu/qemu_hostdev.c b/src/qemu/qemu_hostdev.c<br>
>> index ce5012d..80552cd 100644<br>
>> --- a/src/qemu/qemu_hostdev.c<br>
>> +++ b/src/qemu/qemu_hostdev.c<br>
>> @@ -583,8 +583,7 @@ qemuHostdevHostSupportsPassthroughLegacy(void)<br>
>><br>
>> static bool<br>
>> qemuPrepareHostdevPCICheckSupport(virDomainHostdevDefPtr *hostdevs,<br>
>> - size_t nhostdevs,<br>
>> - virQEMUCapsPtr qemuCaps)<br>
>> + size_t nhostdevs)<br>
>> {<br>
>> bool supportsPassthroughKVM = qemuHostdevHostSupportsPassthroughLegacy();<br>
>> bool supportsPassthroughVFIO = qemuHostdevHostSupportsPassthroughVFIO();<br>
>> @@ -601,23 +600,6 @@ qemuPrepareHostdevPCICheckSupport(virDomainHostdevDefPtr *hostdevs,<br>
>> continue;<br>
>><br>
>> switch ((virDomainHostdevSubsysPciBackendType) *backend) {<br>
>> - case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT:<br>
>> - if (supportsPassthroughVFIO &&<br>
>> - virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VFIO_PCI)) {<br>
>> - *backend = VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO;<br>
>> - } else if (supportsPassthroughKVM &&<br>
>> - (virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCIDEVICE) ||<br>
>> - virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE))) {<br>
>> - *backend = VIR_DOMAIN_HOSTDEV_PCI_BACKEND_KVM;<br>
>> - } else {<br>
>> - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",<br>
>> - _("host doesn't support passthrough of "<br>
>> - "host PCI devices"));<br>
>> - return false;<br>
>> - }<br>
>> -<br>
>> - break;<br>
>> -<br>
>> case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO:<br>
>> if (!supportsPassthroughVFIO) {<br>
>> virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",<br>
>> @@ -635,7 +617,7 @@ qemuPrepareHostdevPCICheckSupport(virDomainHostdevDefPtr *hostdevs,<br>
>><br>
>> break;<br>
>><br>
>> - case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_LAST:<br>
>> + default:<br>
<br>
<br>
</div></div>I'm pretty sure that Peter intentionally *didn't* put a default case<br>
into this switch (and many others) specifically so that somebody adding<br>
a new enum value would get compiler errors telling them all the places<br>
they needed to handle the new case, i.e. please do not replace "case<br>
VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_LAST" with "default".<br>
<div><div class="h5"><br>
<br>
>> break;<br>
>> }<br>
>> }<br>
>> @@ -650,7 +632,6 @@ qemuPrepareHostdevPCIDevices(virQEMUDriverPtr driver,<br>
>> const unsigned char *uuid,<br>
>> virDomainHostdevDefPtr *hostdevs,<br>
>> int nhostdevs,<br>
>> - virQEMUCapsPtr qemuCaps,<br>
>> unsigned int flags)<br>
>> {<br>
>> virPCIDeviceListPtr pcidevs = NULL;<br>
>> @@ -659,7 +640,7 @@ qemuPrepareHostdevPCIDevices(virQEMUDriverPtr driver,<br>
>> int ret = -1;<br>
>> virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);<br>
>><br>
>> - if (!qemuPrepareHostdevPCICheckSupport(hostdevs, nhostdevs, qemuCaps))<br>
>> + if (!qemuPrepareHostdevPCICheckSupport(hostdevs, nhostdevs))<br>
>> goto cleanup;<br>
>><br>
>> virObjectLock(driver->activePciHostdevs);<br>
>> @@ -1189,7 +1170,6 @@ cleanup:<br>
>> int<br>
>> qemuPrepareHostDevices(virQEMUDriverPtr driver,<br>
>> virDomainDefPtr def,<br>
>> - virQEMUCapsPtr qemuCaps,<br>
>> unsigned int flags)<br>
>> {<br>
>> if (!def->nhostdevs)<br>
>> @@ -1197,7 +1177,7 @@ qemuPrepareHostDevices(virQEMUDriverPtr driver,<br>
>><br>
>> if (qemuPrepareHostdevPCIDevices(driver, def->name, def->uuid,<br>
>> def->hostdevs, def->nhostdevs,<br>
>> - qemuCaps, flags) < 0)<br>
>> + flags) < 0)<br>
>> return -1;<br>
>><br>
>> if (qemuPrepareHostUSBDevices(driver, def, flags) < 0)<br>
>> diff --git a/src/qemu/qemu_hostdev.h b/src/qemu/qemu_hostdev.h<br>
>> index 710867d..128032d 100644<br>
>> --- a/src/qemu/qemu_hostdev.h<br>
>> +++ b/src/qemu/qemu_hostdev.h<br>
>> @@ -45,7 +45,6 @@ int qemuPrepareHostdevPCIDevices(virQEMUDriverPtr driver,<br>
>> const unsigned char *uuid,<br>
>> virDomainHostdevDefPtr *hostdevs,<br>
>> int nhostdevs,<br>
>> - virQEMUCapsPtr qemuCaps,<br>
>> unsigned int flags);<br>
>> int qemuFindHostdevUSBDevice(virDomainHostdevDefPtr hostdev,<br>
>> bool mandatory,<br>
>> @@ -59,7 +58,6 @@ int qemuPrepareHostdevSCSIDevices(virQEMUDriverPtr driver,<br>
>> int nhostdevs);<br>
>> int qemuPrepareHostDevices(virQEMUDriverPtr driver,<br>
>> virDomainDefPtr def,<br>
>> - virQEMUCapsPtr qemuCaps,<br>
>> unsigned int flags);<br>
>> void qemuDomainReAttachHostScsiDevices(virQEMUDriverPtr driver,<br>
>> const char *name,<br>
>> diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c<br>
>> index c47c5e8..8486f25 100644<br>
>> --- a/src/qemu/qemu_hotplug.c<br>
>> +++ b/src/qemu/qemu_hotplug.c<br>
>> @@ -1163,7 +1163,7 @@ qemuDomainAttachHostPciDevice(virQEMUDriverPtr driver,<br>
>> if (!cfg->relaxedACS)<br>
>> flags |= VIR_STRICT_ACS_CHECK;<br>
>> if (qemuPrepareHostdevPCIDevices(driver, vm->def->name, vm->def->uuid,<br>
>> - &hostdev, 1, priv->qemuCaps, flags) < 0)<br>
>> + &hostdev, 1, flags) < 0)<br>
>> return -1;<br>
>><br>
>> /* this could have been changed by qemuPrepareHostdevPCIDevices */<br>
>> diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c<br>
>> index f1fe35e..e938649 100644<br>
>> --- a/src/qemu/qemu_process.c<br>
>> +++ b/src/qemu/qemu_process.c<br>
>> @@ -3690,8 +3690,7 @@ int qemuProcessStart(virConnectPtr conn,<br>
>> hostdev_flags |= VIR_STRICT_ACS_CHECK;<br>
>> if (!migrateFrom)<br>
>> hostdev_flags |= VIR_COLD_BOOT;<br>
>> - if (qemuPrepareHostDevices(driver, vm->def, priv->qemuCaps,<br>
>> - hostdev_flags) < 0)<br>
>> + if (qemuPrepareHostDevices(driver, vm->def, hostdev_flags) < 0)<br>
>> goto cleanup;<br>
>><br>
>> VIR_DEBUG("Preparing chr devices");<br>
>> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-address.xml b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-address.xml<br>
>> index 422127c..b9a221a 100644<br>
>> --- a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-address.xml<br>
>> +++ b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-address.xml<br>
>> @@ -24,6 +24,7 @@<br>
>> <controller type='ide' index='0'/><br>
>> <controller type='pci' index='0' model='pci-root'/><br>
>> <hostdev mode='subsystem' type='pci' managed='yes'><br>
>> + <driver name='kvm'/><br>
>> <source><br>
>> <address domain='0x0000' bus='0x06' slot='0x12' function='0x5'/><br>
>> </source><br>
>> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-net-hostdev.xml b/tests/qemuxml2argvdata/qemuxml2argv-net-hostdev.xml<br>
>> index d65ef87..9e79348 100644<br>
>> --- a/tests/qemuxml2argvdata/qemuxml2argv-net-hostdev.xml<br>
>> +++ b/tests/qemuxml2argvdata/qemuxml2argv-net-hostdev.xml<br>
>> @@ -24,6 +24,7 @@<br>
>> <controller type='pci' index='0' model='pci-root'/><br>
>> <interface type='hostdev' managed='yes'><br>
>> <mac address='00:11:22:33:44:55'/><br>
>> + <driver name='kvm'/><br>
>> <source><br>
>> <address type='pci' domain='0x0002' bus='0x03' slot='0x07' function='0x1'/><br>
>> </source><br>
>> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-pci-rom.xml b/tests/qemuxml2argvdata/qemuxml2argv-pci-rom.xml<br>
>> index a5e59b2..924842b 100644<br>
>> --- a/tests/qemuxml2argvdata/qemuxml2argv-pci-rom.xml<br>
>> +++ b/tests/qemuxml2argvdata/qemuxml2argv-pci-rom.xml<br>
>> @@ -33,12 +33,14 @@<br>
>> <rom file='/etc/fake/bootrom.bin'/><br>
>> </interface><br>
>> <hostdev mode='subsystem' type='pci' managed='yes'><br>
>> + <driver name='kvm'/><br>
>> <source><br>
>> <address domain='0x0000' bus='0x06' slot='0x12' function='0x5'/><br>
>> </source><br>
>> <rom bar='off'/><br>
>> </hostdev><br>
>> <hostdev mode='subsystem' type='pci' managed='yes'><br>
>> + <driver name='kvm'/><br>
>> <source><br>
>> <address domain='0x0000' bus='0x06' slot='0x12' function='0x6'/><br>
>> </source><br>
> Can't those hostdev definitions keep the default backend like before?<br>
<br>
</div></div>A changes in the test case is sometimes correct, but should be<br>
considered a red flag. My first guest would be that it was necessary due<br>
to the code that was added to the PostParse function (i.e. it's<br>
indicating a problem)<br>
<br>
<br>
</blockquote></div><br></div></div>