[PATCH v3 5/8] conf: new function virDomainPCIAddressIsMulti()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This function iterates through all the devices in a domain to
determine if the address it has been given is part of a "multifunction
device" (i.e. multiple devices connected to different functions of the
same slot).

This implementation may seem a bit inefficient because it has to
iterate through all the devices for each device that needs checking,
but this really is our only option since the address allocation set
isn't always available (and maybe not even exist at the time it's
needed).
---
 src/conf/domain_addr.c   | 60 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/conf/domain_addr.h   |  5 ++++
 src/libvirt_private.syms |  1 +
 3 files changed, 66 insertions(+)

diff --git a/src/conf/domain_addr.c b/src/conf/domain_addr.c
index 8cc30ee..b8a91d2 100644
--- a/src/conf/domain_addr.c
+++ b/src/conf/domain_addr.c
@@ -867,6 +867,66 @@ virDomainPCIAddressReserveNextSlot(virDomainPCIAddressSetPtr addrs,
 }
 
 
+typedef struct {
+    virPCIDeviceAddressPtr addr;
+    bool isMulti;
+} virDomainPCIAddressIsMultiIterData;
+
+
+static int
+virDomainPCIAddressIsMultiIter(virDomainDefPtr def ATTRIBUTE_UNUSED,
+                               virDomainDeviceDefPtr dev ATTRIBUTE_UNUSED,
+                               virDomainDeviceInfoPtr info,
+                               void *data)
+{
+    virDomainPCIAddressIsMultiIterData *context = data;
+    virPCIDeviceAddressPtr testAddr = context->addr;
+    virPCIDeviceAddressPtr thisAddr;
+
+    if (!info || info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI)
+       return 0;
+
+    thisAddr = &info->addr.pci;
+
+    if (thisAddr->domain == testAddr->domain &&
+        thisAddr->bus == testAddr->bus &&
+        thisAddr->slot == testAddr->slot &&
+        thisAddr->function != testAddr->function) {
+        context->isMulti = true;
+        return -1; /* finish early, *NOT* an error */
+    }
+
+    return 0;
+}
+
+
+/**
+ * virDomainPCIAddressIsMulti():
+ *
+ * @def: the domain definition whose devices need adjusting
+ * @addr: the address to check
+ *
+ * See if there is any PCI device in the domain with the same
+ * domain/bus/slot but different function. If so, then this address is
+ * used by a multifunction device.
+ *
+ * Returns true if the address is being used by multiple devices, else
+ * false.
+ */
+bool
+virDomainPCIAddressIsMulti(const virDomainDef *def,
+                           virPCIDeviceAddressPtr addr)
+{
+    virDomainPCIAddressIsMultiIterData data = { .addr = addr,
+                                                .isMulti = false };
+
+    ignore_value(virDomainDeviceInfoIterate((virDomainDefPtr)def,
+                                            virDomainPCIAddressIsMultiIter,
+                                            &data));
+    return data.isMulti;
+}
+
+
 static char*
 virDomainCCWAddressAsString(virDomainDeviceCCWAddressPtr addr)
 {
diff --git a/src/conf/domain_addr.h b/src/conf/domain_addr.h
index 9c08274..50c4675 100644
--- a/src/conf/domain_addr.h
+++ b/src/conf/domain_addr.h
@@ -173,6 +173,11 @@ int virDomainPCIAddressReserveNextSlot(virDomainPCIAddressSetPtr addrs,
                                        virDomainPCIConnectFlags flags)
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
 
+bool
+virDomainPCIAddressIsMulti(const virDomainDef *def,
+                           virPCIDeviceAddressPtr addr)
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
+
 struct _virDomainCCWAddressSet {
     virHashTablePtr defined;
     virDomainDeviceCCWAddress next;
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 4c0170c..0dd0af5 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -99,6 +99,7 @@ virDomainPCIAddressAsString;
 virDomainPCIAddressBusSetModel;
 virDomainPCIAddressEnsureAddr;
 virDomainPCIAddressFlagsCompatible;
+virDomainPCIAddressIsMulti;
 virDomainPCIAddressReleaseSlot;
 virDomainPCIAddressReserveAddr;
 virDomainPCIAddressReserveNextAddr;
-- 
2.7.4

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list



[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]
  Powered by Linux