From 3335e502446b1542fc99c0c831e0542e53eac6f1 Mon Sep 17 00:00:00 2001 From: Tsz-wo Sze Date: Fri, 26 Oct 2012 18:22:49 +0000 Subject: [PATCH] HDFS-3616. Fix a ConcurrentModificationException bug that BP actor threads may not be shutdown properly in DataNode. Contributed by Jing Zhao git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@1402608 13f79535-47bb-0310-9956-ffa450edef68 --- hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt | 3 +++ .../hdfs/server/datanode/BlockPoolManager.java | 18 +++++++++--------- .../hadoop/hdfs/server/datanode/DataNode.java | 8 +++++++- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt b/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt index 3571a4fe8a1..e98ac82bd1e 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt +++ b/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt @@ -504,6 +504,9 @@ Release 2.0.3-alpha - Unreleased out stream returned by WebHdfsFileSystem does not support it. (Jing Zhao via szetszwo) + HDFS-3616. Fix a ConcurrentModificationException bug that BP actor threads + may not be shutdown properly in DataNode. (Jing Zhao via szetszwo) + Release 2.0.2-alpha - 2012-09-07 INCOMPATIBLE CHANGES diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/BlockPoolManager.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/BlockPoolManager.java index eb4f403c4df..54cbb184bf6 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/BlockPoolManager.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/BlockPoolManager.java @@ -106,15 +106,15 @@ synchronized void remove(BPOfferService t) { } } - void shutDownAll() throws InterruptedException { - BPOfferService[] bposArray = this.getAllNamenodeThreads(); - - for (BPOfferService bpos : bposArray) { - bpos.stop(); //interrupts the threads - } - //now join - for (BPOfferService bpos : bposArray) { - bpos.join(); + void shutDownAll(BPOfferService[] bposArray) throws InterruptedException { + if (bposArray != null) { + for (BPOfferService bpos : bposArray) { + bpos.stop(); //interrupts the threads + } + //now join + for (BPOfferService bpos : bposArray) { + bpos.join(); + } } } 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 1983f40243b..b64c41b1ca7 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 @@ -1095,6 +1095,12 @@ public void shutdown() { } } + // We need to make a copy of the original blockPoolManager#offerServices to + // make sure blockPoolManager#shutDownAll() can still access all the + // BPOfferServices, since after setting DataNode#shouldRun to false the + // offerServices may be modified. + BPOfferService[] bposArray = this.blockPoolManager == null ? null + : this.blockPoolManager.getAllNamenodeThreads(); this.shouldRun = false; shutdownPeriodicScanners(); @@ -1141,7 +1147,7 @@ public void shutdown() { if(blockPoolManager != null) { try { - this.blockPoolManager.shutDownAll(); + this.blockPoolManager.shutDownAll(bposArray); } catch (InterruptedException ie) { LOG.warn("Received exception in BlockPoolManager#shutDownAll: ", ie); }