]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
conf: new function virDomainPCIAddressSetAllMulti()
authorLaine Stump <laine@laine.org>
Tue, 10 Jan 2017 05:02:40 +0000 (00:02 -0500)
committerLaine Stump <laine@laine.org>
Wed, 11 Jan 2017 09:40:24 +0000 (04:40 -0500)
This utility function iterates through all devices looking for any
with a PCI address that has function != 0 (which implies that multiple
functions are in use on that slot), then uses an inner iterator to
find the device that's on function 0 of that same slot and sets the
"multi" in its virDomainDeviceInfo (as long as it hasn't already been
set explicitly by someone who presumably has better information than
we do).

It isn't yet called from anywhere, so will have no functional effect.

src/conf/domain_addr.c
src/conf/domain_addr.h
src/libvirt_private.syms

index 4d14ac495328deef78594e0965c4044a897fc18b..1f6ff7a26a16dbcecb245f8a567a96f23f0b1e49 100644 (file)
@@ -867,6 +867,89 @@ virDomainPCIAddressReserveNextSlot(virDomainPCIAddressSetPtr addrs,
 }
 
 
+static int
+virDomainPCIAddressSetMultiIter(virDomainDefPtr def ATTRIBUTE_UNUSED,
+                                virDomainDeviceDefPtr dev ATTRIBUTE_UNUSED,
+                                virDomainDeviceInfoPtr info,
+                                void *data)
+{
+    virPCIDeviceAddressPtr testAddr = data;
+    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 == 0) {
+
+        /* only set to ON if it wasn't previously set
+         * (assuming that the user must have better information
+         * than us if they explicitly set it OFF)
+         */
+        if (thisAddr->multi == VIR_TRISTATE_SWITCH_ABSENT)
+            thisAddr->multi = VIR_TRISTATE_SWITCH_ON;
+
+        return -1; /* finish early, *NOT* an error */
+    }
+
+    return 0;
+}
+
+
+static int
+virDomainPCIAddressSetAllMultiIter(virDomainDefPtr def,
+                                   virDomainDeviceDefPtr dev ATTRIBUTE_UNUSED,
+                                   virDomainDeviceInfoPtr info,
+                                   void *data ATTRIBUTE_UNUSED)
+{
+    virPCIDeviceAddressPtr testAddr;
+
+    if (!info || info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI)
+       return 0;
+
+    testAddr = &info->addr.pci;
+
+    if (testAddr->function != 0) {
+        ignore_value(virDomainDeviceInfoIterate(def,
+                                                virDomainPCIAddressSetMultiIter,
+                                                testAddr));
+    }
+
+    return 0;
+}
+
+
+/**
+ * virDomainPCIAddressSetAllMulti():
+ *
+ * @def: the domain definition whose devices may need adjusting
+ * @addrs: address set keeping track of all addresses in use.
+ *
+ * Look for any PCI slots that have multiple functions assigned, and
+ * set multi to ON in the address for the device at function 0
+ * (unless it has been explicitly set to OFF).
+ *
+ * No return code, since there is no possibility of failure.
+ */
+void
+virDomainPCIAddressSetAllMulti(virDomainDefPtr def)
+{
+    /* Use nested iterators over all the devices - the outer iterator
+     * scans through all the devices looking for those whose address
+     * has a non-0 function; when one is found, the inner iterator looks
+     * for the device that uses function 0 on the same slot and marks
+     * it as multi = ON
+     */
+    ignore_value(virDomainDeviceInfoIterate(def,
+                                            virDomainPCIAddressSetAllMultiIter,
+                                            NULL));
+}
+
+
 static char*
 virDomainCCWAddressAsString(virDomainDeviceCCWAddressPtr addr)
 {
index 5f0924e4188e616fc13aa916a6e3f27796201213..c728c009b9361dd285a6e9f9c6610f5a144f610f 100644 (file)
@@ -173,6 +173,9 @@ int virDomainPCIAddressReserveNextSlot(virDomainPCIAddressSetPtr addrs,
                                        virDomainPCIConnectFlags flags)
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
 
+void virDomainPCIAddressSetAllMulti(virDomainDefPtr def)
+    ATTRIBUTE_NONNULL(1);
+
 struct _virDomainCCWAddressSet {
     virHashTablePtr defined;
     virDomainDeviceCCWAddress next;
index 4d16620b4e30c3a174bd4f6f08f7c8148e8aa62f..4d2f85cc3da4466e48d19749a54fe0530bbb816d 100644 (file)
@@ -104,6 +104,7 @@ virDomainPCIAddressReserveAddr;
 virDomainPCIAddressReserveNextAddr;
 virDomainPCIAddressReserveNextSlot;
 virDomainPCIAddressReserveSlot;
+virDomainPCIAddressSetAllMulti;
 virDomainPCIAddressSetAlloc;
 virDomainPCIAddressSetFree;
 virDomainPCIAddressSetGrow;