From 1f30506d20638361fd6a21607e2c132933759554 Mon Sep 17 00:00:00 2001 From: Ye Ni <141253+NickyYe@users.noreply.github.com> Date: Thu, 17 Dec 2020 16:53:59 -0800 Subject: [PATCH] Update DatanodeAdminManager.java --- .../blockmanagement/DatanodeAdminManager.java | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/blockmanagement/DatanodeAdminManager.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/blockmanagement/DatanodeAdminManager.java index 4cd97344d73f7..30c6c67d8c8e3 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/blockmanagement/DatanodeAdminManager.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/blockmanagement/DatanodeAdminManager.java @@ -289,6 +289,21 @@ public void startMaintenance(DatanodeDescriptor node, */ @VisibleForTesting public void stopMaintenance(DatanodeDescriptor node) { + stopMaintenance(node, true); + } + + /** + * Stop maintenance of the specified datanode with option to remove it from + * outOfServiceNodeBlocks to avoid ConcurrentModificationException while + * iterating it. + * + * @param node datanode to stop maintenance + * @param removeOutOfServiceNodeBlocks false means the node won't be removed + * from outOfServiceNodeBlocks. Caller + * will do that. + */ + private void stopMaintenance(DatanodeDescriptor node, + boolean removeOutOfServiceNodeBlocks) { if (node.isMaintenance()) { // Update DN stats maintained by HeartbeatManager hbManager.stopMaintenance(node); @@ -324,7 +339,9 @@ public void stopMaintenance(DatanodeDescriptor node) { // Remove from tracking in DatanodeAdminManager pendingNodes.remove(node); - outOfServiceNodeBlocks.remove(node); + if (removeOutOfServiceNodeBlocks) { + outOfServiceNodeBlocks.remove(node); + } } else { LOG.trace("stopMaintenance: Node {} in {}, nothing to do." + node, node.getAdminState()); @@ -556,7 +573,7 @@ private void check() { boolean fullScan = false; if (dn.isMaintenance() && dn.maintenanceExpired()) { // If maintenance expires, stop tracking it. - stopMaintenance(dn); + stopMaintenance(dn, false); toRemove.add(dn); continue; }