This is an automated email from the ASF dual-hosted git repository.

tasanuma pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/hadoop.git


The following commit(s) were added to refs/heads/trunk by this push:
     new fc71dc3e94c8 HDFS-17284. Fix int overflow in calculating 
numEcReplicatedTasks and numReplicationTasks during block recovery (#6348)
fc71dc3e94c8 is described below

commit fc71dc3e94c8c89bdbecd24a77ab822b183b78b7
Author: zhtttylz <hualon...@hotmail.com>
AuthorDate: Wed Dec 27 09:43:10 2023 +0800

    HDFS-17284. Fix int overflow in calculating numEcReplicatedTasks and 
numReplicationTasks during block recovery (#6348)
    
    Reviewed-by: Shilun Fan <slfan1...@apache.org>
    Signed-off-by: Takanobu Asanuma <tasan...@apache.org>
---
 .../server/blockmanagement/DatanodeManager.java    |  6 +-
 .../blockmanagement/TestDatanodeManager.java       | 68 ++++++++++++++++++++++
 2 files changed, 71 insertions(+), 3 deletions(-)

diff --git 
a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/blockmanagement/DatanodeManager.java
 
b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/blockmanagement/DatanodeManager.java
index 1d2ed7464080..ebd2fa992e97 100644
--- 
a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/blockmanagement/DatanodeManager.java
+++ 
b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/blockmanagement/DatanodeManager.java
@@ -1864,11 +1864,11 @@ public class DatanodeManager {
         maxECReplicatedTransfers = maxTransfers;
       }
       int numReplicationTasks = (int) Math.ceil(
-          (double) (replicationBlocks * maxTransfers) / totalBlocks);
+          (double) replicationBlocks * maxTransfers / totalBlocks);
       int numEcReplicatedTasks = (int) Math.ceil(
-              (double) (ecBlocksToBeReplicated * maxECReplicatedTransfers) / 
totalBlocks);
+          (double) ecBlocksToBeReplicated * maxECReplicatedTransfers / 
totalBlocks);
       int numECReconstructedTasks = (int) Math.ceil(
-          (double) (ecBlocksToBeErasureCoded * maxTransfers) / totalBlocks);
+          (double) ecBlocksToBeErasureCoded * maxTransfers / totalBlocks);
       LOG.debug("Pending replication tasks: {} ec to be replicated tasks: {} " 
+
                       "ec reconstruction tasks: {}.",
           numReplicationTasks, numEcReplicatedTasks, numECReconstructedTasks);
diff --git 
a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/blockmanagement/TestDatanodeManager.java
 
b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/blockmanagement/TestDatanodeManager.java
index 015a0385a735..bcdba9577587 100644
--- 
a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/blockmanagement/TestDatanodeManager.java
+++ 
b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/blockmanagement/TestDatanodeManager.java
@@ -71,6 +71,8 @@ import org.apache.hadoop.test.Whitebox;
 import org.junit.Assert;
 import org.junit.Test;
 import org.mockito.Mockito;
+import org.mockito.ArgumentCaptor;
+import org.mockito.ArgumentMatchers;
 
 import static org.hamcrest.core.Is.is;
 import static org.junit.Assert.*;
@@ -1126,4 +1128,70 @@ public class TestDatanodeManager {
       super();
     }
   }
+
+  @Test
+  public void testComputeReconstructedTaskNum() throws IOException {
+    verifyComputeReconstructedTaskNum(100, 100, 150, 250, 100);
+    verifyComputeReconstructedTaskNum(200, 100000, 200000, 300000, 400000);
+    verifyComputeReconstructedTaskNum(1000000, 100, 150, 250, 100);
+    verifyComputeReconstructedTaskNum(14000000, 200, 200, 400, 200);
+
+  }
+  public void verifyComputeReconstructedTaskNum(int xmitsInProgress, int 
numReplicationBlocks,
+      int maxTransfers, int numECTasksToBeReplicated, int 
numBlocksToBeErasureCoded)
+      throws IOException {
+    FSNamesystem fsn = Mockito.mock(FSNamesystem.class);
+    Mockito.when(fsn.hasWriteLock()).thenReturn(true);
+    Configuration conf = new Configuration();
+    conf.setInt(DFSConfigKeys.DFS_NAMENODE_REPLICATION_MAX_STREAMS_KEY, 
maxTransfers);
+    DatanodeManager dm = Mockito.spy(mockDatanodeManager(fsn, conf));
+
+    DatanodeDescriptor nodeInfo = Mockito.mock(DatanodeDescriptor.class);
+    Mockito.when(nodeInfo.isRegistered()).thenReturn(true);
+    Mockito.when(nodeInfo.getStorageInfos()).thenReturn(new 
DatanodeStorageInfo[0]);
+
+    
Mockito.when(nodeInfo.getNumberOfReplicateBlocks()).thenReturn(numReplicationBlocks);
+    
Mockito.when(nodeInfo.getNumberOfECBlocksToBeReplicated()).thenReturn(numECTasksToBeReplicated);
+    Mockito.when(nodeInfo.getNumberOfBlocksToBeErasureCoded())
+        .thenReturn(numBlocksToBeErasureCoded);
+
+    // Create an ArgumentCaptor to capture the counts for numReplicationTasks,
+    // numEcReplicatedTasks,numECReconstructedTasks.
+    ArgumentCaptor<Integer> captor = ArgumentCaptor.forClass(Integer.class);
+    Mockito.when(nodeInfo.getErasureCodeCommand(ArgumentMatchers.anyInt()))
+        .thenReturn(Collections.nCopies(0, null));
+    Mockito.when(nodeInfo.getReplicationCommand(ArgumentMatchers.anyInt()))
+        .thenReturn(Collections.nCopies(0, null));
+    Mockito.when(nodeInfo.getECReplicatedCommand(ArgumentMatchers.anyInt()))
+        .thenReturn(Collections.nCopies(0, null));
+
+    DatanodeRegistration nodeReg = Mockito.mock(DatanodeRegistration.class);
+    Mockito.when(dm.getDatanode(nodeReg)).thenReturn(nodeInfo);
+
+
+    dm.handleHeartbeat(nodeReg, new StorageReport[1], "bp-123", 0, 0,
+        10, xmitsInProgress, 0, null, SlowPeerReports.EMPTY_REPORT,
+        SlowDiskReports.EMPTY_REPORT);
+
+    Mockito.verify(nodeInfo).getReplicationCommand(captor.capture());
+    int numReplicationTasks = captor.getValue();
+
+    Mockito.verify(nodeInfo).getECReplicatedCommand(captor.capture());
+    int numEcReplicatedTasks = captor.getValue();
+
+    Mockito.verify(nodeInfo).getErasureCodeCommand(captor.capture());
+    int numECReconstructedTasks = captor.getValue();
+
+    // Verify that when DN xmitsInProgress exceeds maxTransfers,
+    // the number of tasks should be <= 0.
+    if (xmitsInProgress >= maxTransfers) {
+      assertTrue(numReplicationTasks <= 0);
+      assertTrue(numEcReplicatedTasks <= 0);
+      assertTrue(numECReconstructedTasks <= 0);
+    } else {
+      assertTrue(numReplicationTasks >= 0);
+      assertTrue(numEcReplicatedTasks >= 0);
+      assertTrue(numECReconstructedTasks >= 0);
+    }
+  }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: common-commits-unsubscr...@hadoop.apache.org
For additional commands, e-mail: common-commits-h...@hadoop.apache.org

Reply via email to