From ade6d9a61eb2e57a975f0efcdf8828d51ffec5fd Mon Sep 17 00:00:00 2001 From: Kihwal Lee Date: Thu, 4 Jun 2015 12:51:00 -0500 Subject: [PATCH] HDFS-8463. Calling DFSInputStream.seekToNewSource just after stream creation causes NullPointerException. Contributed by Masatake Iwasaki. --- hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt | 3 +++ .../apache/hadoop/hdfs/DFSInputStream.java | 3 +++ .../hadoop/hdfs/TestDFSInputStream.java | 25 +++++++++++++++++++ 3 files changed, 31 insertions(+) diff --git a/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt b/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt index d65e5132b2..bb65105c5e 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt +++ b/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt @@ -846,6 +846,9 @@ Release 2.8.0 - UNRELEASED HDFS-3716. Purger should remove stale fsimage ckpt files (J.Andreina via vinayakumarb) + HDFS-8463. Calling DFSInputStream.seekToNewSource just after stream creation + causes NullPointerException (Masatake Iwasaki via kihwal) + Release 2.7.1 - UNRELEASED INCOMPATIBLE CHANGES diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/DFSInputStream.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/DFSInputStream.java index 8a3f730952..6563d7b87c 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/DFSInputStream.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/DFSInputStream.java @@ -1533,6 +1533,9 @@ private boolean seekToBlockSource(long targetPos) */ @Override public synchronized boolean seekToNewSource(long targetPos) throws IOException { + if (currentNode == null) { + return seekToBlockSource(targetPos); + } boolean markedDead = deadNodes.containsKey(currentNode); addToDeadNodes(currentNode); DatanodeInfo oldNode = currentNode; diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestDFSInputStream.java b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestDFSInputStream.java index b9ec2cea3b..26412c817c 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestDFSInputStream.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestDFSInputStream.java @@ -18,6 +18,8 @@ package org.apache.hadoop.hdfs; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; import static org.hamcrest.CoreMatchers.equalTo; import java.io.File; @@ -28,6 +30,7 @@ import org.apache.hadoop.fs.FSDataOutputStream; import org.apache.hadoop.fs.Path; import org.apache.hadoop.hdfs.client.HdfsClientConfigKeys; +import org.apache.hadoop.hdfs.protocol.DatanodeInfo; import org.apache.hadoop.net.unix.DomainSocket; import org.apache.hadoop.net.unix.TemporarySocketDirectory; import org.junit.Assume; @@ -111,4 +114,26 @@ public void testSkipWithLocalBlockReader() throws IOException { } } + @Test(timeout=60000) + public void testSeekToNewSource() throws IOException { + Configuration conf = new Configuration(); + MiniDFSCluster cluster = + new MiniDFSCluster.Builder(conf).numDataNodes(3).build(); + DistributedFileSystem fs = cluster.getFileSystem(); + Path path = new Path("/testfile"); + DFSTestUtil.createFile(fs, path, 1024, (short) 3, 0); + DFSInputStream fin = fs.dfs.open("/testfile"); + try { + fin.seekToNewSource(100); + assertEquals(100, fin.getPos()); + DatanodeInfo firstNode = fin.getCurrentDatanode(); + assertNotNull(firstNode); + fin.seekToNewSource(100); + assertEquals(100, fin.getPos()); + assertFalse(firstNode.equals(fin.getCurrentDatanode())); + } finally { + fin.close(); + cluster.shutdown(); + } + } }