From 62c801568331e0701122c68c6876c1b15721bb82 Mon Sep 17 00:00:00 2001 From: Ayush Saxena Date: Sun, 22 Mar 2020 11:44:18 +0530 Subject: [PATCH] HDFS-15227. NPE if the last block changes from COMMITTED to COMPLETE during FSCK. Contributed by Ayush Saxena. --- .../hdfs/server/namenode/NamenodeFsck.java | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/NamenodeFsck.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/NamenodeFsck.java index b7f26b2e15a..b36c11a6715 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/NamenodeFsck.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/NamenodeFsck.java @@ -38,6 +38,7 @@ import java.util.Set; import java.util.concurrent.ThreadLocalRandom; import org.apache.commons.io.IOUtils; +import org.apache.hadoop.hdfs.server.blockmanagement.BlockUnderConstructionFeature; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.apache.hadoop.classification.InterfaceAudience; @@ -871,16 +872,20 @@ public class NamenodeFsck implements DataEncryptionKeyFactory { String blkName = block.toString(); BlockInfo storedBlock = blockManager.getStoredBlock( block.getLocalBlock()); - DatanodeStorageInfo[] storages = storedBlock - .getUnderConstructionFeature().getExpectedStorageLocations(); - report.append('\n') - .append("Under Construction Block:\n") - .append(blockNumber).append(". ").append(blkName) - .append(" len=").append(block.getNumBytes()) - .append(" Expected_repl=" + storages.length); - String info=getReplicaInfo(storedBlock); - if (!info.isEmpty()){ - report.append(" ").append(info); + BlockUnderConstructionFeature uc = + storedBlock.getUnderConstructionFeature(); + if (uc != null) { + // BlockUnderConstructionFeature can be null, in case the block was + // in committed state, and the IBR came just after the check. + DatanodeStorageInfo[] storages = uc.getExpectedStorageLocations(); + report.append('\n').append("Under Construction Block:\n") + .append(blockNumber).append(". ").append(blkName).append(" len=") + .append(block.getNumBytes()) + .append(" Expected_repl=" + storages.length); + String info = getReplicaInfo(storedBlock); + if (!info.isEmpty()) { + report.append(" ").append(info); + } } }