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