Lior Vernia has uploaded a new change for review. Change subject: engine: Enforce maximal QoS commitment on interface ......................................................................
engine: Enforce maximal QoS commitment on interface Made sure that no more than 75% of a an interface's capacity can be committed by QoS, as overcommitment may lead to unexpected and potentially destructive behavior. Change-Id: Icc89f4193d6b7b590c6e1e053af74ab23bc77a11 Signed-off-by: Lior Vernia <lver...@redhat.com> --- M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/host/SetupNetworksHelper.java M backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/errors/VdcBllMessages.java M backend/manager/modules/dal/src/main/resources/bundles/AppErrors.properties M frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/AppErrors.java M frontend/webadmin/modules/webadmin/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties 5 files changed, 34 insertions(+), 3 deletions(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/33/34133/1 diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/host/SetupNetworksHelper.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/host/SetupNetworksHelper.java index 9ee7a92..f998361 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/host/SetupNetworksHelper.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/host/SetupNetworksHelper.java @@ -20,6 +20,7 @@ import org.ovirt.engine.core.common.action.SetupNetworksParameters; import org.ovirt.engine.core.common.businessentities.Entities; import org.ovirt.engine.core.common.businessentities.VDS; +import org.ovirt.engine.core.common.businessentities.network.HostNetworkQos; import org.ovirt.engine.core.common.businessentities.network.Network; import org.ovirt.engine.core.common.businessentities.network.NetworkBootProtocol; import org.ovirt.engine.core.common.businessentities.network.VdsNetworkInterface; @@ -35,6 +36,7 @@ import org.ovirt.engine.core.utils.log.LogFactory; public class SetupNetworksHelper { + private static final float QOS_OVERCOMMITMENT_THRESHOLD = 0.75f; protected static final String VIOLATING_ENTITIES_LIST_FORMAT = "${0}_LIST {1}"; private static final Log log = LogFactory.getLog(SetupNetworksHelper.class); private SetupNetworksParameters params; @@ -50,7 +52,7 @@ private List<VdsNetworkInterface> modifiedInterfaces = new ArrayList<>(); /** All interface`s names that were processed by the helper. */ - private Set<String> ifaceNames = new HashSet<String>(); + private Map<String, VdsNetworkInterface> ifaceByNames = new HashMap<>(); /** Map of all bonds which were processed by the helper. Key = bond name, Value = list of slave NICs. */ private Map<String, List<VdsNetworkInterface>> bonds = new HashMap<String, List<VdsNetworkInterface>>(); @@ -252,6 +254,7 @@ private void validateNetworkQos() { Set<String> someSubInterfacesHaveQos = new HashSet<>(); Set<String> notAllSubInterfacesHaveQos = new HashSet<>(); + Map<String, Float> interfaceCommitment = new HashMap<>(); for (VdsNetworkInterface iface : params.getInterfaces()) { String networkName = iface.getNetworkName(); @@ -263,6 +266,20 @@ String baseIfaceName = NetworkUtils.stripVlan(iface); if (NetworkUtils.qosConfiguredOnInterface(iface, network)) { someSubInterfacesHaveQos.add(baseIfaceName); + + HostNetworkQos qos = + iface.isQosOverridden() ? iface.getQos() : getDbFacade().getHostNetworkQosDao() + .get(network.getQosId()); + Float totalCommitted = interfaceCommitment.get(baseIfaceName); + if (totalCommitted == null) { + totalCommitted = new Float(0); + interfaceCommitment.put(baseIfaceName, totalCommitted); + } + Integer commitment = qos.getOutAverageRealtime(); + if (commitment != null) { + totalCommitted += (float) commitment / ifaceByNames.get(baseIfaceName).getSpeed(); + } + if (iface.isQosOverridden()) { if (!hostNetworkQosSupported) { addViolation(VdcBllMessages.ACTION_TYPE_FAILED_HOST_NETWORK_QOS_NOT_SUPPORTED, networkName); @@ -286,6 +303,12 @@ for (String ifaceName : someSubInterfacesHaveQos) { if (notAllSubInterfacesHaveQos.contains(ifaceName)) { addViolation(VdcBllMessages.ACTION_TYPE_FAILED_HOST_NETWORK_QOS_INTERFACES_WITHOUT_QOS, ifaceName); + } + } + + for (Map.Entry<String, Float> entry : interfaceCommitment.entrySet()) { + if (entry.getValue() > QOS_OVERCOMMITMENT_THRESHOLD) { + addViolation(VdcBllMessages.ACTION_TYPE_FAILED_HOST_NETWORK_QOS_OVERCOMMITMENT, entry.getKey()); } } } @@ -360,6 +383,8 @@ StringUtils.join(v.getValue(), ", "))); } + violationMessages.add("$commitmentThreshold " + 100 * QOS_OVERCOMMITMENT_THRESHOLD); + return violationMessages; } @@ -371,12 +396,12 @@ * @return <code>true</code> if interface wasn't in the list and was added to it, otherwise <code>false</code>. */ private boolean addInterfaceToProcessedList(VdsNetworkInterface iface) { - if (ifaceNames.contains(iface.getName())) { + if (ifaceByNames.containsKey(iface.getName())) { addViolation(VdcBllMessages.NETWORK_INTERFACES_ALREADY_SPECIFIED, iface.getName()); return false; } - ifaceNames.add(iface.getName()); + ifaceByNames.put(iface.getName(), iface); return true; } diff --git a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/errors/VdcBllMessages.java b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/errors/VdcBllMessages.java index 61e6031..f3bd4e5 100644 --- a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/errors/VdcBllMessages.java +++ b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/errors/VdcBllMessages.java @@ -1003,6 +1003,7 @@ ACTION_TYPE_FAILED_HOST_NETWORK_QOS_INCONSISTENT_VALUES(ErrorType.BAD_PARAMETERS), ACTION_TYPE_FAILED_HOST_NETWORK_QOS_SETUP_NETWORKS_INCONSISTENT_VALUES(ErrorType.BAD_PARAMETERS), ACTION_TYPE_FAILED_HOST_NETWORK_QOS_INTERFACES_WITHOUT_QOS(ErrorType.BAD_PARAMETERS), + ACTION_TYPE_FAILED_HOST_NETWORK_QOS_OVERCOMMITMENT(ErrorType.CONSTRAINT_VIOLATION), // Alignment scan ERROR_CANNOT_RUN_ALIGNMENT_SCAN_VM_IS_RUNNING(ErrorType.CONFLICT), diff --git a/backend/manager/modules/dal/src/main/resources/bundles/AppErrors.properties b/backend/manager/modules/dal/src/main/resources/bundles/AppErrors.properties index 6aa075f..d1537dd 100644 --- a/backend/manager/modules/dal/src/main/resources/bundles/AppErrors.properties +++ b/backend/manager/modules/dal/src/main/resources/bundles/AppErrors.properties @@ -1149,6 +1149,7 @@ ACTION_TYPE_FAILED_HOST_NETWORK_QOS_INCONSISTENT_VALUES=Cannot ${action} ${type}. If both are provided, rate limit must not be lower than committed rate. ACTION_TYPE_FAILED_HOST_NETWORK_QOS_SETUP_NETWORKS_INCONSISTENT_VALUES=Cannot ${action} ${type}. If both are provided, rate limit must not be lower than committed rate. However, this is not the case with the following network(s): ${ACTION_TYPE_FAILED_HOST_NETWORK_QOS_SETUP_NETWORKS_INCONSISTENT_VALUES_LIST}. ACTION_TYPE_FAILED_HOST_NETWORK_QOS_INTERFACES_WITHOUT_QOS=Cannot ${action} ${type}. All or none of the networks attached to an interface must have QoS configured, but on the following interface(s) some of the networks are missing QoS: ${ACTION_TYPE_FAILED_HOST_NETWORK_QOS_INTERFACES_WITHOUT_QOS_LIST}. +ACTION_TYPE_FAILED_HOST_NETWORK_QOS_OVERCOMMITMENT=Cannot ${action} ${type}. The overall committed rate on a single interface must not exceed %{commitmentThreshold}% of the interface's speed, but exceeds this threshold on the following interface(s): ${ACTION_TYPE_FAILED_HOST_NETWORK_QOS_OVERCOMMITMENT_LIST}. QOS_NAME_NOT_NULL=QoS name cannot be empty. QOS_NAME_INVALID=Invalid QoS name (name must be formed of "a-z0-9A-Z" or "-_ ") QOS_NAME_TOO_LONG=QoS name length must be under 50 characters. diff --git a/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/AppErrors.java b/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/AppErrors.java index a8b4872..4a8bbb0 100644 --- a/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/AppErrors.java +++ b/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/AppErrors.java @@ -3095,6 +3095,9 @@ @DefaultStringValue("Cannot ${action} ${type}. All or none of the networks attached to an interface must have QoS configured, but on the following interface(s) some of the networks are missing QoS: ${ACTION_TYPE_FAILED_HOST_NETWORK_QOS_INTERFACES_WITHOUT_QOS_LIST}.") String ACTION_TYPE_FAILED_HOST_NETWORK_QOS_INTERFACES_WITHOUT_QOS(); + @DefaultStringValue("Cannot ${action} ${type}. The overall committed rate on a single interface must not exceed %{commitmentThreshold}% of the interface's speed, but exceeds this threshold on the following interface(s): ${ACTION_TYPE_FAILED_HOST_NETWORK_QOS_OVERCOMMITMENT_LIST}.") + String ACTION_TYPE_FAILED_HOST_NETWORK_QOS_OVERCOMMITMENT(); + @DefaultStringValue("Cannot ${action} ${type}. Values are out of range.") String ACTION_TYPE_FAILED_QOS_OUT_OF_RANGE_VALUES(); diff --git a/frontend/webadmin/modules/webadmin/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties b/frontend/webadmin/modules/webadmin/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties index 350fe34..68e4790 100644 --- a/frontend/webadmin/modules/webadmin/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties +++ b/frontend/webadmin/modules/webadmin/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties @@ -1118,6 +1118,7 @@ ACTION_TYPE_FAILED_HOST_NETWORK_QOS_INCONSISTENT_VALUES=Cannot ${action} ${type}. If both are provided, rate limit must not be lower than committed rate. ACTION_TYPE_FAILED_HOST_NETWORK_QOS_SETUP_NETWORKS_INCONSISTENT_VALUES=Cannot ${action} ${type}. If both are provided, rate limit must not be lower than committed rate. However, this is not the case with the following network(s): ${ACTION_TYPE_FAILED_HOST_NETWORK_QOS_SETUP_NETWORKS_INCONSISTENT_VALUES_LIST}. ACTION_TYPE_FAILED_HOST_NETWORK_QOS_INTERFACES_WITHOUT_QOS=Cannot ${action} ${type}. All or none of the networks attached to an interface must have QoS configured, but on the following interface(s) some of the networks are missing QoS: ${ACTION_TYPE_FAILED_HOST_NETWORK_QOS_INTERFACES_WITHOUT_QOS_LIST}. +ACTION_TYPE_FAILED_HOST_NETWORK_QOS_OVERCOMMITMENT=Cannot ${action} ${type}. The overall committed rate on a single interface must not exceed %{commitmentThreshold}% of the interface's speed, but exceeds this threshold on the following interface(s): ${ACTION_TYPE_FAILED_HOST_NETWORK_QOS_OVERCOMMITMENT_LIST}. QOS_NAME_NOT_NULL=QoS name cannot be empty. QOS_NAME_INVALID=Invalid QoS name (name must be formed of "a-z0-9A-Z" or "-_ ") QOS_NAME_TOO_LONG=QoS name length must be under 50 characters. -- To view, visit http://gerrit.ovirt.org/34133 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Icc89f4193d6b7b590c6e1e053af74ab23bc77a11 Gerrit-PatchSet: 1 Gerrit-Project: ovirt-engine Gerrit-Branch: master Gerrit-Owner: Lior Vernia <lver...@redhat.com> _______________________________________________ Engine-patches mailing list Engine-patches@ovirt.org http://lists.ovirt.org/mailman/listinfo/engine-patches