[libvirt] [PATCH v6] 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: Anirban Chakraborty <abchak@juniper.net> --- src/conf/netdev_bandwidth_conf.c | 14 ++++++++++- src/conf/netdev_bandwidth_conf.h | 25 +++++++++++++++++++ src/libvirt_private.syms | 1 + src/lxc/lxc_driver.c | 8 +++++++ src/lxc/lxc_process.c | 52 +++++++++++++++++++++++----------------- src/qemu/qemu_command.c | 16 ++++++++----- src/qemu/qemu_hotplug.c | 12 ++++++++++ src/qemu/qemu_process.c | 4 ++++ src/util/virnetdevmacvlan.c | 10 -------- src/util/virnetdevmacvlan.h | 1 - 10 files changed, 103 insertions(+), 40 deletions(-) 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/libvirt_private.syms b/src/libvirt_private.syms index 0864618..1c0cfb1 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -509,6 +509,7 @@ virInterfaceRemove; # conf/netdev_bandwidth_conf.h virNetDevBandwidthFormat; virNetDevBandwidthParse; +virDomainClearNetBandwidth; # conf/netdev_vlan_conf.h diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index cf2a3c8..e9e0da3 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 @@ -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); @@ -4644,6 +4650,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 37ddbbc..5bbd696 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 1399ce4..8025ff6 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; @@ -7501,6 +7496,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 b9a0cee..3e7b7da 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" @@ -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); diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 7518138..b782984 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -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) { diff --git a/src/util/virnetdevmacvlan.c b/src/util/virnetdevmacvlan.c index 89e221d..2ff24b1 100644 --- a/src/util/virnetdevmacvlan.c +++ b/src/util/virnetdevmacvlan.c @@ -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); 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; -- 1.9.1

On 19.11.2014 00:55, Anirban Chakraborty wrote:
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@juniper.net> --- src/conf/netdev_bandwidth_conf.c | 14 ++++++++++- src/conf/netdev_bandwidth_conf.h | 25 +++++++++++++++++++ src/libvirt_private.syms | 1 + src/lxc/lxc_driver.c | 8 +++++++ src/lxc/lxc_process.c | 52 +++++++++++++++++++++++----------------- src/qemu/qemu_command.c | 16 ++++++++----- src/qemu/qemu_hotplug.c | 12 ++++++++++ src/qemu/qemu_process.c | 4 ++++ src/util/virnetdevmacvlan.c | 10 -------- src/util/virnetdevmacvlan.h | 1 - 10 files changed, 103 insertions(+), 40 deletions(-)
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/libvirt_private.syms b/src/libvirt_private.syms index 0864618..1c0cfb1 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -509,6 +509,7 @@ virInterfaceRemove; # conf/netdev_bandwidth_conf.h virNetDevBandwidthFormat; virNetDevBandwidthParse; +virDomainClearNetBandwidth;
This should go before pre-existing symbols. The symbols are sorted alphabetically.
# conf/netdev_vlan_conf.h diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index cf2a3c8..e9e0da3 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
@@ -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;
Indentation's off.
if (virNetDevSetNamespace(veth, priv->initpid) < 0) { virDomainAuditNet(vm, NULL, net, "attach", false); @@ -4644,6 +4650,8 @@ lxcDomainDetachDeviceNetLive(virDomainObjPtr vm,
detach = vm->def->nets[detachidx];
+ virDomainClearNetBandwidth(vm);
This clears bandwidth on ALL vNICs, not only the one that is being detached. We need similar code that is in the previous chunk.
+ 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 37ddbbc..5bbd696 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; +
Indentation's off.
(*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 1399ce4..8025ff6 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; @@ -7501,6 +7496,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; + }
Why is the check for net->ifname needed?
+ 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 b9a0cee..3e7b7da 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" @@ -947,6 +948,12 @@ int qemuDomainAttachNetDevice(virConnectPtr conn, goto cleanup; }
+ /* Set Bandwidth */ + if (virNetDevSupportBandwidth(actualType) && + virNetDevBandwidthSet(net->ifname, + virDomainNetGetActualBandwidth(net), false) < 0) + goto cleanup; +
Indentation's off.
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); +
See? this chunk is okay (compared to LXC driver).
qemuDomainMarkDeviceForRemoval(vm, &detach->info);
qemuDomainObjEnterMonitor(driver, vm); diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 7518138..b782984 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -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) { diff --git a/src/util/virnetdevmacvlan.c b/src/util/virnetdevmacvlan.c index 89e221d..2ff24b1 100644 --- a/src/util/virnetdevmacvlan.c +++ b/src/util/virnetdevmacvlan.c @@ -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); 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;
So, I think this is good. My initial testing hasn't revealed anything wrong and nor has the review. ACK with this squashed in: diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 1c0cfb1..aeec440 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -507,9 +507,9 @@ virInterfaceRemove; # conf/netdev_bandwidth_conf.h +virDomainClearNetBandwidth; virNetDevBandwidthFormat; virNetDevBandwidthParse; -virDomainClearNetBandwidth; # conf/netdev_vlan_conf.h diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index e9e0da3..93db1ee 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -4217,7 +4217,7 @@ lxcDomainAttachDeviceNetLive(virConnectPtr conn, /* set network bandwidth */ if (virNetDevSupportBandwidth(actualType) && virNetDevBandwidthSet(net->ifname, - virDomainNetGetActualBandwidth(net), false) < 0) + virDomainNetGetActualBandwidth(net), false) < 0) goto cleanup; if (virNetDevSetNamespace(veth, priv->initpid) < 0) { @@ -4641,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; @@ -4649,10 +4649,14 @@ lxcDomainDetachDeviceNetLive(virDomainObjPtr vm, goto cleanup; detach = vm->def->nets[detachidx]; + actualType = virDomainNetGetActualType(detach); - virDomainClearNetBandwidth(vm); + /* 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) { diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c index 5bbd696..9208f02 100644 --- a/src/lxc/lxc_process.c +++ b/src/lxc/lxc_process.c @@ -455,7 +455,7 @@ static int virLXCProcessSetupInterfaces(virConnectPtr conn, /* set network bandwidth */ if (virNetDevSupportBandwidth(type) && virNetDevBandwidthSet(net->ifname, - virDomainNetGetActualBandwidth(net), false) < 0) + virDomainNetGetActualBandwidth(net), false) < 0) goto cleanup; (*veths)[(*nveths)-1] = veth; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 8025ff6..d2e6991 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -7497,13 +7497,11 @@ qemuBuildInterfaceCommandLine(virCommandPtr cmd, } /* Set Bandwidth */ - if (net->ifname && strlen(net->ifname)) { - if (virNetDevSupportBandwidth(actualType) && - virNetDevBandwidthSet(net->ifname, - virDomainNetGetActualBandwidth(net), - false) < 0) - goto cleanup; - } + 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 || diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 3e7b7da..b00fd8f 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -951,7 +951,7 @@ int qemuDomainAttachNetDevice(virConnectPtr conn, /* Set Bandwidth */ if (virNetDevSupportBandwidth(actualType) && virNetDevBandwidthSet(net->ifname, - virDomainNetGetActualBandwidth(net), false) < 0) + virDomainNetGetActualBandwidth(net), false) < 0) goto cleanup; for (i = 0; i < tapfdSize; i++) { @@ -3555,7 +3555,7 @@ qemuDomainDetachNetDevice(virQEMUDriverPtr driver, if (virNetDevSupportBandwidth(virDomainNetGetActualType(detach)) && virNetDevBandwidthClear(detach->ifname) < 0) VIR_WARN("cannot clear bandwidth setting for device : %s", - detach->ifname); + detach->ifname); qemuDomainMarkDeviceForRemoval(vm, &detach->info); I'm fixing the commit and pushing. Congratulations on your firt libvirt contribution! Michal

2014-11-19 2:55 GMT+03:00 Anirban Chakraborty <abchak@juniper.net>:
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>
Hm. Now in libvirt 1.2.10 patch applied and compiled fine, but when i'm try to run server i get error like: 2014-11-19 15:11:56.110+0000: 33405: error : virNetSocketReadWire:1571 : End of file while reading data: Input/output error 2014-11-19 15:11:57.240+0000: 33405: error : qemuMonitorIO:662 : internal error: End of file from monitor 2014-11-19 15:11:57.753+0000: 33408: error : virCommandWait:2533 : internal error: Child process (tc qdisc add dev tap10339 root handle 1: htb default 1) unexpected exit status 1: Cannot find device "tap10339" Relevant xml part is: <interface type='ethernet'> <mac address='{mac}'/> <model type='virtio'/> <alias name='net0'/> <target dev='tap{name}'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> <rom bar='off'/> <bandwidth> <inbound average="40960" peak="51200"/> <outbound average="40960" peak="51200"/> </bandwidth> </interface> -- Vasiliy Tolstov, e-mail: v.tolstov@selfip.ru jabber: vase@selfip.ru

On 11/19/14, 7:15 AM, "Vasiliy Tolstov" <v.tolstov@selfip.ru> wrote:
2014-11-19 2:55 GMT+03:00 Anirban Chakraborty <abchak@juniper.net>:
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>
Hm. Now in libvirt 1.2.10 patch applied and compiled fine, but when i'm try to run server i get error like: 2014-11-19 15:11:56.110+0000: 33405: error : virNetSocketReadWire:1571 : End of file while reading data: Input/output error 2014-11-19 15:11:57.240+0000: 33405: error : qemuMonitorIO:662 : internal error: End of file from monitor 2014-11-19 15:11:57.753+0000: 33408: error : virCommandWait:2533 : internal error: Child process (tc qdisc add dev tap10339 root handle 1: htb default 1) unexpected exit status 1: Cannot find device "tap10339"
Relevant xml part is: <interface type='ethernet'> <mac address='{mac}'/> <model type='virtio'/> <alias name='net0'/> <target dev='tap{name}'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> <rom bar='off'/> <bandwidth> <inbound average="40960" peak="51200"/> <outbound average="40960" peak="51200"/> </bandwidth> </interface>
The Œethernet¹ interface type assumes that you have an existing tap device. Did you check if the tap device that it is complaining against actually exists in the host? Anirban

2014-11-19 20:17 GMT+03:00 Anirban Chakraborty <abchak@juniper.net>:
The Œethernet¹ interface type assumes that you have an existing tap device. Did you check if the tap device that it is complaining against actually exists in the host?
Yes, but ethernet device type does not always means that device already exists. Before this patch a have devices automatic created with libvirt/qemu for me. -- Vasiliy Tolstov, e-mail: v.tolstov@selfip.ru jabber: vase@selfip.ru

On 11/19/14, 9:23 AM, "Vasiliy Tolstov" <v.tolstov@selfip.ru> wrote:
2014-11-19 20:17 GMT+03:00 Anirban Chakraborty <abchak@juniper.net>:
The Œethernet¹ interface type assumes that you have an existing tap device. Did you check if the tap device that it is complaining against actually exists in the host?
Yes, but ethernet device type does not always means that device already exists. Before this patch a have devices automatic created with libvirt/qemu for me.
The patch didn’t do anything to add/delete tap devices. Please see the following links where similar issue has been discussed. http://wiki.libvirt.org/page/Guest_won%27t_start_-_warning:_could_not_open_ /dev/net/tun_%28%27generic_ethernet%27_interface%29 https://answers.launchpad.net/neutron/+question/179967 Anirban

2014-11-19 20:54 GMT+03:00 Anirban Chakraborty <abchak@juniper.net>:
The patch didn’t do anything to add/delete tap devices. Please see the following links where similar issue has been discussed.
http://wiki.libvirt.org/page/Guest_won%27t_start_-_warning:_could_not_open_ /dev/net/tun_%28%27generic_ethernet%27_interface%29
Please re-read me. I'm already have working setup with automatic created tap devices (i'm use docs from this links and i have qemu runs with root privileges and have all needed config options). But after this patch i have error like i send. Also i have one tc entry added before error: qdisc pfifo_fast 0: dev tap10339 root refcnt 2 bands 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1 I think that this tc entry (that i mentioned i early email) added before tap device created via qemu. May be need to fix ordering.... What do you think? Thanks for help! -- Vasiliy Tolstov, e-mail: v.tolstov@selfip.ru jabber: vase@selfip.ru

On 11/19/14, 2:05 PM, "Vasiliy Tolstov" <v.tolstov@selfip.ru> wrote:
2014-11-19 20:54 GMT+03:00 Anirban Chakraborty <abchak@juniper.net>:
The patch didn¹t do anything to add/delete tap devices. Please see the following links where similar issue has been discussed.
http://wiki.libvirt.org/page/Guest_won%27t_start_-_warning:_could_not_ope n_ /dev/net/tun_%28%27generic_ethernet%27_interface%29
Please re-read me. I'm already have working setup with automatic created tap devices (i'm use docs from this links and i have qemu runs with root privileges and have all needed config options). But after this patch i have error like i send. Also i have one tc entry added before error: qdisc pfifo_fast 0: dev tap10339 root refcnt 2 bands 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
I think that this tc entry (that i mentioned i early email) added before tap device created via qemu. May be need to fix ordering.... What do you think?
Thanks for help!
Your original error message was that qemu couldn¹t find a tap device. So, I am not sure how the above error relates to your original error. Can you write your detail configuration setup and the steps you have taken to get at this error? Anirban

2014-11-20 7:58 GMT+03:00 Anirban Chakraborty <abchak@juniper.net>:
Your original error message was that qemu couldn¹t find a tap device. So, I am not sure how the above error relates to your original error. Can you write your detail configuration setup and the steps you have taken to get at this error?
If i'm not wrong error goes from: qemuBuildInterfaceCommandLine builds interface command line and before qemu started tries to add tap device to tc, but tap created later via qemu (in my case). I think that virNetDevBandwidthSet needs to be run after qemu started. -- Vasiliy Tolstov, e-mail: v.tolstov@selfip.ru jabber: vase@selfip.ru

On 11/20/14, 5:43 AM, "Vasiliy Tolstov" <v.tolstov@selfip.ru> wrote:
2014-11-20 7:58 GMT+03:00 Anirban Chakraborty <abchak@juniper.net>:
Your original error message was that qemu couldn¹t find a tap device. So, I am not sure how the above error relates to your original error. Can you write your detail configuration setup and the steps you have taken to get at this error?
If i'm not wrong error goes from: qemuBuildInterfaceCommandLine builds interface command line and before qemu started tries to add tap device to tc, but tap created later via qemu (in my case). I think that virNetDevBandwidthSet needs to be run after qemu started.
Please look at the code. Tap device is not created for network interface type ethernet. virNetDevTapCreate creates the tap device, which eventually gets called from qemuNetworkIfaceConnect and this applies to interface types network or bridge. For ethernet type interfaces, the onus is on the user to create the tap device in the first place before configuring bandwidth for it. So, there is no point in changing any code here, if the tap device doesn’t exist and the vm configuration file has an entry for it, then libvirt is supposed to throw the error message to let the user know about it. Anirban

21 нояб. 2014 г. 9:07 пользователь "Anirban Chakraborty" <abchak@juniper.net> написал:
On 11/20/14, 5:43 AM, "Vasiliy Tolstov" <v.tolstov@selfip.ru> wrote:
2014-11-20 7:58 GMT+03:00 Anirban Chakraborty <abchak@juniper.net>:
Your original error message was that qemu couldn¹t find a tap device. So, I am not sure how the above error relates to your original error. Can you write your detail configuration setup and the steps you have taken to get at this error?
If i'm not wrong error goes from: qemuBuildInterfaceCommandLine builds interface command line and before qemu started tries to add tap device to tc, but tap created later via qemu (in my case). I think that virNetDevBandwidthSet needs to be run after qemu started.
Please look at the code. Tap device is not created for network interface type ethernet. virNetDevTapCreate creates the tap device, which eventually gets called from qemuNetworkIfaceConnect and this applies to interface types network or bridge. For ethernet type interfaces, the onus is on the user to create the tap device in the first place before configuring bandwidth for it.
So, there is no point in changing any code here, if the tap device doesn’t exist and the vm configuration file has an entry for it, then libvirt is supposed to throw the error message to let the user know about it.
Anirban
No, in this case qemu creates device for me and all works fine.

2014-11-21 11:13 GMT+03:00 Vasiliy Tolstov <v.tolstov@selfip.ru>:
No, in this case qemu creates device for me and all works fine.
If i create patch for libvirt to create tap device if user not specify script, does it acceptable by upstream? Benefits of this patch - that we can create tap device and use it without additional running commands via script. -- Vasiliy Tolstov, e-mail: v.tolstov@selfip.ru jabber: vase@selfip.ru

On 11/24/2014 08:39 AM, Vasiliy Tolstov wrote:
2014-11-21 11:13 GMT+03:00 Vasiliy Tolstov <v.tolstov@selfip.ru>:
No, in this case qemu creates device for me and all works fine.
If i create patch for libvirt to create tap device if user not specify script, does it acceptable by upstream? Benefits of this patch - that we can create tap device and use it without additional running commands via script.
Certainly sounds like a reasonable patch from the description. You're welcome to give it a try. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org
participants (4)
-
Anirban Chakraborty
-
Eric Blake
-
Michal Privoznik
-
Vasiliy Tolstov