]> xenbits.xensource.com Git - libvirt.git/commitdiff
bandwidth: Integrate bandwidth into portgroups
authorMichal Privoznik <mprivozn@redhat.com>
Tue, 26 Jul 2011 12:42:37 +0000 (14:42 +0200)
committerMichal Privoznik <mprivozn@redhat.com>
Wed, 27 Jul 2011 08:26:25 +0000 (10:26 +0200)
Every DomainNetDef has a bandwidth, as does every portgroup.
Whenever a DomainNetDef of type NETWORK is about to be used, a call is
made to networkAllocateActualDevice(). This function chooses the "best"
bandwidth object and places it in the DomainActualNetDef.
From that point on, whenever some code needs to use the bandwidth data
for the interface, it's retrieved with virDomainNetGetActualBandwidth(),
which will always return the "best" info as determined in the
previous step.

docs/formatnetwork.html.in
src/conf/domain_conf.c
src/conf/domain_conf.h
src/conf/network_conf.c
src/conf/network_conf.h
src/libvirt_private.syms
src/network/bridge_driver.c
src/qemu/qemu_command.c
src/util/network.c
src/util/network.h

index f0ff703269a8481fbe358762fc663d3f77fa013e..ddfa77cb920ca54e55bd44864a1561dc68ed4720 100644 (file)
         numbers, The units for <code>average</code> and <code>peak</code> attributes
         are kilobytes per second, and for the <code>burst</code> just kilobytes.
         The rate is shared equally within domains connected to the network.
+        Moreover, <code>bandwidth</code> element can be included in
+        <code>portgroup</code> element.
         <span class="since">Since 0.9.4</span>
       </p>
 
index 072c970e7d375f4b5efdd480ddee0283db497e67..f99294cc1cc0fa4536995ee1c6a9a2e419e0e5fd 100644 (file)
@@ -753,6 +753,8 @@ virDomainActualNetDefFree(virDomainActualNetDefPtr def)
         break;
     }
 
+    virBandwidthDefFree(def->bandwidth);
+
     VIR_FREE(def);
 }
 
@@ -2621,6 +2623,7 @@ virDomainActualNetDefParseXML(xmlNodePtr node,
     virDomainActualNetDefPtr actual = NULL;
     int ret = -1;
     xmlNodePtr save_ctxt = ctxt->node;
+    xmlNodePtr bandwidth_node = NULL;
     char *type = NULL;
     char *mode = NULL;
 
@@ -2677,6 +2680,11 @@ virDomainActualNetDefParseXML(xmlNodePtr node,
         }
     }
 
+    bandwidth_node = virXPathNode("./bandwidth", ctxt);
+    if (bandwidth_node &&
+        !(actual->bandwidth = virBandwidthDefParseNode(bandwidth_node)))
+        goto error;
+
     *def = actual;
     actual = NULL;
     ret = 0;
@@ -8713,6 +8721,10 @@ virDomainActualNetDefFormat(virBufferPtr buf,
     default:
         break;
     }
+
+    if (virBandwidthDefFormat(buf, def->bandwidth, "      ") < 0)
+        goto error;
+
     virBufferAddLit(buf, "      </actual>\n");
 
     ret = 0;
@@ -11383,3 +11395,13 @@ virDomainNetGetActualDirectVirtPortProfile(virDomainNetDefPtr iface)
         return NULL;
     return iface->data.network.actual->data.direct.virtPortProfile;
 }
+
+virBandwidthPtr
+virDomainNetGetActualBandwidth(virDomainNetDefPtr iface)
+{
+    if ((iface->type == VIR_DOMAIN_NET_TYPE_NETWORK) &&
+        iface->data.network.actual && iface->data.network.actual->bandwidth) {
+        return iface->data.network.actual->bandwidth;
+    }
+    return iface->bandwidth;
+}
index 212f0c5f0f78a4049c6e15154fce16a60153e144..715d99572eadbe6a040f1aea976ac4a237753e6b 100644 (file)
@@ -362,6 +362,7 @@ struct _virDomainActualNetDef {
             virVirtualPortProfileParamsPtr virtPortProfile;
         } direct;
     } data;
+    virBandwidthPtr bandwidth;
 };
 
 /* Stores the virtual network interface configuration */
@@ -1490,6 +1491,8 @@ char *virDomainNetGetActualDirectDev(virDomainNetDefPtr iface);
 int virDomainNetGetActualDirectMode(virDomainNetDefPtr iface);
 virVirtualPortProfileParamsPtr
 virDomainNetGetActualDirectVirtPortProfile(virDomainNetDefPtr iface);
+virBandwidthPtr
+virDomainNetGetActualBandwidth(virDomainNetDefPtr iface);
 
 int virDomainControllerInsert(virDomainDefPtr def,
                               virDomainControllerDefPtr controller);
index 1ef80dc01db5f654244d909eed56b6e6d2fef9dc..6714c209a764c78bc482d99311c8efe72f34b7c2 100644 (file)
@@ -92,6 +92,8 @@ virPortGroupDefClear(virPortGroupDefPtr def)
 {
     VIR_FREE(def->name);
     VIR_FREE(def->virtPortProfile);
+    virBandwidthDefFree(def->bandwidth);
+    def->bandwidth = NULL;
 }
 
 static void
@@ -771,6 +773,7 @@ virNetworkPortGroupParseXML(virPortGroupDefPtr def,
 
     xmlNodePtr save;
     xmlNodePtr virtPortNode;
+    xmlNodePtr bandwidth_node;
     char *isDefault = NULL;
 
     int result = -1;
@@ -790,6 +793,12 @@ virNetworkPortGroupParseXML(virPortGroupDefPtr def,
         goto error;
     }
 
+    bandwidth_node = virXPathNode("./bandwidth", ctxt);
+    if (bandwidth_node &&
+        !(def->bandwidth = virBandwidthDefParseNode(bandwidth_node))) {
+        goto error;
+    }
+
     result = 0;
 error:
     if (result < 0) {
@@ -1257,6 +1266,7 @@ virPortGroupDefFormat(virBufferPtr buf,
     }
     virBufferAddLit(buf, ">\n");
     virVirtualPortProfileFormat(buf, def->virtPortProfile, "    ");
+    virBandwidthDefFormat(buf, def->bandwidth, "    ");
     virBufferAddLit(buf, "  </portgroup>\n");
 }
 
index 6d0845e36c8e31b5e5bef73cb91631de4874f4ba..869085e0bd2d871d01832c75db22920a70637851 100644 (file)
@@ -123,6 +123,7 @@ struct _virPortGroupDef {
     char *name;
     bool isDefault;
     virVirtualPortProfileParamsPtr virtPortProfile;
+    virBandwidthPtr bandwidth;
 };
 
 typedef struct _virNetworkDef virNetworkDef;
index 853ee628f11af2ad27a6d2bf6f4c5647fd66f1c5..a40610093cb75ffd1ce18019cb0dd0e850be64a5 100644 (file)
@@ -337,6 +337,7 @@ virDomainLoadAllConfigs;
 virDomainMemballoonModelTypeFromString;
 virDomainMemballoonModelTypeToString;
 virDomainNetDefFree;
+virDomainNetGetActualBandwidth;
 virDomainNetGetActualBridgeName;
 virDomainNetGetActualDirectDev;
 virDomainNetGetActualDirectMode;
@@ -710,6 +711,7 @@ nlComm;
 
 
 # network.h
+virBandwidthCopy;
 virBandwidthDefFormat;
 virBandwidthDefFree;
 virBandwidthDefParseNode;
index b1c6b12bf38c92787279538d230094f3fa58efc5..b8c6c975072f2ac307b50b2c6af2c098b54c3426 100644 (file)
@@ -2811,6 +2811,7 @@ networkAllocateActualDevice(virDomainNetDefPtr iface)
                (netdef->forwardType == VIR_NETWORK_FORWARD_VEPA) ||
                (netdef->forwardType == VIR_NETWORK_FORWARD_PASSTHROUGH)) {
         virVirtualPortProfileParamsPtr virtport = NULL;
+        virPortGroupDefPtr portgroup = NULL;
 
         /* <forward type='bridge|private|vepa|passthrough'> are all
          * VIR_DOMAIN_NET_TYPE_DIRECT.
@@ -2839,11 +2840,10 @@ networkAllocateActualDevice(virDomainNetDefPtr iface)
         }
 
         /* Find the most specific virtportprofile and copy it */
+        portgroup = virPortGroupFindByName(netdef, iface->data.network.portgroup);
         if (iface->data.network.virtPortProfile) {
             virtport = iface->data.network.virtPortProfile;
         } else {
-            virPortGroupDefPtr portgroup
-               = virPortGroupFindByName(netdef, iface->data.network.portgroup);
             if (portgroup)
                 virtport = portgroup->virtPortProfile;
             else
@@ -2859,6 +2859,21 @@ networkAllocateActualDevice(virDomainNetDefPtr iface)
              */
             *iface->data.network.actual->data.direct.virtPortProfile = *virtport;
         }
+
+        /* Find the most specific bandwidth config and copy it */
+        if (iface->bandwidth) {
+            if (virBandwidthCopy(&iface->data.network.actual->bandwidth,
+                                 iface->bandwidth) < 0) {
+                goto cleanup;
+            }
+        } else {
+            if (portgroup &&
+                virBandwidthCopy(&iface->data.network.actual->bandwidth,
+                                 portgroup->bandwidth) < 0) {
+                goto cleanup;
+            }
+        }
+
         /* If there is only a single device, just return it (caller will detect
          * any error if exclusive use is required but could not be acquired).
          */
index f8fd4eee9afdded36cba5d9fd892bcaa80680e74..35d6b1e021fcb5df2413aee28ffd6f547851ab93 100644 (file)
@@ -132,7 +132,8 @@ qemuPhysIfaceConnect(virDomainDefPtr def,
                         vnet_hdr, def->uuid,
                         virDomainNetGetActualDirectVirtPortProfile(net),
                         &res_ifname,
-                        vmop, driver->stateDir, net->bandwidth);
+                        vmop, driver->stateDir,
+                        virDomainNetGetActualBandwidth(net));
     if (rc >= 0) {
         virDomainAuditNetDevice(def, net, res_ifname, true);
         VIR_FREE(net->ifname);
@@ -299,7 +300,8 @@ qemuNetworkIfaceConnect(virDomainDefPtr def,
     }
 
     if (tapfd >= 0 &&
-        virBandwidthEnable(net->bandwidth, net->ifname) < 0) {
+        virBandwidthEnable(virDomainNetGetActualBandwidth(net),
+                           net->ifname) < 0) {
         qemuReportError(VIR_ERR_INTERNAL_ERROR,
                         _("cannot set bandwidth limits on %s"),
                         net->ifname);
index 5561012ada61b8f41ce381fad28784d31dca6a82..6fcdab2bba4054381410cd1f58de96dc3cc0b951 100644 (file)
@@ -1263,3 +1263,61 @@ cleanup:
     virCommandFree(cmd);
     return ret;
 }
+
+/*
+ * virBandwidthCopy:
+ * @dest: destination
+ * @src:  source
+ *
+ * Returns -1 on OOM error (which gets reported),
+ * 0 otherwise.
+ */
+int
+virBandwidthCopy(virBandwidthPtr *dest,
+                 const virBandwidthPtr src)
+{
+    int ret = -1;
+
+    if (!dest) {
+        virSocketError(VIR_ERR_INVALID_ARG, "%s",
+                       _("invalid argument supplied"));
+        return -1;
+    }
+
+    *dest = NULL;
+    if (!src) {
+        /* nothing to be copied */
+        return 0;
+    }
+
+    if (VIR_ALLOC(*dest) < 0) {
+        virReportOOMError();
+        goto cleanup;
+    }
+
+    if (src->in) {
+        if (VIR_ALLOC((*dest)->in) < 0) {
+            virReportOOMError();
+            goto cleanup;
+        }
+        memcpy((*dest)->in, src->in, sizeof(*src->in));
+    }
+
+    if (src->out) {
+        if (VIR_ALLOC((*dest)->out) < 0) {
+            virReportOOMError();
+            VIR_FREE((*dest)->in);
+            goto cleanup;
+        }
+        memcpy((*dest)->out, src->out, sizeof(*src->out));
+    }
+
+    ret = 0;
+
+cleanup:
+    if (ret < 0) {
+        virBandwidthDefFree(*dest);
+        *dest = NULL;
+    }
+    return ret;
+}
index 139f6ccb8bef9b5368a1431cf8e20f4c14635baa..6ceaa6d5b9ceaa29cdff788dd483a7415e313bd4 100644 (file)
@@ -158,4 +158,6 @@ int virBandwidthDefFormat(virBufferPtr buf,
 
 int virBandwidthEnable(virBandwidthPtr bandwidth, const char *iface);
 int virBandwidthDisable(const char *iface, bool may_fail);
+int virBandwidthCopy(virBandwidthPtr *dest, const virBandwidthPtr src);
+
 #endif /* __VIR_NETWORK_H__ */