From 289939580815c46cc2e162a7e6e232a4977a7950 Mon Sep 17 00:00:00 2001 From: Wei Zhou Date: Thu, 20 Jun 2013 11:30:44 +0200 Subject: [PATCH] CLOUDSTACK-2017: network throttling implementation for KVM --- .../kvm/resource/BridgeVifDriver.java | 14 ++++---- .../kvm/resource/DirectVifDriver.java | 8 +++-- .../kvm/resource/LibvirtDomainXMLParser.java | 15 ++++++--- .../hypervisor/kvm/resource/LibvirtVMDef.java | 32 +++++++++++++++++-- .../hypervisor/kvm/resource/OvsVifDriver.java | 16 ++++++---- 5 files changed, 63 insertions(+), 22 deletions(-) diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/BridgeVifDriver.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/BridgeVifDriver.java index b897df2ecf3..0db83cc5750 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/BridgeVifDriver.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/BridgeVifDriver.java @@ -91,36 +91,38 @@ public class BridgeVifDriver extends VifDriverBase { } String trafficLabel = nic.getName(); if (nic.getType() == Networks.TrafficType.Guest) { + Integer networkRateKBps = (nic.getNetworkRateMbps() != null && nic.getNetworkRateMbps().intValue() != -1)? nic.getNetworkRateMbps().intValue() * 128: 0; if (nic.getBroadcastType() == Networks.BroadcastDomainType.Vlan && !vlanId.equalsIgnoreCase("untagged")) { if(trafficLabel != null && !trafficLabel.isEmpty()) { s_logger.debug("creating a vlan dev and bridge for guest traffic per traffic label " + trafficLabel); String brName = createVlanBr(vlanId, _pifs.get(trafficLabel)); - intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType)); + intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType), networkRateKBps); } else { String brName = createVlanBr(vlanId, _pifs.get("private")); - intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType)); + intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType), networkRateKBps); } } else { - intf.defBridgeNet(_bridges.get("guest"), null, nic.getMac(), getGuestNicModel(guestOsType)); + intf.defBridgeNet(_bridges.get("guest"), null, nic.getMac(), getGuestNicModel(guestOsType), networkRateKBps); } } else if (nic.getType() == Networks.TrafficType.Control) { /* Make sure the network is still there */ createControlNetwork(); intf.defBridgeNet(_bridges.get("linklocal"), null, nic.getMac(), getGuestNicModel(guestOsType)); } else if (nic.getType() == Networks.TrafficType.Public) { + Integer networkRateKBps = (nic.getNetworkRateMbps() != null && nic.getNetworkRateMbps().intValue() != -1)? nic.getNetworkRateMbps().intValue() * 128: 0; if (nic.getBroadcastType() == Networks.BroadcastDomainType.Vlan && !vlanId.equalsIgnoreCase("untagged")) { if(trafficLabel != null && !trafficLabel.isEmpty()){ s_logger.debug("creating a vlan dev and bridge for public traffic per traffic label " + trafficLabel); String brName = createVlanBr(vlanId, _pifs.get(trafficLabel)); - intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType)); + intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType), networkRateKBps); } else { String brName = createVlanBr(vlanId, _pifs.get("public")); - intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType)); + intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType), networkRateKBps); } } else { - intf.defBridgeNet(_bridges.get("public"), null, nic.getMac(), getGuestNicModel(guestOsType)); + intf.defBridgeNet(_bridges.get("public"), null, nic.getMac(), getGuestNicModel(guestOsType), networkRateKBps); } } else if (nic.getType() == Networks.TrafficType.Management) { intf.defBridgeNet(_bridges.get("private"), null, nic.getMac(), getGuestNicModel(guestOsType)); diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/DirectVifDriver.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/DirectVifDriver.java index 1946d74a495..425abbac145 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/DirectVifDriver.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/DirectVifDriver.java @@ -47,12 +47,14 @@ public class DirectVifDriver extends VifDriverBase { LibvirtVMDef.InterfaceDef intf = new LibvirtVMDef.InterfaceDef(); if (nic.getType() == Networks.TrafficType.Guest) { + Integer networkRateKBps = (nic.getNetworkRateMbps() != null && nic.getNetworkRateMbps().intValue() != -1)? nic.getNetworkRateMbps().intValue() * 128: 0; intf.defDirectNet(_libvirtComputingResource.getNetworkDirectDevice(), null, nic.getMac(), getGuestNicModel(guestOsType), - _libvirtComputingResource.getNetworkDirectSourceMode()); + _libvirtComputingResource.getNetworkDirectSourceMode(), networkRateKBps); } else if (nic.getType() == Networks.TrafficType.Public) { + Integer networkRateKBps = (nic.getNetworkRateMbps() != null && nic.getNetworkRateMbps().intValue() != -1)? nic.getNetworkRateMbps().intValue() * 128: 0; intf.defDirectNet(_libvirtComputingResource.getNetworkDirectDevice(), null, nic.getMac(), getGuestNicModel(guestOsType), - _libvirtComputingResource.getNetworkDirectSourceMode()); + _libvirtComputingResource.getNetworkDirectSourceMode(), networkRateKBps); } return intf; @@ -62,4 +64,4 @@ public class DirectVifDriver extends VifDriverBase { // not needed, libvirt will cleanup } -} \ No newline at end of file +} diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtDomainXMLParser.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtDomainXMLParser.java index 8514a5bd270..a283768da41 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtDomainXMLParser.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtDomainXMLParser.java @@ -142,18 +142,25 @@ public class LibvirtDomainXMLParser { String dev = getAttrValue("target", "dev", nic); String model = getAttrValue("model", "type", nic); InterfaceDef def = new InterfaceDef(); - + NodeList bandwidth = nic.getElementsByTagName("bandwidth"); + Integer networkRateKBps = 0; + if ((bandwidth != null) && (bandwidth.getLength() !=0)) { + Integer inbound = Integer.valueOf(getAttrValue("inbound", "average", (Element)bandwidth.item(0))); + Integer outbound = Integer.valueOf(getAttrValue("outbound", "average", (Element)bandwidth.item(0))); + if (inbound == outbound) + networkRateKBps = inbound; + } if (type.equalsIgnoreCase("network")) { String network = getAttrValue("source", "network", nic); def.defPrivateNet(network, dev, mac, - nicModel.valueOf(model.toUpperCase())); + nicModel.valueOf(model.toUpperCase()), networkRateKBps); } else if (type.equalsIgnoreCase("bridge")) { String bridge = getAttrValue("source", "bridge", nic); def.defBridgeNet(bridge, dev, mac, - nicModel.valueOf(model.toUpperCase())); + nicModel.valueOf(model.toUpperCase()), networkRateKBps); } else if (type.equalsIgnoreCase("ethernet")) { String scriptPath = getAttrValue("script", "path", nic); - def.defEthernet(dev, mac, nicModel.valueOf(model.toUpperCase()), scriptPath); + def.defEthernet(dev, mac, nicModel.valueOf(model.toUpperCase()), scriptPath, networkRateKBps); } interfaces.add(def); } diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java index 93b4dfedb62..51208702169 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java @@ -22,8 +22,6 @@ import java.util.List; import java.util.Map; import java.util.UUID; -import com.cloud.utils.script.Script; - public class LibvirtVMDef { private String _hvsType; private static long _libvirtVersion; @@ -719,45 +717,69 @@ public class LibvirtVMDef { private String _ipAddr; private String _scriptPath; private nicModel _model; + private Integer _networkRateKBps; private String _virtualPortType; private String _virtualPortInterfaceId; private int _vlanTag = -1; public void defBridgeNet(String brName, String targetBrName, String macAddr, nicModel model) { + defBridgeNet(brName, targetBrName, macAddr, model, 0); + } + + public void defBridgeNet(String brName, String targetBrName, + String macAddr, nicModel model, Integer networkRateKBps) { _netType = guestNetType.BRIDGE; _sourceName = brName; _networkName = targetBrName; _macAddr = macAddr; _model = model; + _networkRateKBps = networkRateKBps; } public void defDirectNet(String sourceName, String targetName, String macAddr, nicModel model, String sourceMode) { + defDirectNet(sourceName, targetName, macAddr, model, sourceMode, 0); + } + + public void defDirectNet(String sourceName, String targetName, + String macAddr, nicModel model, String sourceMode, Integer networkRateKBps) { _netType = guestNetType.DIRECT; _netSourceMode = sourceMode; _sourceName = sourceName; _networkName = targetName; _macAddr = macAddr; _model = model; + _networkRateKBps = networkRateKBps; } public void defPrivateNet(String networkName, String targetName, String macAddr, nicModel model) { + defPrivateNet(networkName, targetName, macAddr, model, 0); + } + + public void defPrivateNet(String networkName, String targetName, + String macAddr, nicModel model, Integer networkRateKBps) { _netType = guestNetType.NETWORK; _sourceName = networkName; _networkName = targetName; _macAddr = macAddr; _model = model; + _networkRateKBps = networkRateKBps; } public void defEthernet(String targetName, String macAddr, nicModel model, String scriptPath) { + defEthernet(targetName, macAddr, model, scriptPath, 0); + } + + public void defEthernet(String targetName, String macAddr, nicModel model, String scriptPath, Integer networkRateKBps) { _netType = guestNetType.ETHERNET; _networkName = targetName; _sourceName = targetName; _macAddr = macAddr; _model = model; _scriptPath = scriptPath; + _networkRateKBps = networkRateKBps; } public void defEthernet(String targetName, String macAddr, nicModel model) { @@ -836,6 +858,12 @@ public class LibvirtVMDef { if (_model != null) { netBuilder.append("\n"); } + if ((_libvirtVersion >= 9004) && (_networkRateKBps > 0)) { // supported from libvirt 0.9.4 + netBuilder.append("\n"); + netBuilder.append("\n"); + netBuilder.append("\n"); + netBuilder.append("\n"); + } if (_scriptPath != null) { netBuilder.append("