CLOUDSTACK-2017: network throttling implementation for KVM

This commit is contained in:
Wei Zhou 2013-06-20 11:30:44 +02:00
parent 9df45065d0
commit 2899395808
5 changed files with 63 additions and 22 deletions

View File

@ -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));

View File

@ -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
}
}
}

View File

@ -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);
}

View File

@ -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("<model type='" + _model + "'/>\n");
}
if ((_libvirtVersion >= 9004) && (_networkRateKBps > 0)) { // supported from libvirt 0.9.4
netBuilder.append("<bandwidth>\n");
netBuilder.append("<inbound average='" + _networkRateKBps + "' peak='" + _networkRateKBps + "'/>\n");
netBuilder.append("<outbound average='" + _networkRateKBps + "' peak='" + _networkRateKBps + "'/>\n");
netBuilder.append("</bandwidth>\n");
}
if (_scriptPath != null) {
netBuilder.append("<script path='" + _scriptPath + "'/>\n");
}

View File

@ -81,42 +81,44 @@ public class OvsVifDriver 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 || nic.getBroadcastType() == Networks.BroadcastDomainType.Pvlan)
&& !vlanId.equalsIgnoreCase("untagged")) {
if(trafficLabel != null && !trafficLabel.isEmpty()) {
s_logger.debug("creating a vlan dev and bridge for guest traffic per traffic label " + trafficLabel);
intf.defBridgeNet(_pifs.get(trafficLabel), null, nic.getMac(), getGuestNicModel(guestOsType));
intf.defBridgeNet(_pifs.get(trafficLabel), null, nic.getMac(), getGuestNicModel(guestOsType), networkRateKBps);
intf.setVlanTag(Integer.parseInt(vlanId));
} else {
intf.defBridgeNet(_pifs.get("private"), null, nic.getMac(), getGuestNicModel(guestOsType));
intf.defBridgeNet(_pifs.get("private"), null, nic.getMac(), getGuestNicModel(guestOsType), networkRateKBps);
intf.setVlanTag(Integer.parseInt(vlanId));
}
} else if (nic.getBroadcastType() == Networks.BroadcastDomainType.Lswitch) {
s_logger.debug("nic " + nic + " needs to be connected to LogicalSwitch " + logicalSwitchUuid);
intf.setVirtualPortInterfaceId(nic.getUuid());
String brName = (trafficLabel != null && !trafficLabel.isEmpty()) ? _pifs.get(trafficLabel) : _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(_bridges.get("linklocal"));
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);
intf.defBridgeNet(_pifs.get(trafficLabel), null, nic.getMac(), getGuestNicModel(guestOsType));
intf.defBridgeNet(_pifs.get(trafficLabel), null, nic.getMac(), getGuestNicModel(guestOsType), networkRateKBps);
intf.setVlanTag(Integer.parseInt(vlanId));
} else {
intf.defBridgeNet(_pifs.get("public"), null, nic.getMac(), getGuestNicModel(guestOsType));
intf.defBridgeNet(_pifs.get("public"), null, nic.getMac(), getGuestNicModel(guestOsType), networkRateKBps);
intf.setVlanTag(Integer.parseInt(vlanId));
}
} 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));