diff --git a/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt b/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt index 38b9e55ff3..f6a22a1674 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt +++ b/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt @@ -2201,6 +2201,9 @@ Release 2.8.0 - UNRELEASED HDFS-9332. Fix Precondition failures from NameNodeEditLogRoller while saving namespace. (wang) + HDFS-4937. ReplicationMonitor can infinite-loop in + BlockPlacementPolicyDefault#chooseRandom() (kihwal) + Release 2.7.2 - UNRELEASED INCOMPATIBLE CHANGES diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/blockmanagement/BlockPlacementPolicyDefault.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/blockmanagement/BlockPlacementPolicyDefault.java index d9b8d60b36..f610574463 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/blockmanagement/BlockPlacementPolicyDefault.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/blockmanagement/BlockPlacementPolicyDefault.java @@ -659,6 +659,7 @@ protected DatanodeStorageInfo chooseRandom(int numOfReplicas, int numOfAvailableNodes = clusterMap.countNumOfAvailableNodes( scope, excludedNodes); + int refreshCounter = numOfAvailableNodes; StringBuilder builder = null; if (LOG.isDebugEnabled()) { builder = debugLoggingBuilder.get(); @@ -708,6 +709,17 @@ protected DatanodeStorageInfo chooseRandom(int numOfReplicas, // If no candidate storage was found on this DN then set badTarget. badTarget = (storage == null); } + // Refresh the node count. If the live node count became smaller, + // but it is not reflected in this loop, it may loop forever in case + // the replicas/rack cannot be satisfied. + if (--refreshCounter == 0) { + refreshCounter = clusterMap.countNumOfAvailableNodes(scope, + excludedNodes); + // It has already gone through enough number of nodes. + if (refreshCounter <= excludedNodes.size()) { + break; + } + } } if (numOfReplicas>0) {