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

Reply via email to