Browse Source

Merge -r 1428399:1428400 from trunk to branch-2. Fixes: YARN-301. Fair scheduler throws ConcurrentModificationException when iterating over app's priorities. Contributed by Sandy Ryza.

git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/branches/branch-2@1428401 13f79535-47bb-0310-9956-ffa450edef68
Thomas White 12 years ago
parent
commit
ece31146cf

+ 3 - 0
hadoop-yarn-project/CHANGES.txt

@@ -147,6 +147,9 @@ Release 2.0.3-alpha - Unreleased
     YARN-300. After YARN-271, fair scheduler can infinite loop and not
     schedule any application. (Sandy Ryza via tomwhite)
 
+    YARN-301. Fair scheduler throws ConcurrentModificationException when
+    iterating over app's priorities. (Sandy Ryza via tomwhite)
+
 Release 2.0.2-alpha - 2012-09-07 
 
     YARN-9. Rename YARN_HOME to HADOOP_YARN_HOME. (vinodkv via acmurthy)

+ 30 - 28
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/AppSchedulable.java

@@ -305,34 +305,36 @@ public class AppSchedulable extends Schedulable {
     // For each priority, see if we can schedule a node local, rack local
     // or off-switch request. Rack of off-switch requests may be delayed
     // (not scheduled) in order to promote better locality.
-    for (Priority priority : prioritiesToTry) {
-      app.addSchedulingOpportunity(priority);
-      NodeType allowedLocality = app.getAllowedLocalityLevel(priority,
-          scheduler.getNumClusterNodes(), scheduler.getNodeLocalityThreshold(),
-          scheduler.getRackLocalityThreshold());
-
-      ResourceRequest localRequest = app.getResourceRequest(priority,
-          node.getHostName());
-      if (localRequest != null && localRequest.getNumContainers() != 0) {
-        return assignContainer(node, app, priority,
-            localRequest, NodeType.NODE_LOCAL, reserved);
-      }
-
-      ResourceRequest rackLocalRequest = app.getResourceRequest(priority,
-          node.getRackName());
-      if (rackLocalRequest != null && rackLocalRequest.getNumContainers() != 0
-          && (allowedLocality.equals(NodeType.RACK_LOCAL) ||
-              allowedLocality.equals(NodeType.OFF_SWITCH))) {
-        return assignContainer(node, app, priority, rackLocalRequest,
-            NodeType.RACK_LOCAL, reserved);
-      }
-
-      ResourceRequest offSwitchRequest = app.getResourceRequest(priority,
-          RMNode.ANY);
-      if (offSwitchRequest != null && offSwitchRequest.getNumContainers() != 0
-          && allowedLocality.equals(NodeType.OFF_SWITCH)) {
-        return assignContainer(node, app, priority, offSwitchRequest,
-            NodeType.OFF_SWITCH, reserved);
+    synchronized (app) {
+      for (Priority priority : prioritiesToTry) {
+        app.addSchedulingOpportunity(priority);
+        NodeType allowedLocality = app.getAllowedLocalityLevel(priority,
+            scheduler.getNumClusterNodes(), scheduler.getNodeLocalityThreshold(),
+            scheduler.getRackLocalityThreshold());
+
+        ResourceRequest localRequest = app.getResourceRequest(priority,
+            node.getHostName());
+        if (localRequest != null && localRequest.getNumContainers() != 0) {
+          return assignContainer(node, app, priority,
+              localRequest, NodeType.NODE_LOCAL, reserved);
+        }
+
+        ResourceRequest rackLocalRequest = app.getResourceRequest(priority,
+            node.getRackName());
+        if (rackLocalRequest != null && rackLocalRequest.getNumContainers() != 0
+            && (allowedLocality.equals(NodeType.RACK_LOCAL) ||
+                allowedLocality.equals(NodeType.OFF_SWITCH))) {
+          return assignContainer(node, app, priority, rackLocalRequest,
+              NodeType.RACK_LOCAL, reserved);
+        }
+
+        ResourceRequest offSwitchRequest = app.getResourceRequest(priority,
+            RMNode.ANY);
+        if (offSwitchRequest != null && offSwitchRequest.getNumContainers() != 0
+            && allowedLocality.equals(NodeType.OFF_SWITCH)) {
+          return assignContainer(node, app, priority, offSwitchRequest,
+              NodeType.OFF_SWITCH, reserved);
+        }
       }
     }
     return Resources.none();