From ab451b8e428defee8836beeca57ec0fc741383f3 Mon Sep 17 00:00:00 2001 From: He Xiaoqiao Date: Wed, 4 Nov 2020 13:53:46 +0800 Subject: [PATCH] HDFS-15651. Client could not obtain block when DN CommandProcessingThread exit. Contributed by Aiphago. Reviewed-by: He Xiaoqiao Reviewed-by: Yiqun Lin (cherry picked from commit 3067a25fa12a012709f43aa35cc606db6fb137f9) Conflicts: hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/datanode/TestBPOfferService.java --- .../hdfs/server/datanode/BPServiceActor.java | 12 ++++++++++ .../server/datanode/TestBPOfferService.java | 24 ++++++++++++++++++- 2 files changed, 35 insertions(+), 1 deletion(-) 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 49156c251a..0cc9fac8df 100755 --- 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 @@ -1312,6 +1312,10 @@ public void run() { processQueue(); } catch (Throwable t) { LOG.error("{} encountered fatal exception and exit.", getName(), t); + runningState = RunningState.FAILED; + } finally { + LOG.warn("Ending command processor service for: " + this); + shouldServiceRun = false; } } @@ -1327,6 +1331,7 @@ private void processQueue() { dn.getMetrics().incrNumProcessedCommands(); } catch (InterruptedException e) { LOG.error("{} encountered interrupt and exit.", getName()); + Thread.currentThread().interrupt(); // ignore unless thread was specifically interrupted. if (Thread.interrupted()) { break; @@ -1398,4 +1403,11 @@ void enqueue(DatanodeCommand[] cmds) throws InterruptedException { dn.getMetrics().incrActorCmdQueueLength(1); } } + + @VisibleForTesting + void stopCommandProcessingThread() { + if (commandProcessingThread != null) { + commandProcessingThread.interrupt(); + } + } } \ No newline at end of file diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/datanode/TestBPOfferService.java b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/datanode/TestBPOfferService.java index 9b47884aec..a344011505 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/datanode/TestBPOfferService.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/datanode/TestBPOfferService.java @@ -1216,4 +1216,26 @@ public void testCommandProcessingThread() throws Exception { } } } -} \ No newline at end of file + + @Test(timeout = 5000) + public void testCommandProcessingThreadExit() throws Exception { + Configuration conf = new HdfsConfiguration(); + MiniDFSCluster cluster = new MiniDFSCluster.Builder(conf). + numDataNodes(1).build(); + try { + List datanodes = cluster.getDataNodes(); + DataNode dataNode = datanodes.get(0); + List allBpOs = dataNode.getAllBpOs(); + BPOfferService bpos = allBpOs.get(0); + waitForInitialization(bpos); + BPServiceActor actor = bpos.getBPServiceActors().get(0); + // Stop and wait util actor exit. + actor.stopCommandProcessingThread(); + GenericTestUtils.waitFor(() -> !actor.isAlive(), 100, 3000); + } finally { + if (cluster != null) { + cluster.shutdown(); + } + } + } +}