Repository: hadoop Updated Branches: refs/heads/branch-2.7 86f291f05 -> b2dfab432
HDFS-10512. VolumeScanner may terminate due to NPE in DataNode.reportBadBlocks. Contributed by Wei-Chiu Chuang and Yiqun Lin. (cherry picked from commit da6f1b88dd47e22b24d44f6fc8bbee73e85746f7) (cherry picked from commit 96e68e722f0fe99d1609b38377014c04ef5b6640) Project: http://git-wip-us.apache.org/repos/asf/hadoop/repo Commit: http://git-wip-us.apache.org/repos/asf/hadoop/commit/b2dfab43 Tree: http://git-wip-us.apache.org/repos/asf/hadoop/tree/b2dfab43 Diff: http://git-wip-us.apache.org/repos/asf/hadoop/diff/b2dfab43 Branch: refs/heads/branch-2.7 Commit: b2dfab4326605b4b282a3ae75d00223b35979662 Parents: 86f291f Author: Yongjun Zhang <yzh...@cloudera.com> Authored: Fri Jul 8 19:40:44 2016 -0700 Committer: Wei-Chiu Chuang <weic...@apache.org> Committed: Tue Oct 18 09:09:06 2016 -0700 ---------------------------------------------------------------------- hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt | 3 ++ .../hadoop/hdfs/server/datanode/DataNode.java | 23 ++++++++++- .../hdfs/server/datanode/VolumeScanner.java | 2 +- .../datanode/fsdataset/impl/FsDatasetImpl.java | 3 +- .../fsdataset/impl/TestFsDatasetImpl.java | 42 ++++++++++++++++++++ 5 files changed, 70 insertions(+), 3 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/hadoop/blob/b2dfab43/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt ---------------------------------------------------------------------- diff --git a/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt b/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt index 277efe1..a13a566 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt +++ b/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt @@ -154,6 +154,9 @@ Release 2.7.4 - UNRELEASED HDFS-11002. Fix broken attr/getfattr/setfattr links in ExtendedAttributes.md. (Mingliang Liu via aajisaka) + HDFS-10512. VolumeScanner may terminate due to NPE in + DataNode.reportBadBlocks. Contributed by Wei-Chiu Chuang and Yiqun Lin. + Release 2.7.3 - 2016-08-25 INCOMPATIBLE CHANGES http://git-wip-us.apache.org/repos/asf/hadoop/blob/b2dfab43/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/DataNode.java ---------------------------------------------------------------------- diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/DataNode.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/DataNode.java index 9ef23d4..eb159eb 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/DataNode.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/DataNode.java @@ -990,8 +990,25 @@ public class DataNode extends ReconfigurableBase * Report a bad block which is hosted on the local DN. */ public void reportBadBlocks(ExtendedBlock block) throws IOException{ - BPOfferService bpos = getBPOSForBlock(block); FsVolumeSpi volume = getFSDataset().getVolume(block); + if (volume == null) { + LOG.warn("Cannot find FsVolumeSpi to report bad block: " + block); + return; + } + reportBadBlocks(block, volume); + } + + /** + * Report a bad block which is hosted on the local DN. + * + * @param block the bad block which is hosted on the local DN + * @param volume the volume that block is stored in and the volume + * must not be null + * @throws IOException + */ + public void reportBadBlocks(ExtendedBlock block, FsVolumeSpi volume) + throws IOException { + BPOfferService bpos = getBPOSForBlock(block); bpos.reportBadBlocks( block, volume.getStorageID(), volume.getStorageType()); } @@ -1860,6 +1877,10 @@ public class DataNode extends ReconfigurableBase private void reportBadBlock(final BPOfferService bpos, final ExtendedBlock block, final String msg) { FsVolumeSpi volume = getFSDataset().getVolume(block); + if (volume == null) { + LOG.warn("Cannot find FsVolumeSpi to report bad block: " + block); + return; + } bpos.reportBadBlocks( block, volume.getStorageID(), volume.getStorageType()); LOG.warn(msg); http://git-wip-us.apache.org/repos/asf/hadoop/blob/b2dfab43/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/VolumeScanner.java ---------------------------------------------------------------------- diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/VolumeScanner.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/VolumeScanner.java index ad546d2..d0300f6 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/VolumeScanner.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/VolumeScanner.java @@ -285,7 +285,7 @@ public class VolumeScanner extends Thread { LOG.warn("Reporting bad " + block + " with volume " + volume.getBasePath(), e); try { - scanner.datanode.reportBadBlocks(block); + scanner.datanode.reportBadBlocks(block, volume); } catch (IOException ie) { // This is bad, but not bad enough to shut down the scanner. LOG.warn("Cannot report bad block " + block, ie); http://git-wip-us.apache.org/repos/asf/hadoop/blob/b2dfab43/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/fsdataset/impl/FsDatasetImpl.java ---------------------------------------------------------------------- diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/fsdataset/impl/FsDatasetImpl.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/fsdataset/impl/FsDatasetImpl.java index e93784e..400a778 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/fsdataset/impl/FsDatasetImpl.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/fsdataset/impl/FsDatasetImpl.java @@ -2254,7 +2254,8 @@ class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> { LOG.warn("Reporting the block " + corruptBlock + " as corrupt due to length mismatch"); try { - datanode.reportBadBlocks(new ExtendedBlock(bpid, corruptBlock)); + datanode.reportBadBlocks(new ExtendedBlock(bpid, corruptBlock), + memBlockInfo.getVolume()); } catch (IOException e) { LOG.warn("Failed to repot bad block " + corruptBlock, e); } http://git-wip-us.apache.org/repos/asf/hadoop/blob/b2dfab43/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/datanode/fsdataset/impl/TestFsDatasetImpl.java ---------------------------------------------------------------------- diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/datanode/fsdataset/impl/TestFsDatasetImpl.java b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/datanode/fsdataset/impl/TestFsDatasetImpl.java index f62b2f1..a3b1bff 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/datanode/fsdataset/impl/TestFsDatasetImpl.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/datanode/fsdataset/impl/TestFsDatasetImpl.java @@ -33,6 +33,7 @@ import org.apache.hadoop.hdfs.protocol.Block; import org.apache.hadoop.hdfs.protocol.DatanodeInfo; import org.apache.hadoop.hdfs.protocol.ExtendedBlock; import org.apache.hadoop.hdfs.protocol.LocatedBlock; +import org.apache.hadoop.hdfs.server.blockmanagement.BlockManagerTestUtil; import org.apache.hadoop.hdfs.server.common.HdfsServerConstants; import org.apache.hadoop.hdfs.server.common.Storage; import org.apache.hadoop.hdfs.server.common.StorageInfo; @@ -503,4 +504,45 @@ public class TestFsDatasetImpl { cluster.shutdown(); } } + + @Test(timeout = 30000) + public void testReportBadBlocks() throws Exception { + boolean threwException = false; + MiniDFSCluster cluster = null; + try { + Configuration config = new HdfsConfiguration(); + cluster = new MiniDFSCluster.Builder(config).numDataNodes(1).build(); + cluster.waitActive(); + + Assert.assertEquals(0, cluster.getNamesystem().getCorruptReplicaBlocks()); + DataNode dataNode = cluster.getDataNodes().get(0); + ExtendedBlock block = + new ExtendedBlock(cluster.getNamesystem().getBlockPoolId(), 0); + try { + // Test the reportBadBlocks when the volume is null + dataNode.reportBadBlocks(block); + } catch (NullPointerException npe) { + threwException = true; + } + Thread.sleep(3000); + Assert.assertFalse(threwException); + Assert.assertEquals(0, cluster.getNamesystem().getCorruptReplicaBlocks()); + + FileSystem fs = cluster.getFileSystem(); + Path filePath = new Path("testData"); + DFSTestUtil.createFile(fs, filePath, 1, (short) 1, 0); + + block = DFSTestUtil.getFirstBlock(fs, filePath); + // Test for the overloaded method reportBadBlocks + dataNode.reportBadBlocks(block, dataNode.getFSDataset() + .getVolumes().get(0)); + Thread.sleep(3000); + BlockManagerTestUtil.updateState(cluster.getNamesystem() + .getBlockManager()); + // Verify the bad block has been reported to namenode + Assert.assertEquals(1, cluster.getNamesystem().getCorruptReplicaBlocks()); + } finally { + cluster.shutdown(); + } + } } --------------------------------------------------------------------- To unsubscribe, e-mail: common-commits-unsubscr...@hadoop.apache.org For additional commands, e-mail: common-commits-h...@hadoop.apache.org