提交 22cff52a 编写于 作者: A Anirban Chakraborty 提交者: Michal Privoznik

network: Add network bandwidth support to ethernet interfaces

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: NAnirban Chakraborty <abchak@juniper.net>
Signed-off-by: NMichal Privoznik <mprivozn@redhat.com>
上级 401702d9
......@@ -25,7 +25,6 @@
#include "netdev_bandwidth_conf.h"
#include "virerror.h"
#include "viralloc.h"
#include "domain_conf.h"
#include "virstring.h"
#define VIR_FROM_THIS VIR_FROM_NONE
......@@ -269,3 +268,16 @@ virNetDevBandwidthFormat(virNetDevBandwidthPtr def, virBufferPtr buf)
cleanup:
return ret;
}
void
virDomainClearNetBandwidth(virDomainObjPtr vm)
{
size_t i;
virDomainNetType type;
for (i = 0; i < vm->def->nnets; i++) {
type = virDomainNetGetActualType(vm->def->nets[i]);
if (virNetDevSupportBandwidth(type))
virNetDevBandwidthClear(vm->def->nets[i]->ifname);
}
}
......@@ -27,6 +27,7 @@
# include "virnetdevbandwidth.h"
# include "virbuffer.h"
# include "virxml.h"
# include "domain_conf.h"
virNetDevBandwidthPtr virNetDevBandwidthParse(xmlNodePtr node,
int net_type)
......@@ -35,4 +36,28 @@ int virNetDevBandwidthFormat(virNetDevBandwidthPtr def,
virBufferPtr buf)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
void virDomainClearNetBandwidth(virDomainObjPtr vm)
ATTRIBUTE_NONNULL(1);
static inline bool virNetDevSupportBandwidth(virDomainNetType type)
{
switch (type) {
case VIR_DOMAIN_NET_TYPE_BRIDGE:
case VIR_DOMAIN_NET_TYPE_NETWORK:
case VIR_DOMAIN_NET_TYPE_DIRECT:
case VIR_DOMAIN_NET_TYPE_ETHERNET:
return true;
case VIR_DOMAIN_NET_TYPE_USER:
case VIR_DOMAIN_NET_TYPE_VHOSTUSER:
case VIR_DOMAIN_NET_TYPE_SERVER:
case VIR_DOMAIN_NET_TYPE_CLIENT:
case VIR_DOMAIN_NET_TYPE_MCAST:
case VIR_DOMAIN_NET_TYPE_INTERNAL:
case VIR_DOMAIN_NET_TYPE_HOSTDEV:
case VIR_DOMAIN_NET_TYPE_LAST:
break;
}
return false;
}
#endif /* __VIR_NETDEV_BANDWIDTH_CONF_H__ */
......@@ -507,6 +507,7 @@ virInterfaceRemove;
# conf/netdev_bandwidth_conf.h
virDomainClearNetBandwidth;
virNetDevBandwidthFormat;
virNetDevBandwidthParse;
......
......@@ -72,6 +72,7 @@
#include "viraccessapicheck.h"
#include "viraccessapichecklxc.h"
#include "virhostdev.h"
#include "netdev_bandwidth_conf.h"
#define VIR_FROM_THIS VIR_FROM_LXC
......@@ -4213,6 +4214,11 @@ lxcDomainAttachDeviceNetLive(virConnectPtr conn,
_("Network device type is not supported"));
goto cleanup;
}
/* set network bandwidth */
if (virNetDevSupportBandwidth(actualType) &&
virNetDevBandwidthSet(net->ifname,
virDomainNetGetActualBandwidth(net), false) < 0)
goto cleanup;
if (virNetDevSetNamespace(veth, priv->initpid) < 0) {
virDomainAuditNet(vm, NULL, net, "attach", false);
......@@ -4635,7 +4641,7 @@ static int
lxcDomainDetachDeviceNetLive(virDomainObjPtr vm,
virDomainDeviceDefPtr dev)
{
int detachidx, ret = -1;
int detachidx, actualType, ret = -1;
virDomainNetDefPtr detach = NULL;
virNetDevVPortProfilePtr vport = NULL;
......@@ -4643,8 +4649,14 @@ lxcDomainDetachDeviceNetLive(virDomainObjPtr vm,
goto cleanup;
detach = vm->def->nets[detachidx];
actualType = virDomainNetGetActualType(detach);
/* clear network bandwidth */
if (virNetDevSupportBandwidth(actualType) &&
virNetDevBandwidthClear(detach->ifname))
goto cleanup;
switch (virDomainNetGetActualType(detach)) {
switch (actualType) {
case VIR_DOMAIN_NET_TYPE_BRIDGE:
case VIR_DOMAIN_NET_TYPE_NETWORK:
if (virNetDevVethDelete(detach->ifname) < 0) {
......
......@@ -51,6 +51,7 @@
#include "viratomic.h"
#include "virprocess.h"
#include "virsystemd.h"
#include "netdev_bandwidth_conf.h"
#define VIR_FROM_THIS VIR_FROM_LXC
......@@ -274,11 +275,6 @@ char *virLXCProcessSetupInterfaceBridged(virConnectPtr conn,
if (virNetDevSetOnline(parentVeth, true) < 0)
goto cleanup;
if (virNetDevBandwidthSet(net->ifname,
virDomainNetGetActualBandwidth(net),
false) < 0)
goto cleanup;
if (net->filter &&
virDomainConfNWFilterInstantiate(conn, vm->uuid, net) < 0)
goto cleanup;
......@@ -300,6 +296,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,14 +326,13 @@ 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)
cfg->stateDir, 0) < 0)
goto cleanup;
ret = res_ifname;
......@@ -368,6 +364,8 @@ static int virLXCProcessSetupInterfaces(virConnectPtr conn,
int ret = -1;
size_t i;
size_t niface = 0;
virDomainNetDefPtr net;
virDomainNetType type;
for (i = 0; i < def->nnets; i++) {
char *veth = NULL;
......@@ -375,13 +373,15 @@ static int virLXCProcessSetupInterfaces(virConnectPtr conn,
* network's pool of devices, or resolve bridge device name
* to the one defined in the network definition.
*/
if (networkAllocateActualDevice(def, def->nets[i]) < 0)
net = def->nets[i];
if (networkAllocateActualDevice(def, net) < 0)
goto cleanup;
if (VIR_EXPAND_N(*veths, *nveths, 1) < 0)
goto cleanup;
switch (virDomainNetGetActualType(def->nets[i])) {
type = virDomainNetGetActualType(net);
switch (type) {
case VIR_DOMAIN_NET_TYPE_NETWORK: {
virNetworkPtr network;
char *brname = NULL;
......@@ -389,7 +389,7 @@ static int virLXCProcessSetupInterfaces(virConnectPtr conn,
virErrorPtr errobj;
if (!(network = virNetworkLookupByName(conn,
def->nets[i]->data.network.name)))
net->data.network.name)))
goto cleanup;
if (!(brname = virNetworkGetBridgeName(network)))
fail = true;
......@@ -405,7 +405,7 @@ static int virLXCProcessSetupInterfaces(virConnectPtr conn,
if (!(veth = virLXCProcessSetupInterfaceBridged(conn,
def,
def->nets[i],
net,
brname))) {
VIR_FREE(brname);
goto cleanup;
......@@ -414,7 +414,7 @@ static int virLXCProcessSetupInterfaces(virConnectPtr conn,
break;
}
case VIR_DOMAIN_NET_TYPE_BRIDGE: {
const char *brname = virDomainNetGetActualBridgeName(def->nets[i]);
const char *brname = virDomainNetGetActualBridgeName(net);
if (!brname) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("No bridge name specified"));
......@@ -422,7 +422,7 @@ static int virLXCProcessSetupInterfaces(virConnectPtr conn,
}
if (!(veth = virLXCProcessSetupInterfaceBridged(conn,
def,
def->nets[i],
net,
brname)))
goto cleanup;
} break;
......@@ -430,31 +430,39 @@ static int virLXCProcessSetupInterfaces(virConnectPtr conn,
case VIR_DOMAIN_NET_TYPE_DIRECT:
if (!(veth = virLXCProcessSetupInterfaceDirect(conn,
def,
def->nets[i])))
net)))
goto cleanup;
break;
case VIR_DOMAIN_NET_TYPE_USER:
case VIR_DOMAIN_NET_TYPE_ETHERNET:
break;
case VIR_DOMAIN_NET_TYPE_USER:
case VIR_DOMAIN_NET_TYPE_VHOSTUSER:
case VIR_DOMAIN_NET_TYPE_SERVER:
case VIR_DOMAIN_NET_TYPE_CLIENT:
case VIR_DOMAIN_NET_TYPE_MCAST:
case VIR_DOMAIN_NET_TYPE_INTERNAL:
case VIR_DOMAIN_NET_TYPE_LAST:
case VIR_DOMAIN_NET_TYPE_HOSTDEV:
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Unsupported network type %s"),
virDomainNetTypeToString(
virDomainNetGetActualType(def->nets[i])
));
virDomainNetTypeToString(type));
goto cleanup;
}
/* set network bandwidth */
if (virNetDevSupportBandwidth(type) &&
virNetDevBandwidthSet(net->ifname,
virDomainNetGetActualBandwidth(net), false) < 0)
goto cleanup;
(*veths)[(*nveths)-1] = veth;
/* Make sure all net definitions will have a name in the container */
if (!def->nets[i]->ifname_guest) {
if (virAsprintf(&def->nets[i]->ifname_guest, "eth%zu", niface) < 0)
if (!net->ifname_guest) {
if (virAsprintf(&net->ifname_guest, "eth%zu", niface) < 0)
return -1;
niface++;
}
......
......@@ -43,6 +43,7 @@
#include "domain_addr.h"
#include "domain_audit.h"
#include "domain_conf.h"
#include "netdev_bandwidth_conf.h"
#include "snapshot_conf.h"
#include "storage_conf.h"
#include "secret_conf.h"
......@@ -192,7 +193,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);
......@@ -372,11 +372,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) {
goto cleanup;
......@@ -7501,6 +7496,13 @@ qemuBuildInterfaceCommandLine(virCommandPtr cmd,
goto cleanup;
}
/* Set Bandwidth */
if (virNetDevSupportBandwidth(actualType) &&
virNetDevBandwidthSet(net->ifname,
virDomainNetGetActualBandwidth(net),
false) < 0)
goto cleanup;
if ((actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
actualType == VIR_DOMAIN_NET_TYPE_BRIDGE ||
actualType == VIR_DOMAIN_NET_TYPE_ETHERNET ||
......
......@@ -31,6 +31,7 @@
#include "qemu_command.h"
#include "qemu_hostdev.h"
#include "domain_audit.h"
#include "netdev_bandwidth_conf.h"
#include "domain_nwfilter.h"
#include "virlog.h"
#include "datatypes.h"
......@@ -947,6 +948,12 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
goto cleanup;
}
/* Set Bandwidth */
if (virNetDevSupportBandwidth(actualType) &&
virNetDevBandwidthSet(net->ifname,
virDomainNetGetActualBandwidth(net), false) < 0)
goto cleanup;
for (i = 0; i < tapfdSize; i++) {
if (virSecurityManagerSetTapFDLabel(driver->securityManager,
vm->def, tapfd[i]) < 0)
......@@ -3545,6 +3552,11 @@ qemuDomainDetachNetDevice(virQEMUDriverPtr driver,
goto cleanup;
}
if (virNetDevSupportBandwidth(virDomainNetGetActualType(detach)) &&
virNetDevBandwidthClear(detach->ifname) < 0)
VIR_WARN("cannot clear bandwidth setting for device : %s",
detach->ifname);
qemuDomainMarkDeviceForRemoval(vm, &detach->info);
qemuDomainObjEnterMonitor(driver, vm);
......
......@@ -69,6 +69,7 @@
#include "storage/storage_driver.h"
#include "configmake.h"
#include "nwfilter_conf.h"
#include "netdev_bandwidth_conf.h"
#define VIR_FROM_THIS VIR_FROM_QEMU
......@@ -4843,6 +4844,9 @@ void qemuProcessStop(virQEMUDriverPtr driver,
virStrerror(errno, ebuf, sizeof(ebuf)));
}
/* Clear network bandwidth */
virDomainClearNetBandwidth(vm);
virDomainConfVMNWFilterTeardown(vm);
if (cfg->macFilter) {
......
......@@ -810,7 +810,6 @@ int virNetDevMacVLanCreateWithVPortProfile(const char *tgifname,
char **res_ifname,
virNetDevVPortProfileOp vmOp,
char *stateDir,
virNetDevBandwidthPtr bandwidth,
unsigned int flags)
{
const char *type = (flags & VIR_NETDEV_MACVLAN_CREATE_WITH_TAP) ?
......@@ -923,14 +922,6 @@ int virNetDevMacVLanCreateWithVPortProfile(const char *tgifname,
rc = 0;
}
if (virNetDevBandwidthSet(cr_ifname, bandwidth, false) < 0) {
if (flags & VIR_NETDEV_MACVLAN_CREATE_WITH_TAP)
VIR_FORCE_CLOSE(rc); /* sets rc to -1 */
else
rc = -1;
goto disassociate_exit;
}
if (vmOp == VIR_NETDEV_VPORT_PROFILE_OP_CREATE ||
vmOp == VIR_NETDEV_VPORT_PROFILE_OP_RESTORE) {
/* Only directly register upon a create or restore (restarting
......@@ -1073,7 +1064,6 @@ int virNetDevMacVLanCreateWithVPortProfile(const char *ifname ATTRIBUTE_UNUSED,
char **res_ifname ATTRIBUTE_UNUSED,
virNetDevVPortProfileOp vmop ATTRIBUTE_UNUSED,
char *stateDir ATTRIBUTE_UNUSED,
virNetDevBandwidthPtr bandwidth ATTRIBUTE_UNUSED,
unsigned int flags)
{
virCheckFlags(0, -1);
......
......@@ -68,7 +68,6 @@ int virNetDevMacVLanCreateWithVPortProfile(const char *ifname,
char **res_ifname,
virNetDevVPortProfileOp vmop,
char *stateDir,
virNetDevBandwidthPtr bandwidth,
unsigned int flags)
ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(6)
ATTRIBUTE_NONNULL(8) ATTRIBUTE_NONNULL(10) ATTRIBUTE_RETURN_CHECK;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册