[libvirt] [PATCH-RFC-V2] qemu: Add network bandwidth setting for ethernet interfaces
Anirban Chakraborty
abchak at juniper.net
Wed Oct 8 04:35:47 UTC 2014
On 10/6/14, 3:43 AM, "Michal Privoznik" <mprivozn at redhat.com> wrote:
>On 18.09.2014 01:33, Anirban Chakraborty wrote:
>> V2:
>> Consolidate calls to virNetDevBandwidthSet
>> Clear bandwidth settings when the interface is detached or domain
>>destroyed
>>
>> V1:
>> Ethernet interfaces in libvirt currently do not support bandwidth
>>setting.
>> For example, following xml file for an interface will not apply these
>> settings to corresponding qdiscs.
>>
>> <interface type="ethernet">
>> <mac address="02:36:1d:18:2a:e4"/>
>> <model type="virtio"/>
>> <script path=""/>
>> <target dev="tap361d182a-e4"/>
>> <bandwidth>
>> <inbound average="984" peak="1024" burst="64"/>
>> <outbound average="2000" peak="2048" burst="128"/>
>> </bandwidth>
>> </interface>
>>
>> Signed-off-by: Anirban Chakraborty <abchak at juniper.net>
>> ---
>> src/conf/domain_conf.h | 7 +++++++
>> src/lxc/lxc_process.c | 27 ++++++++++++++-------------
>> src/qemu/qemu_command.c | 9 ++++-----
>> src/qemu/qemu_driver.c | 21 +++++++++++++++++++++
>> src/qemu/qemu_hotplug.c | 13 +++++++++++++
>> src/util/virnetdevmacvlan.c | 10 ----------
>> src/util/virnetdevmacvlan.h | 1 -
>> 7 files changed, 59 insertions(+), 29 deletions(-)
>>
>> diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
>> index 640a4c5..3c950f1 100644
>> --- a/src/conf/domain_conf.h
>> +++ b/src/conf/domain_conf.h
>> @@ -829,6 +829,13 @@ typedef enum {
>> VIR_DOMAIN_NET_TYPE_LAST
>> } virDomainNetType;
>>
>> +/* check bandwidth configuration for a network interface */
>> +#define NETDEVIF_SUPPORT_BANDWIDTH(type) \
>> + ((type == VIR_DOMAIN_NET_TYPE_ETHERNET || \
>> + type == VIR_DOMAIN_NET_TYPE_NETWORK || \
>> + type == VIR_DOMAIN_NET_TYPE_BRIDGE || \
>> + type == VIR_DOMAIN_NET_TYPE_DIRECT) ? true : false)
>> +
>
>I'd rather turn this into a function (possibly inline function).
Will do.
>
>> /* the backend driver used for virtio interfaces */
>> typedef enum {
>> VIR_DOMAIN_NET_BACKEND_TYPE_DEFAULT, /* prefer kernel, fall back
>>to user */
>> diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c
>> index ed30c37..5ef91e8 100644
>> --- a/src/lxc/lxc_process.c
>> +++ b/src/lxc/lxc_process.c
>> @@ -274,11 +274,6 @@ char
>>*virLXCProcessSetupInterfaceBridged(virConnectPtr conn,
>> if (virNetDevSetOnline(parentVeth, true) < 0)
>> goto cleanup;
>>
>> - if (virNetDevBandwidthSet(net->ifname,
>> - virDomainNetGetActualBandwidth(net),
>> - false) < 0)
>> - goto cleanup;
>> -
>
>Well, the virLXCProcessSetupInterfaceBridged is used elsewhere in the
>code too. For instance after this patch the QoS is not applied on
>interfaces hotplugged into an LXC container.
Thanks for pointing it out. I am taking care of it in my next patch.
>
>> if (net->filter &&
>> virDomainConfNWFilterInstantiate(conn, vm->uuid, net) < 0)
>> goto cleanup;
>> @@ -300,6 +295,7 @@ char
>>*virLXCProcessSetupInterfaceDirect(virConnectPtr conn,
>> virNetDevBandwidthPtr bw;
>> virNetDevVPortProfilePtr prof;
>> virLXCDriverConfigPtr cfg = virLXCDriverGetConfig(driver);
>> + const char *linkdev = virDomainNetGetActualDirectDev(net);
>>
>> /* XXX how todo bandwidth controls ?
>> * Since the 'net-ifname' is about to be moved to a different
>> @@ -329,16 +325,15 @@ char
>>*virLXCProcessSetupInterfaceDirect(virConnectPtr conn,
>>
>> if (virNetDevMacVLanCreateWithVPortProfile(
>> net->ifname, &net->mac,
>> - virDomainNetGetActualDirectDev(net),
>> + linkdev,
>> virDomainNetGetActualDirectMode(net),
>> false, def->uuid,
>> - virDomainNetGetActualVirtPortProfile(net),
>> + prof,
>> &res_ifname,
>> VIR_NETDEV_VPORT_PROFILE_OP_CREATE,
>> cfg->stateDir,
>> - virDomainNetGetActualBandwidth(net), 0) < 0)
>> + 0) < 0)
>> goto cleanup;
>> -
>> ret = res_ifname;
>>
>> cleanup:
>> @@ -368,6 +363,7 @@ static int
>>virLXCProcessSetupInterfaces(virConnectPtr conn,
>> int ret = -1;
>> size_t i;
>> size_t niface = 0;
>> + int actualType;
>>
>> for (i = 0; i < def->nnets; i++) {
>> char *veth = NULL;
>> @@ -381,7 +377,8 @@ static int
>>virLXCProcessSetupInterfaces(virConnectPtr conn,
>> if (VIR_EXPAND_N(*veths, *nveths, 1) < 0)
>> goto cleanup;
>>
>> - switch (virDomainNetGetActualType(def->nets[i])) {
>> + actualType = virDomainNetGetActualType(def->nets[i]);
>> + switch (actualType) {
>> case VIR_DOMAIN_NET_TYPE_NETWORK: {
>> virNetworkPtr network;
>> char *brname = NULL;
>> @@ -444,11 +441,15 @@ static int
>>virLXCProcessSetupInterfaces(virConnectPtr conn,
>> case VIR_DOMAIN_NET_TYPE_LAST:
>> virReportError(VIR_ERR_INTERNAL_ERROR,
>> _("Unsupported network type %s"),
>> - virDomainNetTypeToString(
>> - virDomainNetGetActualType(def->nets[i])
>> - ));
>> + virDomainNetTypeToString(actualType));
>> goto cleanup;
>> }
>> + /* set network bandwidth */
>> + if (NETDEVIF_SUPPORT_BANDWIDTH(actualType) &&
>>virNetDevBandwidthSet(
>> + def->nets[i]->ifname, virDomainNetGetActualBandwidth(
>> + def->nets[i]),
>> + false) < 0)
>
>I must say this formatting looks very strange to me in libvirt
>connotations.
Yeah, this was not right, for some reason it escaped my attention.
>
>> + goto cleanup;
>>
>> (*veths)[(*nveths)-1] = veth;
>>
>> diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
>> index f2e6e5a..404c51b 100644
>> --- a/src/qemu/qemu_command.c
>> +++ b/src/qemu/qemu_command.c
>> @@ -191,7 +191,6 @@ qemuPhysIfaceConnect(virDomainDefPtr def,
>> virDomainNetGetActualVirtPortProfile(net),
>> &res_ifname,
>> vmop, cfg->stateDir,
>> - virDomainNetGetActualBandwidth(net),
>> macvlan_create_flags);
>> if (rc >= 0) {
>> virDomainAuditNetDevice(def, net, res_ifname, true);
>> @@ -371,10 +370,6 @@ qemuNetworkIfaceConnect(virDomainDefPtr def,
>> &net->mac) < 0)
>> goto cleanup;
>>
>> - if (virNetDevBandwidthSet(net->ifname,
>> - virDomainNetGetActualBandwidth(net),
>> - false) < 0)
>> - goto cleanup;
>>
>> if (net->filter &&
>> virDomainConfNWFilterInstantiate(conn, def->uuid, net) < 0) {
>> @@ -7313,6 +7308,10 @@ qemuBuildInterfaceCommandLine(virCommandPtr cmd,
>> if (tapfd[0] < 0)
>> goto cleanup;
>> }
>> + /* Set bandwidth */
>> + if (NETDEVIF_SUPPORT_BANDWIDTH(actualType) &&
>>virNetDevBandwidthSet(
>> + net->ifname, virDomainNetGetActualBandwidth(net), false) <
>>0)
>> + goto cleanup;
>>
>> if ((actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
>> actualType == VIR_DOMAIN_NET_TYPE_BRIDGE ||
>> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
>> index 5fd89a3..f5a5cbe 100644
>> --- a/src/qemu/qemu_driver.c
>> +++ b/src/qemu/qemu_driver.c
>> @@ -186,6 +186,9 @@ qemuVMFilterRebuild(virDomainObjListIterator iter,
>>void *data)
>> return virDomainObjListForEach(qemu_driver->domains, iter, data);
>> }
>>
>> +static void
>> +qemuDomainClearNetBandwidth(virDomainObjPtr vm);
>> +
>> static virNWFilterCallbackDriver qemuCallbackDriver = {
>> .name = QEMU_DRIVER_NAME,
>> .vmFilterRebuild = qemuVMFilterRebuild,
>> @@ -2196,6 +2199,9 @@ qemuDomainDestroyFlags(virDomainPtr dom,
>> if (virDomainDestroyFlagsEnsureACL(dom->conn, vm->def) < 0)
>> goto cleanup;
>>
>> + /* Clear network bandwidth settings */
>> + qemuDomainClearNetBandwidth(vm);
>> +
>
>
>No. This clears QoS only if the destroy API is called. However, domain
>may terminate by other means where the QoS should be cleared too, e.g.
>'sudo poweroff' caled from within the domain. So this call needs to go
>into qemuProcessStop.
Got it, thanks for catching it.
>
>> qemuDomainSetFakeReboot(driver, vm, false);
>>
>>
>> @@ -17952,6 +17958,21 @@ qemuConnectGetAllDomainStats(virConnectPtr
>>conn,
>> return ret;
>> }
>>
>> +/* Clear the bandwidth setting of all the network interfaces of a vm */
>> +static void
>> +qemuDomainClearNetBandwidth(virDomainObjPtr vm)
>> +{
>> + size_t i;
>> + int actualType;
>> +
>> + for (i = 0; i < vm->def->nnets; i++) {
>> + virDomainNetDefPtr net = vm->def->nets[i];
>> + actualType = virDomainNetGetActualType(net);
>> + if (NETDEVIF_SUPPORT_BANDWIDTH(actualType))
>> + virNetDevBandwidthClear(net->ifname);
>> + }
>> +}
>> +
>
>Okay. Previously QoS was set on TAP devices only. So there was no need
>to call virNetDevBandwidthClear as the TAP devices were removed with
>qemu process tearing down. However, this clears just qemu domains and
>left LXC containers uncleared.
I¹ll take care of it in my next patch. Thanks.
Anirban
More information about the libvir-list
mailing list