From 69b903bbd8e2dafac6b2cb1d748ea666b6f877cf Mon Sep 17 00:00:00 2001 From: Surendra Singh Lilhore Date: Sun, 5 May 2019 16:33:52 +0530 Subject: [PATCH] HDFS-14372. NPE while DN is shutting down. Contributed by lujie. --- .../hdfs/server/datanode/BPServiceActor.java | 8 +++- .../server/datanode/TestDatanodeRegister.java | 44 +++++++++++++++++++ 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/BPServiceActor.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/BPServiceActor.java index b0a721f9700..83b0460e07d 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/BPServiceActor.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/BPServiceActor.java @@ -803,8 +803,12 @@ class BPServiceActor implements Runnable { sleepAndLogInterrupts(1000, "connecting to server"); } } - - LOG.info("Block pool " + this + " successfully registered with NN"); + + if (bpRegistration == null) { + throw new IOException("DN shut down before block pool registered"); + } + + LOG.info(this + " successfully registered with NN"); bpos.registrationSucceeded(this, bpRegistration); // reset lease id whenever registered to NN. diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/datanode/TestDatanodeRegister.java b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/datanode/TestDatanodeRegister.java index 13fe9e39b04..95a361a65dd 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/datanode/TestDatanodeRegister.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/datanode/TestDatanodeRegister.java @@ -26,9 +26,20 @@ import static org.mockito.Mockito.when; import java.io.IOException; import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.Collections; import org.slf4j.Logger; import org.slf4j.LoggerFactory; + +import com.google.common.collect.Lists; + +import org.junit.Assert; + +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.fs.FileSystem; +import org.apache.hadoop.hdfs.DFSConfigKeys; +import org.apache.hadoop.hdfs.HdfsConfiguration; import org.apache.hadoop.hdfs.protocolPB.DatanodeProtocolClientSideTranslatorPB; import org.apache.hadoop.hdfs.server.common.HdfsServerConstants; import org.apache.hadoop.hdfs.server.common.IncorrectVersionException; @@ -118,4 +129,37 @@ public class TestDatanodeRegister { fail("Should not fail to retrieve NS info from DN with different layout version"); } } + + @Test + public void testDNShutdwonBeforeRegister() throws Exception { + final InetSocketAddress nnADDR = new InetSocketAddress( + "localhost", 5020); + Configuration conf = new HdfsConfiguration(); + conf.set(DFSConfigKeys.DFS_DATANODE_ADDRESS_KEY, "0.0.0.0:0"); + conf.set(DFSConfigKeys.DFS_DATANODE_HTTP_ADDRESS_KEY, "0.0.0.0:0"); + conf.set(DFSConfigKeys.DFS_DATANODE_IPC_ADDRESS_KEY, "0.0.0.0:0"); + FileSystem.setDefaultUri(conf, + "hdfs://" + nnADDR.getHostName() + ":" + nnADDR.getPort()); + ArrayList locations = new ArrayList<>(); + DataNode dn = new DataNode(conf, locations, null, null); + BPOfferService bpos = new BPOfferService("test_ns", + Lists.newArrayList("nn0"), Lists.newArrayList(nnADDR), + Collections.nCopies(1, null), dn); + DatanodeProtocolClientSideTranslatorPB fakeDnProt = + mock(DatanodeProtocolClientSideTranslatorPB.class); + when(fakeDnProt.versionRequest()).thenReturn(fakeNsInfo); + + BPServiceActor localActor = new BPServiceActor("test", "test", + INVALID_ADDR, null, bpos); + localActor.setNameNode(fakeDnProt); + try { + NamespaceInfo nsInfo = localActor.retrieveNamespaceInfo(); + bpos.setNamespaceInfo(nsInfo); + localActor.stop(); + localActor.register(nsInfo); + } catch (IOException e) { + Assert.assertEquals("DN shut down before block pool registered", + e.getMessage()); + } + } }