diff --git a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/replication/MisReplicationHandler.java b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/replication/MisReplicationHandler.java index 0104925ab8d4..b418b9236eab 100644 --- a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/replication/MisReplicationHandler.java +++ b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/replication/MisReplicationHandler.java @@ -95,15 +95,17 @@ private List getTargetDatanodes( } private Set filterSources(Set replicas) { - return replicas.stream().filter(r -> r - .getState() == StorageContainerDatanodeProtocolProtos - .ContainerReplicaProto.State.CLOSED) - .filter(r -> ReplicationManager - .getNodeStatus(r.getDatanodeDetails(), nodeManager) - .isHealthy()) - .filter(r -> r.getDatanodeDetails().getPersistedOpState() - == HddsProtos.NodeOperationalState.IN_SERVICE) - .collect(Collectors.toSet()); + return replicas.stream() + .filter(r -> r.getState() == StorageContainerDatanodeProtocolProtos + .ContainerReplicaProto.State.CLOSED || r.getState() == + StorageContainerDatanodeProtocolProtos + .ContainerReplicaProto.State.QUASI_CLOSED + ) + .filter(r -> ReplicationManager.getNodeStatus( + r.getDatanodeDetails(), nodeManager).isHealthy()) + .filter(r -> r.getDatanodeDetails().getPersistedOpState() + == HddsProtos.NodeOperationalState.IN_SERVICE) + .collect(Collectors.toSet()); } protected abstract ReplicateContainerCommand getReplicateCommand( diff --git a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/TestRatisMisReplicationHandler.java b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/TestRatisMisReplicationHandler.java index de9574e03d9f..f960974256bd 100644 --- a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/TestRatisMisReplicationHandler.java +++ b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/TestRatisMisReplicationHandler.java @@ -22,6 +22,7 @@ import org.apache.hadoop.hdds.conf.OzoneConfiguration; import org.apache.hadoop.hdds.protocol.MockDatanodeDetails; import org.apache.hadoop.hdds.protocol.proto.HddsProtos.ReplicationFactor; +import org.apache.hadoop.hdds.protocol.proto.StorageContainerDatanodeProtocolProtos.ContainerReplicaProto.State; import org.apache.hadoop.hdds.scm.ContainerPlacementStatus; import org.apache.hadoop.hdds.scm.PlacementPolicy; import org.apache.hadoop.hdds.scm.container.ContainerReplica; @@ -67,6 +68,17 @@ public void testMisReplicationWithAllNodesAvailable(int misreplicationCount) 0, misreplicationCount, Math.min(misreplicationCount, 3)); } + @ParameterizedTest + @ValueSource(ints = {1, 2, 3, 4, 5, 6, 7}) + public void testMisReplicationWithAllNodesAvailableQuasiClosed( + int misreplicationCount) throws IOException { + Set availableReplicas = ReplicationTestUtil + .createReplicas(State.QUASI_CLOSED, Pair.of(IN_SERVICE, 0), + Pair.of(IN_SERVICE, 0), Pair.of(IN_SERVICE, 0)); + testMisReplication(availableReplicas, Collections.emptyList(), + 0, misreplicationCount, Math.min(misreplicationCount, 3)); + } + @Test public void testMisReplicationWithNoNodesReturned() throws IOException { Set availableReplicas = ReplicationTestUtil