diff --git a/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt b/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt index 3571a4fe8a..e98ac82bd1 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 eb4f403c4d..54cbb184bf 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 1983f40243..b64c41b1ca 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); }