From acd712ca929c6153c539fbd5615a90f07fa0b493 Mon Sep 17 00:00:00 2001 From: huhaiyang Date: Wed, 19 May 2021 09:04:41 +0800 Subject: [PATCH] HDFS-15877. BlockReconstructionWork should resetTargets() before BlockManager#validateReconstructionWork return false (#2747) --- .../server/blockmanagement/BlockManager.java | 4 +++- .../blockmanagement/TestBlockManager.java | 22 +++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/blockmanagement/BlockManager.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/blockmanagement/BlockManager.java index 247de6b411..cc7b93fc4e 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/blockmanagement/BlockManager.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/blockmanagement/BlockManager.java @@ -2246,7 +2246,8 @@ public class BlockManager implements BlockStatsMXBean { } } - private boolean validateReconstructionWork(BlockReconstructionWork rw) { + @VisibleForTesting + boolean validateReconstructionWork(BlockReconstructionWork rw) { BlockInfo block = rw.getBlock(); int priority = rw.getPriority(); // Recheck since global lock was released @@ -2281,6 +2282,7 @@ public class BlockManager implements BlockStatsMXBean { placementStatus.getAdditionalReplicasRequired())) { // If the new targets do not meet the placement policy, or at least // reduce the number of replicas needed, then no use continuing. + rw.resetTargets(); return false; } // mark that the reconstruction work is to replicate internal block to a diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/blockmanagement/TestBlockManager.java b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/blockmanagement/TestBlockManager.java index 3b46702f4e..59709423f9 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/blockmanagement/TestBlockManager.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/blockmanagement/TestBlockManager.java @@ -1949,4 +1949,26 @@ public class TestBlockManager { assertEquals(0, ibs.getBlocks()); assertEquals(0, ibs.getECBlocks()); } + + @Test + public void testValidateReconstructionWorkAndRacksNotEnough() { + addNodes(nodes); + // Originally on only nodes in rack A. + List origNodes = rackA; + BlockInfo blockInfo = addBlockOnNodes(0, origNodes); + BlockPlacementStatus status = bm.getBlockPlacementStatus(blockInfo); + // Block has enough copies, but not enough racks. + assertFalse(status.isPlacementPolicySatisfied()); + DatanodeStorageInfo newNode = DFSTestUtil.createDatanodeStorageInfo( + "storage8", "8.8.8.8", "/rackA", "host8"); + BlockReconstructionWork work = bm.scheduleReconstruction(blockInfo, 3); + assertNotNull(work); + assertEquals(1, work.getAdditionalReplRequired()); + // the new targets in rack A. + work.setTargets(new DatanodeStorageInfo[]{newNode}); + // the new targets do not meet the placement policy return false. + assertFalse(bm.validateReconstructionWork(work)); + // validateReconstructionWork return false, need to perform resetTargets(). + assertNull(work.getTargets()); + } }