Roy Golan has uploaded a new change for review.

Change subject: core: use NumaPlacement instead of weird Pairs
......................................................................

core: use NumaPlacement instead of weird Pairs

reflect the VM's numa runtime placemtn using NumaPlacement with
attributes of Physical Numa Id, pinnid, and index.

Change-Id: I27a8f369e9896faeddd1e361ec884bf2c049b98f
Signed-off-by: Roy Golan <[email protected]>
---
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VmHandler.java
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/numa/vm/AbstractVmNumaNodeCommand.java
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/numa/vm/AddVmNumaNodesCommand.java
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/numa/vm/UpdateVmNumaNodesCommand.java
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/policyunits/MemoryPolicyUnit.java
M 
backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/NumaPlacement.java
M 
backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VmNumaNode.java
M 
backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/VdsNumaNodeDAODbFacadeImpl.java
M 
backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/VmNumaNodeDAODbFacadeImpl.java
M 
backend/manager/modules/dal/src/test/java/org/ovirt/engine/core/dao/VmNumaNodeDAOTest.java
M 
backend/manager/modules/restapi/types/src/main/java/org/ovirt/engine/api/restapi/types/NumaMapper.java
M 
backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/NumaUtils.java
M 
backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/ResourceManager.java
M 
backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/VmAnalyzer.java
M 
backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/NumaSettingFactory.java
M 
backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/VdsBrokerObjectsBuilder.java
M 
backend/manager/modules/vdsbroker/src/test/java/org/ovirt/engine/core/vdsbroker/vdsbroker/NumaSettingFactoryTest.java
M 
frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/view/popup/numa/NumaSupportPopupView.java
M 
frontend/webadmin/modules/gwt-common/src/main/resources/org/ovirt/engine/core/Common.gwt.xml
M 
frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/builders/vm/NumaUnitToVmBaseBuilder.java
M 
frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/hosts/numa/NumaSupportModel.java
M 
frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/hosts/numa/VNodeModel.java
22 files changed, 189 insertions(+), 197 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/48/38048/1

diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VmHandler.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VmHandler.java
index c3479e8..f3ee25c 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VmHandler.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VmHandler.java
@@ -870,16 +870,6 @@
                 && 
vmNumaNodes.get(0).getNumaPlacements().iterator().next().isPinned()) {
             return ValidationResult.VALID;
         }
-            if
-            List<Pair<Guid, Pair<Boolean, Integer>>> vdsNumaNodeList = 
vmNumaNodes.get(0).getVdsNumaNodeList();
-            boolean pinnedToSingleNode = vdsNumaNodeList != null
-                    && vdsNumaNodeList.size() == 1
-                    && vdsNumaNodeList.get(0).getSecond() != null
-                    && vdsNumaNodeList.get(0).getSecond().getFirst();
-            if (pinnedToSingleNode) {
-                return ValidationResult.VALID;
-            }
-        }
 
         return new 
ValidationResult(VdcBllMessages.VM_NUMA_NODE_PREFERRED_NOT_PINNED_TO_SINGLE_NODE);
     }
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/numa/vm/AbstractVmNumaNodeCommand.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/numa/vm/AbstractVmNumaNodeCommand.java
index 5c09b37..338c763 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/numa/vm/AbstractVmNumaNodeCommand.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/numa/vm/AbstractVmNumaNodeCommand.java
@@ -14,7 +14,6 @@
 import org.ovirt.engine.core.common.config.Config;
 import org.ovirt.engine.core.common.config.ConfigValues;
 import org.ovirt.engine.core.common.errors.VdcBllMessages;
-import org.ovirt.engine.core.common.utils.Pair;
 import org.ovirt.engine.core.compat.Guid;
 import org.ovirt.engine.core.dao.VdsNumaNodeDAO;
 import org.ovirt.engine.core.dao.VmNumaNodeDAO;
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/numa/vm/AddVmNumaNodesCommand.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/numa/vm/AddVmNumaNodesCommand.java
index cd0aadf..669b889 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/numa/vm/AddVmNumaNodesCommand.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/numa/vm/AddVmNumaNodesCommand.java
@@ -10,7 +10,6 @@
 import org.ovirt.engine.core.common.businessentities.NumaPlacement;
 import org.ovirt.engine.core.common.businessentities.VdsNumaNode;
 import org.ovirt.engine.core.common.businessentities.VmNumaNode;
-import org.ovirt.engine.core.common.utils.Pair;
 import org.ovirt.engine.core.compat.Guid;
 
 public class AddVmNumaNodesCommand<T extends VmNumaNodeOperationParameters> 
extends AbstractVmNumaNodeCommand<T> {
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/numa/vm/UpdateVmNumaNodesCommand.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/numa/vm/UpdateVmNumaNodesCommand.java
index 7aacd26..631cd99 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/numa/vm/UpdateVmNumaNodesCommand.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/numa/vm/UpdateVmNumaNodesCommand.java
@@ -10,7 +10,6 @@
 import org.ovirt.engine.core.common.businessentities.NumaPlacement;
 import org.ovirt.engine.core.common.businessentities.VdsNumaNode;
 import org.ovirt.engine.core.common.businessentities.VmNumaNode;
-import org.ovirt.engine.core.common.utils.Pair;
 import org.ovirt.engine.core.compat.Guid;
 
 public class UpdateVmNumaNodesCommand<T extends VmNumaNodeOperationParameters> 
extends AbstractVmNumaNodeCommand<T> {
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/policyunits/MemoryPolicyUnit.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/policyunits/MemoryPolicyUnit.java
index f37470f..b4a343e 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/policyunits/MemoryPolicyUnit.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/policyunits/MemoryPolicyUnit.java
@@ -18,8 +18,6 @@
 import org.ovirt.engine.core.common.errors.VdcBllMessages;
 import org.ovirt.engine.core.common.scheduling.PerHostMessages;
 import org.ovirt.engine.core.common.scheduling.PolicyUnit;
-import org.ovirt.engine.core.common.utils.Pair;
-import org.ovirt.engine.core.compat.Guid;
 import org.ovirt.engine.core.dal.dbbroker.DbFacade;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
diff --git 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/NumaPlacement.java
 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/NumaPlacement.java
index 7a43eb1..07f84de 100644
--- 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/NumaPlacement.java
+++ 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/NumaPlacement.java
@@ -3,7 +3,7 @@
 import org.ovirt.engine.core.compat.Guid;
 
 /**
- * A representation of the phisical Numa node, its mode and index. A Virtual 
Node can have
+ * A representation of the physical Numa node, its mode and index. A Virtual 
Node can have
  * a set of those, depending on the configuration.
  */
 public class NumaPlacement {
@@ -21,12 +21,19 @@
      */
     private int index;
 
+    public NumaPlacement() {
+    }
+
     public NumaPlacement(Guid physicalNodeId, Mode mode, int index) {
         this.physicalNodeId = physicalNodeId;
         this.mode = mode;
         this.index = index;
     }
 
+    public NumaPlacement(Guid physicalNodeId, boolean pinned, int index) {
+        this(physicalNodeId, pinned ? Mode.PINNED : Mode.NON_PINNED, index);
+    }
+
     public Guid getPhysicalNodeId() {
         return physicalNodeId;
     }
diff --git 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VmNumaNode.java
 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VmNumaNode.java
index a7d57c2..0084c92 100644
--- 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VmNumaNode.java
+++ 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VmNumaNode.java
@@ -1,12 +1,8 @@
 package org.ovirt.engine.core.common.businessentities;
 
-import java.util.ArrayList;
 import java.util.HashSet;
-import java.util.List;
 import java.util.Set;
 
-import org.ovirt.engine.core.common.utils.Pair;
-import org.ovirt.engine.core.compat.Guid;
 
 /**
  * Object which represents vm virtual NUMA node information
@@ -16,19 +12,8 @@
 
     private static final long serialVersionUID = -5384287037435972730L;
 
-    private List<Pair<Guid, Pair<Boolean, Integer>>> vdsNumaNodeList;
-
     public VmNumaNode() {
-        setVdsNumaNodeList(new ArrayList<Pair<Guid, Pair<Boolean, 
Integer>>>());
         numaPlacements = new HashSet<>();
-    }
-
-    /**
-     * @return vNUMA node pair list; first is the pNUMA node uuid,
-     *         second is a pair(boolean for pinned or not (TRUE=pinned), 
integer for pNUMA node index)
-     */
-    public List<Pair<Guid, Pair<Boolean, Integer>>> getVdsNumaNodeList() {
-        return vdsNumaNodeList;
     }
 
     private Set<NumaPlacement> numaPlacements;
@@ -37,17 +22,12 @@
         return numaPlacements;
     }
 
-
-    public void setVdsNumaNodeList(List<Pair<Guid, Pair<Boolean, Integer>>> 
vdsNumaNodeList) {
-        this.vdsNumaNodeList = vdsNumaNodeList;
-    }
-
     @Override
     public int hashCode() {
         final int prime = 31;
         int result = super.hashCode();
         result = prime * result
-                + ((vdsNumaNodeList == null) ? 0 : vdsNumaNodeList.hashCode());
+                + ((numaPlacements == null) ? 0 : numaPlacements.hashCode());
         return result;
     }
 
@@ -60,12 +40,16 @@
         if (getClass() != obj.getClass())
             return false;
         VmNumaNode other = (VmNumaNode) obj;
-        if (vdsNumaNodeList == null) {
-            if (other.vdsNumaNodeList != null)
+        if (numaPlacements == null) {
+            if (other.numaPlacements != null)
                 return false;
-        } else if (!vdsNumaNodeList.equals(other.vdsNumaNodeList))
+        } else if (!numaPlacements.equals(other.numaPlacements))
             return false;
         return true;
     }
 
+    public void setNumaPlacements(Set<NumaPlacement> numaPlacements) {
+        this.numaPlacements = numaPlacements;
+
+    }
 }
diff --git 
a/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/VdsNumaNodeDAODbFacadeImpl.java
 
b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/VdsNumaNodeDAODbFacadeImpl.java
index 1ad96ee..e843962 100644
--- 
a/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/VdsNumaNodeDAODbFacadeImpl.java
+++ 
b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/VdsNumaNodeDAODbFacadeImpl.java
@@ -10,6 +10,7 @@
 
 import org.apache.commons.lang.StringUtils;
 import org.ovirt.engine.core.common.businessentities.NumaNodeStatistics;
+import org.ovirt.engine.core.common.businessentities.NumaPlacement;
 import org.ovirt.engine.core.common.businessentities.VdsNumaNode;
 import org.ovirt.engine.core.common.businessentities.VmNumaNode;
 import org.ovirt.engine.core.common.utils.Pair;
@@ -64,8 +65,8 @@
                 
numaNodeCpusExecutions.add(createNumaNodeCpusParametersMapper(node, cpuId));
             }
             if (node instanceof VmNumaNode) {
-                for (Pair<Guid, Pair<Boolean, Integer>> pair : 
((VmNumaNode)node).getVdsNumaNodeList()) {
-                    
vNodeToPnodeExecutions.add(createVnodeToPnodeParametersMapper(pair, 
node.getId()));
+                for (NumaPlacement placement : ((VmNumaNode) 
node).getNumaPlacements()) {
+                    
vNodeToPnodeExecutions.add(createVnodeToPnodeParametersMapper(node.getId(), 
placement));
                 }
             }
         }
@@ -102,8 +103,8 @@
             }
             if (node instanceof VmNumaNode) {
                 
vNodeToPnodeDeletions.add(getCustomMapSqlParameterSource().addValue("vm_numa_node_id",
 node.getId()));
-                for (Pair<Guid, Pair<Boolean, Integer>> pair : 
((VmNumaNode)node).getVdsNumaNodeList()) {
-                    
vNodeToPnodeInsertions.add(createVnodeToPnodeParametersMapper(pair, 
node.getId()));
+                for (NumaPlacement placement : 
((VmNumaNode)node).getNumaPlacements()) {
+                    
vNodeToPnodeInsertions.add(createVnodeToPnodeParametersMapper(node.getId(), 
placement));
                 }
             }
         }
@@ -154,14 +155,13 @@
                 .addValue("cpu_core_id", cpuId);
     }
 
-    protected MapSqlParameterSource createVnodeToPnodeParametersMapper(
-            Pair<Guid, Pair<Boolean, Integer>> pNode, Guid vNodeId) {
+    protected MapSqlParameterSource createVnodeToPnodeParametersMapper(Guid 
vNodeId, NumaPlacement placement) {
         return getCustomMapSqlParameterSource()
                 .addValue("id", Guid.newGuid())
                 .addValue("vm_numa_node_id", vNodeId)
-                .addValue("vds_numa_node_id", pNode.getFirst())
-                .addValue("vds_numa_node_index", pNode.getSecond().getSecond())
-                .addValue("is_pinned", pNode.getSecond().getFirst());
+                .addValue("vds_numa_node_id", placement.getPhysicalNodeId())
+                .addValue("vds_numa_node_index", placement.getIndex())
+                .addValue("is_pinned", placement.isPinned());
     }
 
     private static final RowMapper<VdsNumaNode> vdsNumaNodeRowMapper =
diff --git 
a/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/VmNumaNodeDAODbFacadeImpl.java
 
b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/VmNumaNodeDAODbFacadeImpl.java
index 9f942c4..5c33431 100644
--- 
a/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/VmNumaNodeDAODbFacadeImpl.java
+++ 
b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/VmNumaNodeDAODbFacadeImpl.java
@@ -4,9 +4,12 @@
 import java.sql.SQLException;
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
+import org.ovirt.engine.core.common.businessentities.NumaPlacement;
 import org.ovirt.engine.core.common.businessentities.VmNumaNode;
 import org.ovirt.engine.core.common.utils.Pair;
 import org.ovirt.engine.core.compat.Guid;
@@ -38,14 +41,14 @@
             numaNodesCpusMap.get(pair.getFirst()).add(pair.getSecond());
         }
 
-        Map<Guid, List<Pair<Guid, Pair<Boolean, Integer>>>> vmNumaNodesPinMap 
= getAllVmNumaNodePinInfo();
+        Map<Guid, Set<NumaPlacement>> vmNumaNodesPinMap = 
getAllVmNumaNodePinInfo();
 
         for (VmNumaNode node : vmNumaNodes) {
             if (numaNodesCpusMap.containsKey(node.getId())) {
                 node.setCpuIds(numaNodesCpusMap.get(node.getId()));
             }
             if (vmNumaNodesPinMap.containsKey(node.getId())) {
-                node.setVdsNumaNodeList(vmNumaNodesPinMap.get(node.getId()));
+                node.setNumaPlacements(vmNumaNodesPinMap.get(node.getId()));
             }
         }
 
@@ -64,14 +67,14 @@
 
         Map<Guid, List<Integer>> numaNodesCpusMap = getAllNumaNodeCpuMap();
 
-        Map<Guid, List<Pair<Guid, Pair<Boolean, Integer>>>> vmNumaNodesPinMap 
= getAllVmNumaNodePinInfo();
+        Map<Guid, Set<NumaPlacement>> vmNumaNodesPinMap = 
getAllVmNumaNodePinInfo();
 
         for (VmNumaNode node : vmNumaNodes) {
             if (numaNodesCpusMap.containsKey(node.getId())) {
                 node.setCpuIds(numaNodesCpusMap.get(node.getId()));
             }
             if (vmNumaNodesPinMap.containsKey(node.getId())) {
-                node.setVdsNumaNodeList(vmNumaNodesPinMap.get(node.getId()));
+                node.setNumaPlacements(vmNumaNodesPinMap.get(node.getId()));
             }
         }
 
@@ -95,16 +98,16 @@
         return numaNodesCpusMap;
     }
 
-    private Map<Guid, List<Pair<Guid, Pair<Boolean, Integer>>>> 
getAllVmNumaNodePinInfo() {
-        List<Pair<Guid, Pair<Guid, Pair<Boolean, Integer>>>> numaNodesAssign =
+    private Map<Guid, Set<NumaPlacement>> getAllVmNumaNodePinInfo() {
+        List<Pair<Guid, NumaPlacement>> numaNodesAssign =
                 
getCallsHandler().executeReadList("GetAllAssignedNumaNodeInfomation",
                         vmNumaNodeAssignmentRowMapper, null);
 
-        Map<Guid, List<Pair<Guid, Pair<Boolean, Integer>>>> vmNumaNodesPinMap 
= new HashMap<>();
+        Map<Guid, Set<NumaPlacement>> vmNumaNodesPinMap = new HashMap<>();
 
-        for (Pair<Guid, Pair<Guid, Pair<Boolean, Integer>>> pair : 
numaNodesAssign) {
+        for (Pair<Guid, NumaPlacement> pair : numaNodesAssign) {
             if (!vmNumaNodesPinMap.containsKey(pair.getFirst())) {
-                vmNumaNodesPinMap.put(pair.getFirst(), new 
ArrayList<Pair<Guid, Pair<Boolean, Integer>>>());
+                vmNumaNodesPinMap.put(pair.getFirst(), new 
HashSet<NumaPlacement>());
             }
 
             vmNumaNodesPinMap.get(pair.getFirst()).add(pair.getSecond());
@@ -160,16 +163,18 @@
                 }
             };
 
-    private static final RowMapper<Pair<Guid, Pair<Guid, Pair<Boolean, 
Integer>>>> vmNumaNodeAssignmentRowMapper =
-            new RowMapper<Pair<Guid, Pair<Guid, Pair<Boolean, Integer>>>>() {
+    private static final RowMapper<Pair<Guid, NumaPlacement>> 
vmNumaNodeAssignmentRowMapper =
+            new RowMapper<Pair<Guid, NumaPlacement>>() {
 
                 @Override
-                public Pair<Guid, Pair<Guid, Pair<Boolean, Integer>>> 
mapRow(ResultSet rs, int rowNum)
+                public Pair<Guid, NumaPlacement> mapRow(ResultSet rs, int 
rowNum)
                         throws SQLException {
-                    return new Pair<>(getGuid(rs, "assigned_vm_numa_node_id"),
-                            new Pair<>(getGuid(rs, "run_in_vds_numa_node_id"),
-                                    new Pair<>(rs.getBoolean("is_pinned"),
-                                    rs.getInt("run_in_vds_numa_node_index"))));
+                    return new Pair<>(
+                            getGuid(rs, "assigned_vm_numa_node_id"),
+                            new NumaPlacement(
+                                    getGuid(rs, "run_in_vds_numa_node_id"),
+                                    rs.getBoolean("is_pinned"),
+                                    rs.getInt("run_in_vds_numa_node_index")));
                 }
             };
 
@@ -184,14 +189,14 @@
 
         Map<Guid, List<Integer>> numaNodesCpusMap = getAllNumaNodeCpuMap();
 
-        Map<Guid, List<Pair<Guid, Pair<Boolean, Integer>>>> vmNumaNodesPinMap 
= getAllVmNumaNodePinInfo();
+        Map<Guid, Set<NumaPlacement>> vmNumaNodesPinMap = 
getAllVmNumaNodePinInfo();
 
         for (VmNumaNode node : vmNumaNodes) {
             if (numaNodesCpusMap.containsKey(node.getId())) {
                 node.setCpuIds(numaNodesCpusMap.get(node.getId()));
             }
             if (vmNumaNodesPinMap.containsKey(node.getId())) {
-                node.setVdsNumaNodeList(vmNumaNodesPinMap.get(node.getId()));
+                node.setNumaPlacements(vmNumaNodesPinMap.get(node.getId()));
             }
         }
 
@@ -209,14 +214,14 @@
 
         Map<Guid, List<Integer>> numaNodesCpusMap = getAllNumaNodeCpuMap();
 
-        Map<Guid, List<Pair<Guid, Pair<Boolean, Integer>>>> vmNumaNodesPinMap 
= getAllVmNumaNodePinInfo();
+        Map<Guid, Set<NumaPlacement>> vmNumaNodesPinMap = 
getAllVmNumaNodePinInfo();
 
         for (Pair<Guid, VmNumaNode> pair : vmNumaNodes) {
             if (numaNodesCpusMap.containsKey(pair.getSecond().getId())) {
                 
pair.getSecond().setCpuIds(numaNodesCpusMap.get(pair.getSecond().getId()));
             }
             if (vmNumaNodesPinMap.containsKey(pair.getSecond().getId())) {
-                
pair.getSecond().setVdsNumaNodeList(vmNumaNodesPinMap.get(pair.getSecond().getId()));
+                
pair.getSecond().setNumaPlacements(vmNumaNodesPinMap.get(pair.getSecond().getId()));
             }
         }
 
@@ -238,9 +243,9 @@
         List<MapSqlParameterSource> vNodeToPnodeInsertions = new ArrayList<>();
         for (VmNumaNode node : vmNumaNodes) {
             
vNodeToPnodeDeletions.add(getCustomMapSqlParameterSource().addValue("vm_numa_node_id",
 node.getId()));
-            for (Pair<Guid, Pair<Boolean, Integer>> pair : 
node.getVdsNumaNodeList()) {
-                if (!pair.getSecond().getFirst()) {
-                    
vNodeToPnodeInsertions.add(createVnodeToPnodeParametersMapper(pair, 
node.getId()));
+            for (NumaPlacement placement : node.getNumaPlacements()) {
+                if (!placement.isPinned()) {
+                    
vNodeToPnodeInsertions.add(createVnodeToPnodeParametersMapper(node.getId(), 
placement));
                 }
             }
         }
diff --git 
a/backend/manager/modules/dal/src/test/java/org/ovirt/engine/core/dao/VmNumaNodeDAOTest.java
 
b/backend/manager/modules/dal/src/test/java/org/ovirt/engine/core/dao/VmNumaNodeDAOTest.java
index 4256294..ea37bbd 100644
--- 
a/backend/manager/modules/dal/src/test/java/org/ovirt/engine/core/dao/VmNumaNodeDAOTest.java
+++ 
b/backend/manager/modules/dal/src/test/java/org/ovirt/engine/core/dao/VmNumaNodeDAOTest.java
@@ -9,11 +9,13 @@
 
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
 import org.junit.Test;
 import org.ovirt.engine.core.common.businessentities.NumaNodeStatistics;
+import org.ovirt.engine.core.common.businessentities.NumaPlacement;
 import org.ovirt.engine.core.common.businessentities.VdsNumaNode;
 import org.ovirt.engine.core.common.businessentities.VmNumaNode;
 import org.ovirt.engine.core.common.businessentities.VmStatic;
@@ -61,13 +63,15 @@
         assertTrue(nodes.containsKey(vmNumaNode1));
         assertTrue(nodes.containsKey(vmNumaNode2));
 
-        assertEquals(2, nodes.get(vmNumaNode1).getVdsNumaNodeList().size());
-        assertEquals(true, 
nodes.get(vmNumaNode1).getVdsNumaNodeList().get(0).getSecond().getFirst());
-        assertEquals(true, 
nodes.get(vmNumaNode1).getVdsNumaNodeList().get(1).getSecond().getFirst());
+        assertEquals(2, nodes.get(vmNumaNode1).getNumaPlacements().size());
+        Iterator<NumaPlacement> iterator = 
nodes.get(vmNumaNode1).getNumaPlacements().iterator();
+        assertEquals(true, iterator.next().isPinned());
+        assertEquals(true, iterator.next().isPinned());
 
-        assertEquals(1, nodes.get(vmNumaNode2).getVdsNumaNodeList().size());
-        assertEquals(false, 
nodes.get(vmNumaNode2).getVdsNumaNodeList().get(0).getSecond().getFirst());
-        assertEquals(0, 
nodes.get(vmNumaNode2).getVdsNumaNodeList().get(0).getSecond().getSecond().intValue());
+        assertEquals(1, nodes.get(vmNumaNode2).getNumaPlacements().size());
+        NumaPlacement pl = 
nodes.get(vmNumaNode2).getNumaPlacements().iterator().next();
+        assertEquals(false, pl.isPinned());
+        assertEquals(0, pl.getIndex());
     }
 
     @Test
@@ -80,9 +84,10 @@
         assertEquals(1, result.size());
 
         assertEquals(vmNumaNode1, result.get(0).getId());
-        assertEquals(vdsNumaNodeId, 
result.get(0).getVdsNumaNodeList().get(0).getFirst());
-        assertEquals(true, 
result.get(0).getVdsNumaNodeList().get(0).getSecond().getFirst());
-        assertEquals(0, 
result.get(0).getVdsNumaNodeList().get(0).getSecond().getSecond().intValue());
+        NumaPlacement placement = 
result.get(0).getNumaPlacements().iterator().next();
+        assertEquals(vdsNumaNodeId, placement.getPhysicalNodeId());
+        assertEquals(true, placement.isPinned());
+        assertEquals(0, placement.getIndex());
     }
 
     @Test
@@ -102,13 +107,15 @@
         assertTrue(nodes.containsKey(vmNumaNode1));
         assertTrue(nodes.containsKey(vmNumaNode2));
 
-        assertEquals(vdsNumaNodeId, 
nodes.get(vmNumaNode1).getVdsNumaNodeList().get(0).getFirst());
-        assertEquals(true, 
nodes.get(vmNumaNode1).getVdsNumaNodeList().get(0).getSecond().getFirst());
-        assertEquals(0, 
nodes.get(vmNumaNode1).getVdsNumaNodeList().get(0).getSecond().getSecond().intValue());
+        NumaPlacement placement1 = 
nodes.get(vmNumaNode1).getNumaPlacements().iterator().next();
+        assertEquals(vdsNumaNodeId, placement1.getPhysicalNodeId());
+        assertEquals(true, placement1.isPinned());
+        assertEquals(0, placement1.getIndex());
 
-        assertEquals(vdsNumaNodeId, 
nodes.get(vmNumaNode2).getVdsNumaNodeList().get(0).getFirst());
-        assertEquals(false, 
nodes.get(vmNumaNode2).getVdsNumaNodeList().get(0).getSecond().getFirst());
-        assertEquals(0, 
nodes.get(vmNumaNode2).getVdsNumaNodeList().get(0).getSecond().getSecond().intValue());
+        NumaPlacement placement2 = 
nodes.get(vmNumaNode2).getNumaPlacements().iterator().next();
+        assertEquals(vdsNumaNodeId, placement2.getPhysicalNodeId());
+        assertEquals(false, placement2.isPinned());
+        assertEquals(0, placement2.getIndex());
     }
 
     @Test
@@ -143,14 +150,14 @@
         newVmNumaNode.setCpuIds(generateCpuList(0, 4));
         newVmNumaNode.setId(vmNumaNode1);
         newVmNumaNode.setIndex(0);
-        ((VmNumaNode)newVmNumaNode).getVdsNumaNodeList().add(new 
Pair<>(vdsNumaNode1, new Pair<>(true, 0)));
+        ((VmNumaNode) newVmNumaNode).getNumaPlacements().add(new 
NumaPlacement(vdsNumaNode1, NumaPlacement.Mode.PINNED, 0));
         newVmNode.add(newVmNumaNode);
 
         newVmNumaNode = new VmNumaNode();
         newVmNumaNode.setCpuIds(generateCpuList(4, 4));
         newVmNumaNode.setId(vmNumaNode2);
         newVmNumaNode.setIndex(1);
-        ((VmNumaNode)newVmNumaNode).getVdsNumaNodeList().add(new 
Pair<>(vdsNumaNode2, new Pair<>(true, 1)));
+        ((VmNumaNode) newVmNumaNode).getNumaPlacements().add(new 
NumaPlacement(vdsNumaNode2, NumaPlacement.Mode.PINNED, 1));
         newVmNode.add(newVmNumaNode);
 
         vmNumaNodeDao.massSaveNumaNode(newVmNode, null, 
ANOTHER_EXISTING_VM_ID);
@@ -165,15 +172,15 @@
         assertTrue(nodes.containsKey(vmNumaNode1));
         assertTrue(nodes.containsKey(vmNumaNode2));
 
-        assertEquals(1, nodes.get(vmNumaNode1).getVdsNumaNodeList().size());
-        assertEquals(true, 
nodes.get(vmNumaNode1).getVdsNumaNodeList().get(0).getSecond().getFirst());
-        assertEquals(vdsNumaNode1, 
nodes.get(vmNumaNode1).getVdsNumaNodeList().get(0).getFirst());
-        assertEquals(0, 
nodes.get(vmNumaNode1).getVdsNumaNodeList().get(0).getSecond().getSecond().intValue());
+        assertEquals(1, nodes.get(vmNumaNode1).getNumaPlacements().size());
+        assertEquals(true, 
nodes.get(vmNumaNode1).getNumaPlacements().iterator().next().isPinned());
+        assertEquals(vdsNumaNode1, 
nodes.get(vmNumaNode1).getNumaPlacements().iterator().next().getPhysicalNodeId());
+        assertEquals(0, 
nodes.get(vmNumaNode1).getNumaPlacements().iterator().next().getIndex());
 
-        assertEquals(1, nodes.get(vmNumaNode2).getVdsNumaNodeList().size());
-        assertEquals(true, 
nodes.get(vmNumaNode2).getVdsNumaNodeList().get(0).getSecond().getFirst());
-        assertEquals(vdsNumaNode2, 
nodes.get(vmNumaNode2).getVdsNumaNodeList().get(0).getFirst());
-        assertEquals(1, 
nodes.get(vmNumaNode2).getVdsNumaNodeList().get(0).getSecond().getSecond().intValue());
+        assertEquals(1, nodes.get(vmNumaNode2).getNumaPlacements().size());
+        assertEquals(true, 
nodes.get(vmNumaNode2).getNumaPlacements().iterator().next().isPinned());
+        assertEquals(vdsNumaNode2, 
nodes.get(vmNumaNode2).getNumaPlacements().iterator().next().getPhysicalNodeId());
+        assertEquals(1, 
nodes.get(vmNumaNode2).getNumaPlacements().iterator().next().getIndex());
 
         List<Guid> vmNodeList = new ArrayList<Guid>();
         vmNodeList.add(vmNumaNode1);
@@ -203,7 +210,7 @@
         newVmNumaNode.setIndex(0);
         newVmNumaNode.setNumaNodeDistances(generateDistance(2, 0));
         newVmNumaNode.setNumaNodeStatistics(newNodeStatistics);
-        ((VmNumaNode)newVmNumaNode).getVdsNumaNodeList().add(new 
Pair<>(vdsNumaNode1, new Pair<>(true, 0)));
+        ((VmNumaNode)newVmNumaNode).getNumaPlacements().add(new 
NumaPlacement(vdsNumaNode1, NumaPlacement.Mode.PINNED, 0));
         newVmNode.add(newVmNumaNode);
 
         newVmNumaNode = new VmNumaNode();
@@ -212,7 +219,7 @@
         newVmNumaNode.setIndex(1);
         newVmNumaNode.setNumaNodeDistances(generateDistance(2, 1));
         newVmNumaNode.setNumaNodeStatistics(newNodeStatistics);
-        ((VmNumaNode)newVmNumaNode).getVdsNumaNodeList().add(new 
Pair<>(vdsNumaNode2, new Pair<>(true, 1)));
+        ((VmNumaNode)newVmNumaNode).getNumaPlacements().add(new 
NumaPlacement(vdsNumaNode2, NumaPlacement.Mode.PINNED, 1));
         newVmNode.add(newVmNumaNode);
 
         vmNumaNodeDao.massSaveNumaNode(newVmNode, null, 
ANOTHER_EXISTING_VM_ID);
@@ -224,11 +231,11 @@
         nodes.put(result.get(0).getId(), result.get(0));
         nodes.put(result.get(1).getId(), result.get(1));
 
-        nodes.get(vmNumaNode1).getVdsNumaNodeList().clear();
-        nodes.get(vmNumaNode1).getVdsNumaNodeList().add(new 
Pair<>(vdsNumaNode2, new Pair<>(true, 1)));
+        nodes.get(vmNumaNode1).getNumaPlacements().clear();
+        ((VmNumaNode)newVmNumaNode).getNumaPlacements().add(new 
NumaPlacement(vdsNumaNode2, NumaPlacement.Mode.PINNED, 1));
 
-        nodes.get(vmNumaNode2).getVdsNumaNodeList().clear();
-        nodes.get(vmNumaNode2).getVdsNumaNodeList().add(new 
Pair<>(vdsNumaNode1, new Pair<>(true, 0)));
+        nodes.get(vmNumaNode2).getNumaPlacements().clear();
+        ((VmNumaNode)newVmNumaNode).getNumaPlacements().add(new 
NumaPlacement(vdsNumaNode1, NumaPlacement.Mode.PINNED, 0));
 
         newVmNode.clear();
         newVmNode.add(nodes.get(vmNumaNode1));
@@ -247,15 +254,15 @@
         assertTrue(nodes.containsKey(vmNumaNode1));
         assertTrue(nodes.containsKey(vmNumaNode2));
 
-        assertEquals(1, nodes.get(vmNumaNode1).getVdsNumaNodeList().size());
-        assertEquals(true, 
nodes.get(vmNumaNode1).getVdsNumaNodeList().get(0).getSecond().getFirst());
-        assertEquals(vdsNumaNode2, 
nodes.get(vmNumaNode1).getVdsNumaNodeList().get(0).getFirst());
-        assertEquals(1, 
nodes.get(vmNumaNode1).getVdsNumaNodeList().get(0).getSecond().getSecond().intValue());
+        assertEquals(1, nodes.get(vmNumaNode1).getNumaPlacements().size());
+        assertEquals(true, 
nodes.get(vmNumaNode1).getNumaPlacements().iterator().next().isPinned());
+        assertEquals(vdsNumaNode2, 
nodes.get(vmNumaNode1).getNumaPlacements().iterator().next().getPhysicalNodeId());
+        assertEquals(1, 
nodes.get(vmNumaNode1).getNumaPlacements().iterator().next().getIndex());
 
-        assertEquals(1, nodes.get(vmNumaNode2).getVdsNumaNodeList().size());
-        assertEquals(true, 
nodes.get(vmNumaNode2).getVdsNumaNodeList().get(0).getSecond().getFirst());
-        assertEquals(vdsNumaNode1, 
nodes.get(vmNumaNode2).getVdsNumaNodeList().get(0).getFirst());
-        assertEquals(0, 
nodes.get(vmNumaNode2).getVdsNumaNodeList().get(0).getSecond().getSecond().intValue());
+        assertEquals(1, nodes.get(vmNumaNode2).getNumaPlacements().size());
+        assertEquals(true, 
nodes.get(vmNumaNode2).getNumaPlacements().iterator().next().isPinned());
+        assertEquals(vdsNumaNode1, 
nodes.get(vmNumaNode2).getNumaPlacements().iterator().next().getPhysicalNodeId());
+        assertEquals(0, 
nodes.get(vmNumaNode2).getNumaPlacements().iterator().next().getIndex());
 
         List<Guid> vmNodeList = new ArrayList<Guid>();
         vmNodeList.add(vmNumaNode1);
@@ -285,7 +292,7 @@
         newVmNumaNode.setIndex(0);
         newVmNumaNode.setNumaNodeDistances(generateDistance(2, 0));
         newVmNumaNode.setNumaNodeStatistics(newNodeStatistics);
-        newVmNumaNode.getVdsNumaNodeList().add(new Pair<>(vdsNumaNode1, new 
Pair<>(false, 0)));
+        newVmNumaNode.getNumaPlacements().add(new NumaPlacement(vdsNumaNode1, 
NumaPlacement.Mode.NON_PINNED, 0));
         newVmNode.add(newVmNumaNode);
 
         newVmNumaNode = new VmNumaNode();
@@ -294,7 +301,7 @@
         newVmNumaNode.setIndex(1);
         newVmNumaNode.setNumaNodeDistances(generateDistance(2, 1));
         newVmNumaNode.setNumaNodeStatistics(newNodeStatistics);
-        newVmNumaNode.getVdsNumaNodeList().add(new Pair<>(vdsNumaNode2, new 
Pair<>(false, 1)));
+        newVmNumaNode.getNumaPlacements().add(new NumaPlacement(vdsNumaNode2, 
NumaPlacement.Mode.NON_PINNED, 1));
         newVmNode.add(newVmNumaNode);
 
         vmNumaNodeDao.massSaveNumaNode(newVmNode, null, 
ANOTHER_EXISTING_VM_ID);
@@ -306,11 +313,11 @@
         nodes.put(result.get(0).getId(), result.get(0));
         nodes.put(result.get(1).getId(), result.get(1));
 
-        nodes.get(vmNumaNode1).getVdsNumaNodeList().clear();
-        nodes.get(vmNumaNode1).getVdsNumaNodeList().add(new 
Pair<>(vdsNumaNode2, new Pair<>(false, 1)));
+        newVmNumaNode.getNumaPlacements().clear();
+        newVmNumaNode.getNumaPlacements().add(new NumaPlacement(vdsNumaNode2, 
NumaPlacement.Mode.NON_PINNED, 1));
 
-        nodes.get(vmNumaNode2).getVdsNumaNodeList().clear();
-        nodes.get(vmNumaNode2).getVdsNumaNodeList().add(new 
Pair<>(vdsNumaNode1, new Pair<>(false, 0)));
+        newVmNumaNode.getNumaPlacements().clear();
+        newVmNumaNode.getNumaPlacements().add(new NumaPlacement(vdsNumaNode1, 
NumaPlacement.Mode.NON_PINNED, 0));
 
         List<VmNumaNode> updateNodes = new ArrayList<>();
         updateNodes.add(nodes.get(vmNumaNode1));
@@ -329,15 +336,15 @@
         assertTrue(nodes.containsKey(vmNumaNode1));
         assertTrue(nodes.containsKey(vmNumaNode2));
 
-        assertEquals(1, nodes.get(vmNumaNode1).getVdsNumaNodeList().size());
-        assertEquals(false, 
nodes.get(vmNumaNode1).getVdsNumaNodeList().get(0).getSecond().getFirst());
-        assertEquals(vdsNumaNode2, 
nodes.get(vmNumaNode1).getVdsNumaNodeList().get(0).getFirst());
-        assertEquals(1, 
nodes.get(vmNumaNode1).getVdsNumaNodeList().get(0).getSecond().getSecond().intValue());
+        assertEquals(1, nodes.get(vmNumaNode1).getNumaPlacements().size());
+        assertEquals(false, 
nodes.get(vmNumaNode1).getNumaPlacements().iterator().next().isPinned());
+        assertEquals(vdsNumaNode2, 
nodes.get(vmNumaNode1).getNumaPlacements().iterator().next().getPhysicalNodeId());
+        assertEquals(1, 
nodes.get(vmNumaNode1).getNumaPlacements().iterator().next().getIndex());
 
-        assertEquals(1, nodes.get(vmNumaNode2).getVdsNumaNodeList().size());
-        assertEquals(false, 
nodes.get(vmNumaNode2).getVdsNumaNodeList().get(0).getSecond().getFirst());
-        assertEquals(vdsNumaNode1, 
nodes.get(vmNumaNode2).getVdsNumaNodeList().get(0).getFirst());
-        assertEquals(0, 
nodes.get(vmNumaNode2).getVdsNumaNodeList().get(0).getSecond().getSecond().intValue());
+        assertEquals(1, nodes.get(vmNumaNode2).getNumaPlacements().size());
+        assertEquals(false, 
nodes.get(vmNumaNode2).getNumaPlacements().iterator().next().isPinned());
+        assertEquals(vdsNumaNode1, 
nodes.get(vmNumaNode2).getNumaPlacements().iterator().next().getPhysicalNodeId());
+        assertEquals(0, 
nodes.get(vmNumaNode2).getNumaPlacements().iterator().next().getIndex());
 
         List<Guid> vmNodeList = new ArrayList<Guid>();
         vmNodeList.add(vmNumaNode1);
diff --git 
a/backend/manager/modules/restapi/types/src/main/java/org/ovirt/engine/api/restapi/types/NumaMapper.java
 
b/backend/manager/modules/restapi/types/src/main/java/org/ovirt/engine/api/restapi/types/NumaMapper.java
index 2953d63..4c29b8a 100644
--- 
a/backend/manager/modules/restapi/types/src/main/java/org/ovirt/engine/api/restapi/types/NumaMapper.java
+++ 
b/backend/manager/modules/restapi/types/src/main/java/org/ovirt/engine/api/restapi/types/NumaMapper.java
@@ -1,7 +1,9 @@
 package org.ovirt.engine.api.restapi.types;
 
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 import org.apache.commons.lang.StringUtils;
 import org.ovirt.engine.api.model.CPU;
@@ -12,9 +14,9 @@
 import org.ovirt.engine.api.model.NumaNodePins;
 import org.ovirt.engine.api.model.VirtualNumaNode;
 import org.ovirt.engine.api.restapi.utils.GuidUtils;
+import org.ovirt.engine.core.common.businessentities.NumaPlacement;
 import org.ovirt.engine.core.common.businessentities.VdsNumaNode;
 import org.ovirt.engine.core.common.businessentities.VmNumaNode;
-import org.ovirt.engine.core.common.utils.Pair;
 import org.ovirt.engine.core.compat.Guid;
 
 public class NumaMapper {
@@ -63,16 +65,16 @@
             cpu.setCores(cores);
             model.setCpu(cpu);
         }
-        if (entity.getVdsNumaNodeList() != null && 
entity.getVdsNumaNodeList().size() > 0) {
+        if (entity.getNumaPlacements() != null && 
entity.getNumaPlacements().size() > 0) {
             NumaNodePins pins = new NumaNodePins();
-            for (Pair<Guid, Pair<Boolean, Integer>> pair : 
entity.getVdsNumaNodeList()) {
+            for (NumaPlacement placement : entity.getNumaPlacements()) {
                 NumaNodePin pin = new NumaNodePin();
                 pin.setHostNumaNode(new NumaNode());
-                if (pair.getFirst() != null) {
-                    pin.getHostNumaNode().setId(pair.getFirst().toString());
+                if (placement.getPhysicalNodeId() != null) {
+                    
pin.getHostNumaNode().setId(placement.getPhysicalNodeId().toString());
                 }
-                pin.setPinned(pair.getSecond().getFirst());
-                pin.setIndex(pair.getSecond().getSecond());
+                pin.setPinned(placement.isPinned());
+                pin.setIndex(placement.getIndex());
                 pins.getNumaNodePin().add(pin);
             }
             model.setNumaNodePins(pins);
@@ -103,18 +105,16 @@
             entity.setMemTotal(model.getMemory());
         }
         if (model.isSetNumaNodePins()) {
-            List<Pair<Guid, Pair<Boolean, Integer>>> pairs = new 
ArrayList<Pair<Guid, Pair<Boolean, Integer>>>();
+            Set<NumaPlacement> placements = new HashSet<>();
             for (NumaNodePin pin : model.getNumaNodePins().getNumaNodePin()) {
-                Pair<Boolean, Integer> first = new Pair<Boolean, 
Integer>(pin.isPinned(), pin.getIndex());
                 Guid guid = null;
                 NumaNode node = pin.getHostNumaNode();
                 if (node != null && node.getId() != null) {
                     guid = GuidUtils.asGuid(pin.getHostNumaNode().getId());
                 }
-                Pair<Guid, Pair<Boolean, Integer>> second = new Pair<Guid, 
Pair<Boolean, Integer>>(guid, first);
-                pairs.add(second);
+                placements.add(new NumaPlacement(guid, pin.isPinned(), 
pin.getIndex()));
             }
-            entity.setVdsNumaNodeList(pairs);
+            entity.setNumaPlacements(placements);
         }
         return entity;
     }
diff --git 
a/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/NumaUtils.java
 
b/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/NumaUtils.java
index a9f6a19..da47394 100644
--- 
a/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/NumaUtils.java
+++ 
b/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/NumaUtils.java
@@ -3,10 +3,10 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
+import java.util.Set;
 
+import org.ovirt.engine.core.common.businessentities.NumaPlacement;
 import org.ovirt.engine.core.common.businessentities.VdsNumaNode;
-import org.ovirt.engine.core.common.utils.Pair;
-import org.ovirt.engine.core.compat.Guid;
 
 public class NumaUtils {
     public static VdsNumaNode getVdsNumaNodeByIndex(List<VdsNumaNode> 
numaNodes, int index) {
@@ -38,11 +38,11 @@
         return nodeIndexes;
     }
 
-    public static List<Integer> getPinnedNodeIndexList(List<Pair<Guid, 
Pair<Boolean, Integer>>> nodeList) {
-        List<Integer> nodeIndexes = new ArrayList<>(nodeList.size());
-        for (Pair<Guid, Pair<Boolean, Integer>> item : nodeList) {
-            if (item.getSecond().getFirst() && item.getFirst() != null) {
-                nodeIndexes.add(item.getSecond().getSecond());
+    public static List<Integer> getPinnedNodeIndexList(Set<NumaPlacement> 
placements) {
+        List<Integer> nodeIndexes = new ArrayList<>(placements.size());
+        for (NumaPlacement placement : placements) {
+            if (placement.getPhysicalNodeId() != null && placement.isPinned()) 
{
+                nodeIndexes.add(placement.getIndex());
             }
         }
         return nodeIndexes;
diff --git 
a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/ResourceManager.java
 
b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/ResourceManager.java
index 5a8e7d2..7a844cc 100644
--- 
a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/ResourceManager.java
+++ 
b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/ResourceManager.java
@@ -377,7 +377,7 @@
         }
         List<VmNumaNode> vmNumaNodes = vm.getvNumaNodeList();
         for (VmNumaNode node : vmNumaNodes) {
-            node.getVdsNumaNodeList().clear();
+            node.getNumaPlacements().clear();
         }
     }
 
diff --git 
a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/VmAnalyzer.java
 
b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/VmAnalyzer.java
index 44e8b09..fb37212 100644
--- 
a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/VmAnalyzer.java
+++ 
b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/VmAnalyzer.java
@@ -7,6 +7,7 @@
 import org.ovirt.engine.core.common.businessentities.DiskImageDynamic;
 import org.ovirt.engine.core.common.businessentities.LUNs;
 import org.ovirt.engine.core.common.businessentities.LunDisk;
+import org.ovirt.engine.core.common.businessentities.NumaPlacement;
 import org.ovirt.engine.core.common.businessentities.UnchangeableByVdsm;
 import org.ovirt.engine.core.common.businessentities.VDSStatus;
 import org.ovirt.engine.core.common.businessentities.VM;
@@ -916,18 +917,18 @@
             VmNumaNode dbVmNumaNode = vmAllNumaNodesMap.get(vNode.getIndex());
             if (dbVmNumaNode != null) {
                 vNode.setId(dbVmNumaNode.getId());
-                List<Integer> pinnedNodes = 
NumaUtils.getPinnedNodeIndexList(dbVmNumaNode.getVdsNumaNodeList());
-                List<Pair<Guid, Pair<Boolean, Integer>>> runTimePinList = new 
ArrayList<>();
-                for (Pair<Guid, Pair<Boolean, Integer>> pair : 
vNode.getVdsNumaNodeList()) {
-                    if ((!pinnedNodes.contains(pair.getSecond().getSecond())) 
&&
-                            
(runOnVdsAllNumaNodesMap.containsKey(pair.getSecond().getSecond()))) {
-                        
pair.setFirst(runOnVdsAllNumaNodesMap.get(pair.getSecond().getSecond()).getId());
-                        pair.getSecond().setFirst(false);
-                        runTimePinList.add(pair);
+                List<Integer> pinnedNodes = 
NumaUtils.getPinnedNodeIndexList(dbVmNumaNode.getNumaPlacements());
+                Set<NumaPlacement> runTimePinList = new HashSet<>();
+                for (NumaPlacement placement : vNode.getNumaPlacements()) {
+                    if ( (!pinnedNodes.contains(placement.getIndex())
+                            && 
(runOnVdsAllNumaNodesMap.containsKey(placement.getIndex())))) {
+                        
placement.setPhysicalNodeId(runOnVdsAllNumaNodesMap.get(placement.getIndex()).getId());
+                        placement.setMode(NumaPlacement.Mode.NON_PINNED);
+                        runTimePinList.add(placement);
                     }
                 }
                 if (!runTimePinList.isEmpty()) {
-                    vNode.setVdsNumaNodeList(runTimePinList);
+                    vNode.setNumaPlacements(runTimePinList);
                     vmNumaNodesNeedUpdate.add(vNode);
                 }
             }
diff --git 
a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/NumaSettingFactory.java
 
b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/NumaSettingFactory.java
index dd2f1ab..48ff788 100644
--- 
a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/NumaSettingFactory.java
+++ 
b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/NumaSettingFactory.java
@@ -34,7 +34,7 @@
             vdsNumaNodeCpus.put(node.getIndex(), node.getCpuIds());
         }
         for (VmNumaNode node : vmNodes) {
-            List<Integer> pinnedNodeIndexes = 
NumaUtils.getPinnedNodeIndexList(node.getVdsNumaNodeList());
+            List<Integer> pinnedNodeIndexes = 
NumaUtils.getPinnedNodeIndexList(node.getNumaPlacements());
             if (!pinnedNodeIndexes.isEmpty()) {
                 Set <Integer> totalPinnedVdsCpus = new LinkedHashSet<>();
                 for (Integer vCpu : node.getCpuIds()) {
@@ -56,8 +56,8 @@
         Map<String, Object> createNumaTune = new HashMap<>(2);
         Set<Integer> vmNumaNodePinInfo = new HashSet<>();
         for (VmNumaNode node : vmNumaNodes) {
-            if (!node.getVdsNumaNodeList().isEmpty()) {
-                
vmNumaNodePinInfo.addAll(NumaUtils.getPinnedNodeIndexList(node.getVdsNumaNodeList()));
+            if (!node.getNumaPlacements().isEmpty()) {
+                
vmNumaNodePinInfo.addAll(NumaUtils.getPinnedNodeIndexList(node.getNumaPlacements()));
             }
         }
         if (vmNumaNodePinInfo.isEmpty()) {
diff --git 
a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/VdsBrokerObjectsBuilder.java
 
b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/VdsBrokerObjectsBuilder.java
index 9292f05..3d82db6 100644
--- 
a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/VdsBrokerObjectsBuilder.java
+++ 
b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/VdsBrokerObjectsBuilder.java
@@ -33,6 +33,7 @@
 import org.ovirt.engine.core.common.businessentities.KdumpStatus;
 import org.ovirt.engine.core.common.businessentities.LUNs;
 import org.ovirt.engine.core.common.businessentities.NumaNodeStatistics;
+import org.ovirt.engine.core.common.businessentities.NumaPlacement;
 import org.ovirt.engine.core.common.businessentities.SessionState;
 import org.ovirt.engine.core.common.businessentities.StoragePool;
 import org.ovirt.engine.core.common.businessentities.StorageType;
@@ -72,7 +73,6 @@
 import org.ovirt.engine.core.common.config.Config;
 import org.ovirt.engine.core.common.config.ConfigValues;
 import org.ovirt.engine.core.common.utils.EnumUtils;
-import org.ovirt.engine.core.common.utils.Pair;
 import org.ovirt.engine.core.common.utils.SizeConverter;
 import org.ovirt.engine.core.compat.Guid;
 import org.ovirt.engine.core.compat.RpmVersion;
@@ -1899,8 +1899,11 @@
             VmNumaNode vNode = new VmNumaNode();
             vNode.setIndex(Integer.valueOf(item.getKey()));
             for (Object pNodeIndex : item.getValue()) {
-                vNode.getVdsNumaNodeList().add(new Pair<>(
-                        Guid.Empty, new Pair<>(false, (Integer)pNodeIndex)));
+                vNode.getNumaPlacements().add(new NumaPlacement(
+                        Guid.Empty,
+                        NumaPlacement.Mode.NON_PINNED,
+                        (Integer)pNodeIndex
+                ));
             }
             vm.getvNumaNodeStatisticsList().add(vNode);
         }
diff --git 
a/backend/manager/modules/vdsbroker/src/test/java/org/ovirt/engine/core/vdsbroker/vdsbroker/NumaSettingFactoryTest.java
 
b/backend/manager/modules/vdsbroker/src/test/java/org/ovirt/engine/core/vdsbroker/vdsbroker/NumaSettingFactoryTest.java
index 7ed5b01..55de883 100644
--- 
a/backend/manager/modules/vdsbroker/src/test/java/org/ovirt/engine/core/vdsbroker/vdsbroker/NumaSettingFactoryTest.java
+++ 
b/backend/manager/modules/vdsbroker/src/test/java/org/ovirt/engine/core/vdsbroker/vdsbroker/NumaSettingFactoryTest.java
@@ -11,10 +11,10 @@
 import org.junit.BeforeClass;
 import org.junit.Test;
 import org.ovirt.engine.core.common.businessentities.NumaNodeStatistics;
+import org.ovirt.engine.core.common.businessentities.NumaPlacement;
 import org.ovirt.engine.core.common.businessentities.NumaTuneMode;
 import org.ovirt.engine.core.common.businessentities.VdsNumaNode;
 import org.ovirt.engine.core.common.businessentities.VmNumaNode;
-import org.ovirt.engine.core.common.utils.Pair;
 import org.ovirt.engine.core.compat.Guid;
 
 public class NumaSettingFactoryTest {
@@ -73,7 +73,7 @@
         newVmNumaNode.setId(Guid.newGuid());
         newVmNumaNode.setIndex(0);
         newVmNumaNode.setMemTotal(1024);
-        newVmNumaNode.getVdsNumaNodeList().add(new Pair<>(Guid.newGuid(), new 
Pair<>(true, 0)));
+        newVmNumaNode.getNumaPlacements().add(new 
NumaPlacement(Guid.newGuid(), NumaPlacement.Mode.PINNED, 0));
         newVmNodes.add(newVmNumaNode);
 
         newVmNumaNode = new VmNumaNode();
@@ -81,7 +81,7 @@
         newVmNumaNode.setId(Guid.newGuid());
         newVmNumaNode.setIndex(1);
         newVmNumaNode.setMemTotal(1024);
-        newVmNumaNode.getVdsNumaNodeList().add(new Pair<>(Guid.newGuid(), new 
Pair<>(true, 1)));
+        newVmNumaNode.getNumaPlacements().add(new 
NumaPlacement(Guid.newGuid(), NumaPlacement.Mode.PINNED, 1));
         newVmNodes.add(newVmNumaNode);
 
         return newVmNodes;
diff --git 
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/view/popup/numa/NumaSupportPopupView.java
 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/view/popup/numa/NumaSupportPopupView.java
index 52793b0..1814fd8 100644
--- 
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/view/popup/numa/NumaSupportPopupView.java
+++ 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/view/popup/numa/NumaSupportPopupView.java
@@ -4,12 +4,11 @@
 import java.util.List;
 import java.util.Set;
 
+import org.ovirt.engine.core.common.businessentities.NumaPlacement;
 import org.ovirt.engine.core.common.businessentities.VDS;
 import org.ovirt.engine.core.common.businessentities.VM;
 import org.ovirt.engine.core.common.businessentities.VdsNumaNode;
 import org.ovirt.engine.core.common.businessentities.VmNumaNode;
-import org.ovirt.engine.core.common.utils.Pair;
-import org.ovirt.engine.core.compat.Guid;
 import org.ovirt.engine.ui.common.CommonApplicationConstants;
 import org.ovirt.engine.ui.common.CommonApplicationMessages;
 import org.ovirt.engine.ui.common.CommonApplicationResources;
@@ -162,11 +161,9 @@
         for (VM vm: vmsWithVNuma) {
             for(VmNumaNode vmNumaNode: vm.getvNumaNodeList()) {
                 VNodeModel vNodeModel = new VNodeModel(supportModel, vm, 
vmNumaNode, false);
-                if (vmNumaNode.getVdsNumaNodeList() != null && 
!vmNumaNode.getVdsNumaNodeList().isEmpty()) {
-                    for (Pair<Guid, Pair<Boolean, Integer>> pair : 
vmNumaNode.getVdsNumaNodeList()) {
-                        if (pair.getSecond().getFirst()) {
-                            vNodeModel.setPinned(true);
-                        }
+                if (vmNumaNode.getNumaPlacements() != null) {
+                    for (NumaPlacement placement : 
vmNumaNode.getNumaPlacements()) {
+                        vNodeModel.setPinned(placement.isPinned());
                     }
                 }
                 numaNodes.add(vNodeModel);
diff --git 
a/frontend/webadmin/modules/gwt-common/src/main/resources/org/ovirt/engine/core/Common.gwt.xml
 
b/frontend/webadmin/modules/gwt-common/src/main/resources/org/ovirt/engine/core/Common.gwt.xml
index beaeb3b..8d8e765 100644
--- 
a/frontend/webadmin/modules/gwt-common/src/main/resources/org/ovirt/engine/core/Common.gwt.xml
+++ 
b/frontend/webadmin/modules/gwt-common/src/main/resources/org/ovirt/engine/core/Common.gwt.xml
@@ -369,6 +369,7 @@
                <include name="common/businessentities/NumaTuneMode.java" />
                <include name="common/businessentities/VdsNumaNode.java" />
                <include name="common/businessentities/VmNumaNode.java" />
+               <include name="common/businessentities/NumaPlacement.java" />
         <!-- Foreman Objects -->
         <include name="common/businessentities/ExternalEntityBase.java"/>
         <include name="common/businessentities/ExternalHostGroup.java"/>
diff --git 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/builders/vm/NumaUnitToVmBaseBuilder.java
 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/builders/vm/NumaUnitToVmBaseBuilder.java
index a72f7f5..9c09416 100644
--- 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/builders/vm/NumaUnitToVmBaseBuilder.java
+++ 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/builders/vm/NumaUnitToVmBaseBuilder.java
@@ -1,12 +1,12 @@
 package org.ovirt.engine.ui.uicommonweb.builders.vm;
 
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
 
+import org.ovirt.engine.core.common.businessentities.NumaPlacement;
 import org.ovirt.engine.core.common.businessentities.VmBase;
 import org.ovirt.engine.core.common.businessentities.VmNumaNode;
-import org.ovirt.engine.core.common.utils.Pair;
-import org.ovirt.engine.core.compat.Guid;
 import org.ovirt.engine.ui.uicommonweb.builders.BaseSyncBuilder;
 import org.ovirt.engine.ui.uicommonweb.models.vms.UnitVmModel;
 
@@ -61,10 +61,13 @@
     }
 
     private void updateNumaPinning(VmNumaNode vmNumaNode, int index) {
-        if (vmNumaNode.getVdsNumaNodeList() == null) {
-            vmNumaNode.setVdsNumaNodeList(new ArrayList<Pair<Guid, 
Pair<Boolean, Integer>>>());
-            Pair<Guid, Pair<Boolean, Integer>> pair = new Pair<Guid, 
Pair<Boolean, Integer>>();
-            pair.setSecond(new Pair<Boolean, Integer>(false, index));
+        if (vmNumaNode.getNumaPlacements() == null) {
+            vmNumaNode.setNumaPlacements(new HashSet<NumaPlacement>());
         }
+        vmNumaNode.getNumaPlacements().add(new NumaPlacement(
+                null,
+                NumaPlacement.Mode.NON_PINNED,
+                index
+        ));
     }
 }
diff --git 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/hosts/numa/NumaSupportModel.java
 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/hosts/numa/NumaSupportModel.java
index 05a88ee..bbc94d0 100644
--- 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/hosts/numa/NumaSupportModel.java
+++ 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/hosts/numa/NumaSupportModel.java
@@ -11,6 +11,7 @@
 
 import org.ovirt.engine.core.common.action.VdcActionParametersBase;
 import org.ovirt.engine.core.common.action.VmNumaNodeOperationParameters;
+import org.ovirt.engine.core.common.businessentities.NumaPlacement;
 import org.ovirt.engine.core.common.businessentities.VDS;
 import org.ovirt.engine.core.common.businessentities.VM;
 import org.ovirt.engine.core.common.businessentities.VdsNumaNode;
@@ -113,15 +114,14 @@
             if (vm.getvNumaNodeList() != null) {
                 for (VmNumaNode vmNumaNode : vm.getvNumaNodeList()) {
                     VNodeModel vNodeModel = new VNodeModel(this, vm, 
vmNumaNode, false);
-                    if (vmNumaNode.getVdsNumaNodeList() != null && 
!vmNumaNode.getVdsNumaNodeList().isEmpty()) {
-                        for (Pair<Guid, Pair<Boolean, Integer>> pair : 
vmNumaNode.getVdsNumaNodeList()) {
-                            if (!pair.getSecond().getFirst()) {
+                    if (vmNumaNode.getNumaPlacements() != null && 
!vmNumaNode.getNumaPlacements().isEmpty()) {
+                        for (NumaPlacement placement : 
vmNumaNode.getNumaPlacements()) {
+                            if (placement.isPinned()) {
+                                vNodeModel.setPinned(true);
+                                assignVNumaToPhysicalNuma(vNodeModel, 
placement.getPhysicalNodeId());
+                            } else {
                                 unassignedVNodeModelList.add(vNodeModel);
                                 break;
-                            } else {
-                                vNodeModel.setPinned(true);
-                                Guid nodeId = pair.getFirst();
-                                assignVNumaToPhysicalNuma(vNodeModel, nodeId);
                             }
                         }
                     } else {
@@ -260,22 +260,21 @@
                 for (VmNumaNode vmNumaNode : vm.getvNumaNodeList()) {
                     if (vmNumaNode.getIndex() == sourceVNumaIndex) {
                         breakFlag = true;
-                        if (vmNumaNode.getVdsNumaNodeList().isEmpty()) {
-                            Pair<Guid, Pair<Boolean, Integer>> pair = new 
Pair<Guid, Pair<Boolean, Integer>>();
-                            
pair.setFirst(getNodeByIndex(targetPNumaNodeIndex).getId());
-                            pair.setSecond(new Pair<Boolean, Integer>());
-                            pair.getSecond().setFirst(true);
-                            pair.getSecond().setSecond(targetPNumaNodeIndex);
-                            vmNumaNode.getVdsNumaNodeList().add(pair);
+                        if (vmNumaNode.getNumaPlacements().isEmpty()) {
+                            vmNumaNode.getNumaPlacements().add(new 
NumaPlacement(
+                                    
getNodeByIndex(targetPNumaNodeIndex).getId(),
+                                    NumaPlacement.Mode.PINNED,
+                                    targetPNumaNodeIndex
+                            ));
                         } else {
-                            for (Pair<Guid, Pair<Boolean, Integer>> pair : 
vmNumaNode.getVdsNumaNodeList()) {
+                            for (NumaPlacement placement : 
vmNumaNode.getNumaPlacements()) {
                                 if (targetPNumaNodeIndex == -1) {
-                                    pair.setFirst(null);
-                                    pair.getSecond().setFirst(false);
+                                    placement.setPhysicalNodeId(null);
+                                    
placement.setMode(NumaPlacement.Mode.NON_PINNED);
                                 } else {
-                                    
pair.setFirst(getNodeByIndex(targetPNumaNodeIndex).getId());
-                                    pair.getSecond().setFirst(true);
-                                    
pair.getSecond().setSecond(targetPNumaNodeIndex);
+                                    
placement.setPhysicalNodeId(getNodeByIndex(targetPNumaNodeIndex).getId());
+                                    
placement.setMode(NumaPlacement.Mode.PINNED);
+                                    placement.setIndex(targetPNumaNodeIndex);
                                 }
                             }
                         }
diff --git 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/hosts/numa/VNodeModel.java
 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/hosts/numa/VNodeModel.java
index edabeac..a302920 100644
--- 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/hosts/numa/VNodeModel.java
+++ 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/hosts/numa/VNodeModel.java
@@ -39,7 +39,7 @@
     }
 
     public boolean isSplitted() {
-        return getVmNumaNode().getVdsNumaNodeList() != null && 
getVmNumaNode().getVdsNumaNodeList().size() > 1;
+        return getVmNumaNode().getNumaPlacements() != null && 
getVmNumaNode().getNumaPlacements().size() > 1;
     }
 
     public void setLocked(boolean locked) {


-- 
To view, visit http://gerrit.ovirt.org/38048
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I27a8f369e9896faeddd1e361ec884bf2c049b98f
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-engine
Gerrit-Branch: master
Gerrit-Owner: Roy Golan <[email protected]>
_______________________________________________
Engine-patches mailing list
[email protected]
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to