[libvirt] [PATCH v2 3/6] pci: Introduce virPCIStubDriver enumeration

Michal Privoznik mprivozn at redhat.com
Fri Dec 18 12:05:21 UTC 2015


On 17.12.2015 18:59, Andrea Bolognani wrote:
> This replaces the virPCIKnownStubs string array that was used
> internally for stub driver validation.
> 
> Advantages:
> 
>   * possible values are well-defined
>   * typos in driver names will be detected at compile time
>   * avoids having several copies of the same string around
>   * no error checking required when setting / getting value
> 
> The names used mirror those in the
> virDomainHostdevSubsysPCIBackendType enumeration.
> ---
> Changes in v2:
> 
>   * add VIR_PCI_STUB_DRIVER_NONE so we can detect when no driver has
>     been configured for a specific device
>   * simplify code in testVirPCIDeviceDetachFail() by not reading the
>     driver back from the device, since we set it a few lines above
> 
> testVirPCIDeviceDetachFail
>  src/libvirt_private.syms |  2 ++
>  src/libxl/libxl_driver.c |  3 +-
>  src/qemu/qemu_driver.c   |  6 ++--
>  src/util/virhostdev.c    | 45 +++++++++----------------
>  src/util/virpci.c        | 86 +++++++++++++++++++++++++++---------------------
>  src/util/virpci.h        | 17 +++++++---
>  src/xen/xen_driver.c     |  3 +-
>  tests/virhostdevtest.c   |  5 +--
>  tests/virpcitest.c       | 23 ++++++-------
>  9 files changed, 99 insertions(+), 91 deletions(-)
> 


> diff --git a/src/util/virhostdev.c b/src/util/virhostdev.c
> index 4065535..f9072a4 100644
> --- a/src/util/virhostdev.c
> +++ b/src/util/virhostdev.c
> @@ -237,22 +237,13 @@ virHostdevGetPCIHostDeviceList(virDomainHostdevDefPtr *hostdevs, int nhostdevs)
>          }
>  
>          virPCIDeviceSetManaged(dev, hostdev->managed);
> -        if (pcisrc->backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO) {
> -            if (virPCIDeviceSetStubDriver(dev, "vfio-pci") < 0) {
> -                virObjectUnref(list);
> -                return NULL;
> -            }
> -        } else if (pcisrc->backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_XEN) {
> -            if (virPCIDeviceSetStubDriver(dev, "pciback") < 0) {
> -                virObjectUnref(list);
> -                return NULL;
> -            }
> -        } else {
> -            if (virPCIDeviceSetStubDriver(dev, "pci-stub") < 0) {
> -                virObjectUnref(list);
> -                return NULL;
> -            }
> -        }
> +
> +        if (pcisrc->backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO)
> +            virPCIDeviceSetStubDriver(dev, VIR_PCI_STUB_DRIVER_VFIO);
> +        else if (pcisrc->backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_XEN)
> +            virPCIDeviceSetStubDriver(dev, VIR_PCI_STUB_DRIVER_XEN);
> +        else
> +            virPCIDeviceSetStubDriver(dev, VIR_PCI_STUB_DRIVER_KVM);
>      }
>  
>      return list;
> @@ -574,7 +565,7 @@ virHostdevPreparePCIDevices(virHostdevManagerPtr hostdev_mgr,
>      for (i = 0; i < virPCIDeviceListCount(pcidevs); i++) {
>          virPCIDevicePtr dev = virPCIDeviceListGet(pcidevs, i);
>          bool strict_acs_check = !!(flags & VIR_HOSTDEV_STRICT_ACS_CHECK);
> -        bool usesVfio = STREQ(virPCIDeviceGetStubDriver(dev), "vfio-pci");
> +        bool usesVfio = (virPCIDeviceGetStubDriver(dev) == VIR_PCI_STUB_DRIVER_VFIO);

I believe these braces are redundant. But do not hurt either.

>          struct virHostdevIsPCINodeDeviceUsedData data = {hostdev_mgr, dom_name,
>                                                           usesVfio};
>  
> @@ -745,7 +736,7 @@ virHostdevReattachPCIDevice(virPCIDevicePtr dev, virHostdevManagerPtr mgr)
>      }
>  
>      /* Wait for device cleanup if it is qemu/kvm */
> -    if (STREQ(virPCIDeviceGetStubDriver(dev), "pci-stub")) {
> +    if (virPCIDeviceGetStubDriver(dev) == VIR_PCI_STUB_DRIVER_KVM) {
>          int retries = 100;
>          while (virPCIDeviceWaitForCleanup(dev, "kvm_assigned_device")
>                 && retries) {
> @@ -913,19 +904,15 @@ virHostdevUpdateActivePCIDevices(virHostdevManagerPtr mgr,
>              goto cleanup;
>  
>          virPCIDeviceSetManaged(dev, hostdev->managed);
> -        if (pcisrc->backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO) {
> -            if (virPCIDeviceSetStubDriver(dev, "vfio-pci") < 0)
> -                goto cleanup;
> -        } else if (pcisrc->backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_XEN) {
> -            if (virPCIDeviceSetStubDriver(dev, "pciback") < 0)
> -                goto cleanup;
> -        } else {
> -            if (virPCIDeviceSetStubDriver(dev, "pci-stub") < 0)
> -                goto cleanup;
> -
> -        }
>          virPCIDeviceSetUsedBy(dev, drv_name, dom_name);
>  
> +        if (pcisrc->backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO)
> +            virPCIDeviceSetStubDriver(dev, VIR_PCI_STUB_DRIVER_VFIO);
> +        else if (pcisrc->backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_XEN)
> +            virPCIDeviceSetStubDriver(dev, VIR_PCI_STUB_DRIVER_XEN);
> +        else
> +            virPCIDeviceSetStubDriver(dev, VIR_PCI_STUB_DRIVER_KVM);
> +
>          /* Setup the original states for the PCI device */
>          virPCIDeviceSetUnbindFromStub(dev, hostdev->origstates.states.pci.unbind_from_stub);
>          virPCIDeviceSetRemoveSlot(dev, hostdev->origstates.states.pci.remove_slot);
> diff --git a/src/util/virpci.c b/src/util/virpci.c
> index 21eacf5..aec7b69 100644
> --- a/src/util/virpci.c
> +++ b/src/util/virpci.c
> @@ -55,6 +55,13 @@ VIR_LOG_INIT("util.pci");
>  VIR_ENUM_IMPL(virPCIELinkSpeed, VIR_PCIE_LINK_SPEED_LAST,
>                "", "2.5", "5", "8")
>  
> +VIR_ENUM_IMPL(virPCIStubDriver, VIR_PCI_STUB_DRIVER_LAST,
> +              "none",
> +              "pciback", /* XEN */
> +              "pci-stub", /* KVM */
> +              "vfio-pci", /* VFIO */
> +);
> +
>  struct _virPCIDevice {
>      virPCIDeviceAddress address;
>  
> @@ -71,7 +78,8 @@ struct _virPCIDevice {
>      bool          has_flr;
>      bool          has_pm_reset;
>      bool          managed;
> -    char          *stubDriver;
> +
> +    virPCIStubDriver stubDriver;
>  
>      /* used by reattach function */
>      bool          unbind_from_stub;
> @@ -941,7 +949,7 @@ virPCIDeviceReset(virPCIDevicePtr dev,
>      if (virPCIDeviceGetDriverPathAndName(dev, &drvPath, &drvName) < 0)
>          goto cleanup;
>  
> -    if (STREQ_NULLABLE(drvName, "vfio-pci")) {
> +    if (virPCIStubDriverTypeFromString(drvName) == VIR_PCI_STUB_DRIVER_VFIO) {
>          VIR_DEBUG("Device %s is bound to vfio-pci - skip reset",
>                    dev->name);
>          ret = 0;
> @@ -992,13 +1000,22 @@ virPCIDeviceReset(virPCIDevicePtr dev,
>  
>  
>  static int
> -virPCIProbeStubDriver(const char *driver)
> +virPCIProbeStubDriver(virPCIStubDriver driver)
>  {
> +    const char *drvname = NULL;
>      char *drvpath = NULL;
>      bool probed = false;
>  
> +    if (!(drvname = virPCIStubDriverTypeToString(driver)) ||
> +        driver == VIR_PCI_STUB_DRIVER_NONE) {
> +        virReportError(VIR_ERR_INTERNAL_ERROR,
> +                       "%s",
> +                       _("Attempting to use unknown stub driver"));
> +        return -1;
> +    }

Hm. Interesting, I thought that checking for TypeToString(driver) would
be useless, since we are passing an enum into the function. But
apparently I was wrong since the following code does not throw any error
whatsoever:

virPCIProbeStubDriver(20);

So I guess it's a good idea to have it there. Also, this brings up an
interesting question - should we check for other TypeToString() return
values too? e.g. like we do in virCPUDefFormatBuf().

> +
>   recheck:
> -    if ((drvpath = virPCIDriverDir(driver)) && virFileExists(drvpath)) {
> +    if ((drvpath = virPCIDriverDir(drvname)) && virFileExists(drvpath)) {
>          /* driver already loaded, return */
>          VIR_FREE(drvpath);
>          return 0;


ACK

Michal




More information about the libvir-list mailing list