diff --git a/src/conf/netdev_bandwidth_conf.c b/src/conf/netdev_bandwidth_conf.c index 2e5b564..63a39e3 100644 --- a/src/conf/netdev_bandwidth_conf.c +++ b/src/conf/netdev_bandwidth_conf.c @@ -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); + } +} diff --git a/src/conf/netdev_bandwidth_conf.h b/src/conf/netdev_bandwidth_conf.h index 23aaaf3..60dacc6 100644 --- a/src/conf/netdev_bandwidth_conf.h +++ b/src/conf/netdev_bandwidth_conf.h @@ -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__ */ diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index 6a58d50..e418f8e 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -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 @@ -4212,6 +4213,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); @@ -4643,6 +4649,8 @@ lxcDomainDetachDeviceNetLive(virDomainObjPtr vm, detach = vm->def->nets[detachidx]; + virDomainClearNetBandwidth(vm); + switch (virDomainNetGetActualType(detach)) { case VIR_DOMAIN_NET_TYPE_BRIDGE: case VIR_DOMAIN_NET_TYPE_NETWORK: diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c index 6c83fdb..77069b9 100644 --- a/src/lxc/lxc_process.c +++ b/src/lxc/lxc_process.c @@ -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++; } diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index a5ed8ed..83b6276 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -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; @@ -7499,6 +7494,15 @@ qemuBuildInterfaceCommandLine(virCommandPtr cmd, goto cleanup; } + /* Set Bandwidth */ + if (net->ifname && strlen(net->ifname)) { + 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 || diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 13bcd88..e09f1a9 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -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" @@ -948,6 +949,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) @@ -3547,6 +3554,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); diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 24e5f0f..9c1a417 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -68,6 +68,7 @@ #include "virhostdev.h" #include "storage/storage_driver.h" #include "configmake.h" +#include "netdev_bandwidth_conf.h" #define VIR_FROM_THIS VIR_FROM_QEMU @@ -4842,6 +4843,9 @@ void qemuProcessStop(virQEMUDriverPtr driver, virStrerror(errno, ebuf, sizeof(ebuf))); } + /* Clear network bandwidth */ + virDomainClearNetBandwidth(vm); + virDomainConfVMNWFilterTeardown(vm); if (cfg->macFilter) { diff --git a/src/util/virnetdevmacvlan.c b/src/util/virnetdevmacvlan.c index c83341c..956a96b 100644 --- a/src/util/virnetdevmacvlan.c +++ b/src/util/virnetdevmacvlan.c @@ -811,7 +811,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) ? @@ -925,14 +924,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 @@ -1076,7 +1067,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); diff --git a/src/util/virnetdevmacvlan.h b/src/util/virnetdevmacvlan.h index 41aa4e2..f08d32b 100644 --- a/src/util/virnetdevmacvlan.h +++ b/src/util/virnetdevmacvlan.h @@ -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;