43fe83
From e3be969238c715142642a1429630f2f0bcb5b293 Mon Sep 17 00:00:00 2001
43fe83
Message-Id: <e3be969238c715142642a1429630f2f0bcb5b293.1383922565.git.jdenemar@redhat.com>
43fe83
From: Laine Stump <laine@laine.org>
43fe83
Date: Wed, 6 Nov 2013 04:47:59 -0700
43fe83
Subject: [PATCH] network: fix connections count in case of allocate failure
43fe83
43fe83
This resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1020135
43fe83
43fe83
If networkAllocateActualDevice() had failed due to a pool of hostdev
43fe83
or direct devices being depleted, the calling function could still
43fe83
call networkReleaseActualDevice() as part of its cleanup, and that
43fe83
function would then unconditionally decrement the connections count
43fe83
for the network, even though it hadn't been incremented (due to
43fe83
failure of allocate). This *was* necessary because the .actual member
43fe83
of the netdef was allocated with a "lazy" algorithm, only being
43fe83
created if there was a need to store data there (e.g. if a device was
43fe83
allocated from a pool, or bandwidth was allocated for the device), so
43fe83
there was no simple way for networkReleaseActualDevice() to tell if
43fe83
something really had been allocated (i.e. if "connections++" had been
43fe83
executed).
43fe83
43fe83
This patch changes networkAllocateDevice() to *always* allocate an
43fe83
actual device for any netdef of type='network', even if it isn't
43fe83
needed for any other reason. This has no ill effects anywhere else in
43fe83
the code (except for using a small amount of memory), and
43fe83
networkReleaseActualDevice() can then determine if there was a
43fe83
previous successful allocate by checking for .actual != NULL (if not,
43fe83
it skips the "connections--").
43fe83
43fe83
(cherry picked from commit b4e0299d4ff059c8707a760b7ec2063ccd57cc21)
43fe83
43fe83
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
43fe83
---
43fe83
 src/network/bridge_driver.c | 41 +++++++++++------------------------------
43fe83
 1 file changed, 11 insertions(+), 30 deletions(-)
43fe83
43fe83
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
43fe83
index ea09663..c900478 100644
43fe83
--- a/src/network/bridge_driver.c
43fe83
+++ b/src/network/bridge_driver.c
43fe83
@@ -3841,6 +3841,9 @@ networkAllocateActualDevice(virDomainNetDefPtr iface)
43fe83
     }
43fe83
     netdef = network->def;
43fe83
 
43fe83
+    if (VIR_ALLOC(iface->data.network.actual) < 0)
43fe83
+        goto error;
43fe83
+
43fe83
     /* portgroup can be present for any type of network, in particular
43fe83
      * for bandwidth information, so we need to check for that and
43fe83
      * fill it in appropriately for all forward types.
43fe83
@@ -3857,14 +3860,9 @@ networkAllocateActualDevice(virDomainNetDefPtr iface)
43fe83
     else if (portgroup && portgroup->bandwidth)
43fe83
         bandwidth = portgroup->bandwidth;
43fe83
 
43fe83
-    if (bandwidth) {
43fe83
-        if (!iface->data.network.actual &&
43fe83
-            VIR_ALLOC(iface->data.network.actual) < 0)
43fe83
-            goto error;
43fe83
-        if (virNetDevBandwidthCopy(&iface->data.network.actual->bandwidth,
43fe83
-                                   bandwidth) < 0)
43fe83
-            goto error;
43fe83
-    }
43fe83
+    if (bandwidth && virNetDevBandwidthCopy(&iface->data.network.actual->bandwidth,
43fe83
+                                            bandwidth) < 0)
43fe83
+        goto error;
43fe83
 
43fe83
     /* copy appropriate vlan info to actualNet */
43fe83
     if (iface->vlan.nTags > 0)
43fe83
@@ -3874,13 +3872,8 @@ networkAllocateActualDevice(virDomainNetDefPtr iface)
43fe83
     else if (netdef->vlan.nTags > 0)
43fe83
         vlan = &netdef->vlan;
43fe83
 
43fe83
-    if (vlan) {
43fe83
-        if (!iface->data.network.actual &&
43fe83
-            VIR_ALLOC(iface->data.network.actual) < 0)
43fe83
-            goto error;
43fe83
-        if (virNetDevVlanCopy(&iface->data.network.actual->vlan, vlan) < 0)
43fe83
-           goto error;
43fe83
-    }
43fe83
+    if (vlan && virNetDevVlanCopy(&iface->data.network.actual->vlan, vlan) < 0)
43fe83
+        goto error;
43fe83
 
43fe83
     if ((netdef->forward.type == VIR_NETWORK_FORWARD_NONE) ||
43fe83
         (netdef->forward.type == VIR_NETWORK_FORWARD_NAT) ||
43fe83
@@ -3889,8 +3882,7 @@ networkAllocateActualDevice(virDomainNetDefPtr iface)
43fe83
          *NETWORK; we just keep the info from the portgroup in
43fe83
          * iface->data.network.actual
43fe83
         */
43fe83
-        if (iface->data.network.actual)
43fe83
-            iface->data.network.actual->type = VIR_DOMAIN_NET_TYPE_NETWORK;
43fe83
+        iface->data.network.actual->type = VIR_DOMAIN_NET_TYPE_NETWORK;
43fe83
 
43fe83
         if (networkPlugBandwidth(network, iface) < 0)
43fe83
             goto error;
43fe83
@@ -3902,10 +3894,6 @@ networkAllocateActualDevice(virDomainNetDefPtr iface)
43fe83
          * is VIR_DOMAIN_NET_TYPE_BRIDGE
43fe83
          */
43fe83
 
43fe83
-        if (!iface->data.network.actual &&
43fe83
-            VIR_ALLOC(iface->data.network.actual) < 0)
43fe83
-            goto error;
43fe83
-
43fe83
         iface->data.network.actual->type = actualType = VIR_DOMAIN_NET_TYPE_BRIDGE;
43fe83
         if (VIR_STRDUP(iface->data.network.actual->data.bridge.brname,
43fe83
                        netdef->bridge) < 0)
43fe83
@@ -3938,10 +3926,6 @@ networkAllocateActualDevice(virDomainNetDefPtr iface)
43fe83
 
43fe83
         virDomainHostdevSubsysPciBackendType backend;
43fe83
 
43fe83
-        if (!iface->data.network.actual &&
43fe83
-            VIR_ALLOC(iface->data.network.actual) < 0)
43fe83
-            goto error;
43fe83
-
43fe83
         iface->data.network.actual->type = actualType = VIR_DOMAIN_NET_TYPE_HOSTDEV;
43fe83
         if (netdef->forward.npfs > 0 && netdef->forward.nifs <= 0 &&
43fe83
             networkCreateInterfacePool(netdef) < 0) {
43fe83
@@ -4025,10 +4009,6 @@ networkAllocateActualDevice(virDomainNetDefPtr iface)
43fe83
          * VIR_DOMAIN_NET_TYPE_DIRECT.
43fe83
          */
43fe83
 
43fe83
-        if (!iface->data.network.actual &&
43fe83
-            VIR_ALLOC(iface->data.network.actual) < 0)
43fe83
-            goto error;
43fe83
-
43fe83
         /* Set type=direct and appropriate <source mode='xxx'/> */
43fe83
         iface->data.network.actual->type = actualType = VIR_DOMAIN_NET_TYPE_DIRECT;
43fe83
         switch (netdef->forward.type) {
43fe83
@@ -4503,7 +4483,8 @@ networkReleaseActualDevice(virDomainNetDefPtr iface)
43fe83
    }
43fe83
 
43fe83
 success:
43fe83
-    netdef->connections--;
43fe83
+    if (iface->data.network.actual)
43fe83
+        netdef->connections--;
43fe83
     VIR_DEBUG("Releasing network %s, %d connections",
43fe83
               netdef->name, netdef->connections);
43fe83
     ret = 0;
43fe83
-- 
43fe83
1.8.4.2
43fe83