--- ./source/private_module/pmgr/pmgr_intf.c	2018-04-20 08:53:49.000000000 +0000
+++ ./source/private_module/pmgr/pmgr_intf.c.hotpatch	2021-05-10 12:50:47.000000000 +0000
@@ -637,7 +637,7 @@
     
     return;
 }
-
+extern void sendReconAlarm(poolid_t poolId, diskid_t diskId, uint32_t taskType, uint32_t alarmType);
 /**************************************************************************
     :  ɾ洢poolʱָ澯
 :  poolObj   pool
@@ -665,8 +665,8 @@
     for (index = 0; index < memberDiskNum; index++)
     {
         diskId = poolCfgDiskInfo->memberDiskId[index];
-
-        /* ϱԱ̰γ澯ָ */
+        sendReconAlarm(poolId, diskId, PRE_COPY, ALM_ALARM_TYPE_RESUME);
+        sendReconAlarm(poolId, diskId, DISK_RECON, ALM_ALARM_TYPE_RESUME);
         (void)sendDiskAlarm(poolId, diskId, ALM_DISK_POOL_DISK_OUT, ALM_ALARM_TYPE_RESUME, poolName);
     }
     
--- ./source/private_module/pmgr/pmgr_task_mgr.c	2018-02-09 13:47:03.000000000 +0000
+++ ./source/private_module/pmgr/pmgr_task_mgr.c.hotpatch	2021-06-04 10:15:22.000000000 +0000
@@ -3678,19 +3678,19 @@
     return;
 }
 
+void sendReconAlarm(poolid_t poolId, diskid_t diskId, uint32_t taskType, uint32_t alarmType);
+void sendReconFailAlarm(TASK_RECORD_S *taskRcd, int32_t result);
+void resumeReconFailAlarm(TASK_RECORD_S *taskRcd);
 /*******************************************************************************
      :  񷵻ؽstep
  :  ehTask     ṹ
             result      ִн
- :  
- ֵ  :  
-     :  
 *******************************************************************************/
 void fillTaskFailStepByResult(PMGR_EH_TASK *ehTask, int32_t result)
 {
     TASK_RECORD_S *taskRcd = NULL;
     taskRcd = ehTask->taskRcd;
-    
+    taskRcd->reserve[0]++;
     if (RETURN_NO_SPACE == result)
     {        
   
@@ -3707,7 +3707,7 @@
         DBG_LogInfo(PMGR_LOG_ID0764, "Execute soft reconstruct task(task id 0x%llx, pool %u, "
                     "disk %u, task name %s) succeeded.", taskRcd->taskId, 
                     taskRcd->poolId, taskRcd->diskId, getTaskName(taskRcd->taskType));
-
+		ehTask->pad1 = 0x56;
         fillSoftReconSucceedTaskStep((TASK_S *)ehTask);
     }
     else
@@ -3715,20 +3715,20 @@
         if (LEVELING == taskRcd->taskType)
         {
             DBG_LogError(PMGR_LOG_ID0765, "Execute leveling task(task id 0x%llx, "
-                         "pool %u, tier %u, task name %s) failed.", taskRcd->taskId, 
-                         taskRcd->poolId, taskRcd->tierId, getTaskName(taskRcd->taskType));
+                         "pool %u, tier %u, task name %s) failed times(%u) ret(%d).", taskRcd->taskId, 
+                         taskRcd->poolId, taskRcd->tierId, getTaskName(taskRcd->taskType), taskRcd->reserve[0], result);
         }
         else
         {
             DBG_LogError(PMGR_LOG_ID0766, "Execute reconstruction task(task id 0x%llx, "
-                        "pool %u, disk %u, task name %s) failed.", taskRcd->taskId, 
-                        taskRcd->poolId, taskRcd->diskId, getTaskName(taskRcd->taskType));
+                        "pool %u, disk %u, task name %s) failed times(%u) ret(%d).", taskRcd->taskId, 
+                        taskRcd->poolId, taskRcd->diskId, getTaskName(taskRcd->taskType), taskRcd->reserve[0], result);
         }     
 
         ehTask->eventType = PMGR_TASK_ERROR;
         fillHandleFailedTaskStep((TASK_S *)ehTask);
     } 
-    
+    sendReconFailAlarm(taskRcd, result);
     sendTaskFailAlarm(taskRcd, result);
 
     /*BDMӲ̷޸
@@ -3833,7 +3833,6 @@
                 (void)ALM_SendAlarm(PID_PMGR, LOG_DISK_POOL_LEVELING_END, ALM_ALARM_TYPE_EVENT, "%s, %u, %u, %u", 
                                     poolName, taskRcd->poolId, nodeGroupId, taskRcd->tierId);
             }
-			/* Modified by w90004114 for PANGEA DMI 2014/3/24 begin */
             else if (PRE_COPY == taskRcd->taskType)
             {
                 /* ϱԤɹ־ */
@@ -3851,6 +3850,7 @@
                                     diskInfo.slot, diskInfo.type);
              /* Modified by w90004114 for PANGEA DMI 2014/3/24 end */
             }
+            resumeReconFailAlarm(taskRcd);
         }    
     }
     else
@@ -5682,3 +5682,173 @@
     return;
 }
 
+#define MAX_RECON_FAIL_TIMES_FOR_ALARM 3  /* عʧﵽٴϱ澯 */
+#define ALM_DISK_POOL_DISK_RECON_FAIL       0x00F010A0075ULL    /* Ӳ̳عʧ */
+#define ALM_DISK_POOL_DISK_PRECOPY_FAIL     0x00F010A0076ULL    /* Ӳ̳Ԥʧ */
+/*******************************************************************************
+     :  ϱعԤʧܸ澯ָ
+ :  poolId      ӲID
+            diskId      Ӳ߼ID
+            taskType    
+            alarmType   澯ϱ/澯ָ
+ :  
+ ֵ  :  
+     :  
+*******************************************************************************/
+
+void sendReconAlarm(poolid_t poolId, diskid_t diskId, uint32_t taskType, uint32_t alarmType)
+{
+    int32_t ret;
+    char poolName[MAX_NAME_LEN] = {0};
+    LD_INFO_S diskInfo = {0};
+    PMGR_FRAME_INFO_S frameInfo = {0};
+    char resultOutput[] = "--";
+    
+    ret = getPoolName(poolId, poolName);
+    if (RETURN_OK != ret)
+    {
+        DBG_LogError(PMGR_LOG_ID0760, "Get the name of pool(pool id %u) failed.", poolId); 
+        return;
+    }
+    
+    CLEAR_LD_INFO_SEGMENT(diskInfo);
+    
+    ret = ldGetLogicDiskInfo(diskId, &diskInfo);
+    if (RETURN_OK != ret)
+    {
+        DBG_LogError(PMGR_LOG_ID0761, "Get disk(%u) info from BDM failed, return 0x%x.", diskId, ret); 
+        return;
+    }
+
+    ret = getUserFrameInfoForAlarm(diskInfo.frame, &frameInfo);
+    if (RETURN_OK != ret)
+    {
+        DBG_LogError(PMGR_LOG_ID3173, "Get frame info of disk(disk %u, frame %u, slot %u) failed,"
+                     " return 0x%x.", diskId, diskInfo.frame, diskInfo.slot, ret);
+        return;
+    }
+
+    if (PRE_COPY == taskType)
+    {
+        (void)ALM_SendAlarm(PID_PMGR, ALM_DISK_POOL_DISK_PRECOPY_FAIL, alarmType, 
+                            "%s, %u, %u, %s, %u, %u, %s, %s", poolName, poolId, 
+                            GET_FRAME_TYPE(diskInfo.frame), frameInfo.frameName, 
+                            diskInfo.slot, diskInfo.type, diskInfo.wwn, resultOutput);
+    }
+    else
+    {
+        (void)ALM_SendAlarm(PID_PMGR, ALM_DISK_POOL_DISK_RECON_FAIL, alarmType, 
+                            "%s, %u, %u, %s, %u, %u, %s, %s", poolName, poolId, 
+                            GET_FRAME_TYPE(diskInfo.frame), frameInfo.frameName,
+                            diskInfo.slot, diskInfo.type, diskInfo.wwn, resultOutput);
+    }
+
+    return;
+
+}
+
+/*******************************************************************************
+     :  ǷҪϱعʧܸ澯
+ :  taskRcd     ṹ
+            result      ع
+            
+ :  
+ ֵ  :  
+     :  澯ϱ:
+            1ȫعԤָعϱ澯
+            2ȱռ䲻㵼µʧܣϱ澯
+            3Ӳϣϱ澯
+            4عɹϱ澯
+            5ԭµعʧܴﵽ3ʱϱ澯            
+*******************************************************************************/
+bool checkNeedSendReconFailAlarm(TASK_RECORD_S *taskRcd, int32_t result)
+{
+    int32_t ret;
+    HEALTH_STATUS_E healthStatus;
+    RUNNING_STATUS_E runningStatus;
+    
+    if (DISK_RECON != taskRcd->taskType && 
+        PRE_COPY != taskRcd->taskType && 
+        RECOVER_RECON != taskRcd->taskType)
+    {
+        return FALSE;
+    }
+
+    if (RETURN_NO_SPACE == result)
+    {
+        return FALSE;
+    }
+    
+    ret = queryDiskPoolStatus(taskRcd->poolId, &healthStatus, &runningStatus);
+    if (RETURN_OK != ret)
+    {    
+        return FALSE;
+    }
+
+    if (HEALTH_STATUS_FAULT == healthStatus || 
+        RUNNING_STATUS_OFFLINE == runningStatus)
+    {
+        return FALSE;
+    }
+
+    if (RETURN_SOFT_RECON_SUCCESS == result)
+    {
+        return TRUE;
+    }
+
+    if (taskRcd->reserve[0] == MAX_RECON_FAIL_TIMES_FOR_ALARM) 
+    {
+        return TRUE;
+    }
+
+    return FALSE;
+}
+/*******************************************************************************
+     :  ϱعԤʧܸ澯
+ :  taskRcd     ṹ
+            result      ʧܽ
+ :  
+ ֵ  :  
+     :  
+*******************************************************************************/
+void sendReconFailAlarm(TASK_RECORD_S *taskRcd, int32_t result)
+{
+    if (!checkNeedSendReconFailAlarm(taskRcd, result))
+    {
+        DBG_LogDebug(NO_LOGID, "Recon task(id 0x%llx type %u poolId %u diskId %u) has failed %u times, result is %u.",
+                taskRcd->taskId, taskRcd->taskType, taskRcd->poolId, taskRcd->diskId, taskRcd->reserve[0], result);
+        return;
+    }
+
+    DBG_LogWarning(PMGR_LOG_ID3266, "Recon task(id 0x%llx type %u poolId %u diskId %u) has failed %u times and need send alarm, result is %u.",
+            taskRcd->taskId, taskRcd->taskType, taskRcd->poolId, taskRcd->diskId, taskRcd->reserve[0], result);
+    
+    sendReconAlarm(taskRcd->poolId, taskRcd->diskId, taskRcd->taskType, ALM_ALARM_TYPE_FAULT);
+
+    return;
+}
+
+/*******************************************************************************
+     :  ϱعԤʧܸ澯ָ
+ :  taskRcd     ṹ
+ :  
+ ֵ  :  
+     :  عɹԤɹҪϱ澯ָ
+*******************************************************************************/
+void resumeReconFailAlarm(TASK_RECORD_S *taskRcd)
+{
+    if (PRE_COPY != taskRcd->taskType && 
+        DISK_RECON != taskRcd->taskType && 
+        RECOVER_RECON != taskRcd->taskType)
+    {
+        return;
+    }
+
+    sendReconAlarm(taskRcd->poolId, taskRcd->diskId, PRE_COPY, ALM_ALARM_TYPE_RESUME);
+    sendReconAlarm(taskRcd->poolId, taskRcd->diskId, DISK_RECON, ALM_ALARM_TYPE_RESUME);
+    return;
+}
+
+
+
+
