--- ./source/private_module/pmgr/pmgr_debug.c	2018-04-20 08:53:49.000000000 +0000
+++ ./source/private_module/pmgr/pmgr_debug.c.hotpatch	2022-11-30 09:40:51.000000000 +0000
@@ -3096,7 +3096,7 @@
 
     return;
 }
-
+void pmgrDiagRecoverReconStatus(int32_t argc, char *argv[]);
 /**************************************************************************
     :  diagnose²鿴ת־
 :  argc    (δʹ)
@@ -3121,7 +3121,7 @@
 
     return;
 }
-
+void pmgrDiagDeletePrecopyTask(int32_t argc, char *argv[]);
 /**************************************************************************
     :  diagnose²鿴SecureVideoϢ
 :  
@@ -3134,14 +3134,18 @@
     int32_t   result;
     DBG_OPT_S opt;
     poolid_t  poolId = INVALID_POOL_ID;
-    
-    if (argc != 3)
-    {
+    if (argc == 8 && strcmp(argv[1], "deleteprecopytask") == 0) {
+        pmgrDiagDeletePrecopyTask(argc - 1, &argv[1]);
+        return;
+    }
+    if (argc == 6 && strcmp(argv[1], "recoverreconstatus") == 0) {
+        pmgrDiagRecoverReconStatus(argc - 1, &argv[1]);
+        return;
+    }
+    if (argc != 3) {
         DBG_Print("input invalid cmd :  parameter input error \n");
         return;
     }
-
-    /* pmgr showdisk -p poolid  */
     while ((result = DBG_GetOpt(argc, &argv[0], "p:",  &opt)) != -1)
     {
         if ('p' == result)
@@ -3154,15 +3158,11 @@
             return;
         }
     }
-
-    if (g_MaxDiskPoolNum <= poolId)
-    {
+    if (g_MaxDiskPoolNum <= poolId) {
         DBG_Print("input poolId(%d) is not in range [0, %d) \n", poolId, g_MaxDiskPoolNum);
         return;
     }
-
     printPoolVideoInfo(poolId);
-
     return;
 }
 
@@ -4617,3 +4617,139 @@
     return;
 }
 
+int32_t pmgrCheckInputPoolAndDisk(poolid_t poolId, diskid_t diskId)
+{
+    
+    PMGR_OBJ_S *poolObj = NULL;
+    if (poolId >= g_MaxDiskPoolNum) {
+        DBG_Print("Input invalid pool %u.\n", poolId);
+        return RETURN_ERROR;
+    }
+    if (INPUT_DISK_INVALID(diskId)) {
+        DBG_Print("Input invalid diskId %u.\n", diskId);
+        return RETURN_ERROR;
+    }
+    poolObj = getPoolObj(poolId);
+    spin_lock(&poolObj->poolObjLock);
+    if (poolObj->diskPoolCfgPara.diskPoolId != poolId) {
+        spin_unlock(&poolObj->poolObjLock);
+        DBG_Print("The disk pool %u is not exist.\n", poolId);
+        return RETURN_ERROR;
+    }
+    if (!poolObj->isPoolWorkNode) {
+        spin_unlock(&poolObj->poolObjLock);
+        DBG_Print("This is not pool %u worknode.\n", poolId);
+        return RETURN_ERROR;
+    }
+    spin_unlock(&poolObj->poolObjLock);
+    return RETURN_OK;
+}
+
+int32_t pmgrDiagDelTaskCheckArg(poolid_t poolId, diskid_t diskId)
+{
+    PMGR_DISK_INFO_S *diskInfo = NULL;
+    if (pmgrCheckInputPoolAndDisk(poolId, diskId) != RETURN_OK) {
+        return RETURN_ERROR;
+    }
+    diskInfo = getLocalDiskInfo(diskId);
+    spin_lock(&diskInfo->diskLock);
+    if (diskInfo->diskPoolId == poolId) {
+        spin_unlock(&diskInfo->diskLock);
+        DBG_PrintBuf("This disk %u is pool %u member disk, can not delete.\n", diskId, poolId);
+        return RETURN_ERROR;
+    }
+    spin_unlock(&diskInfo->diskLock);
+    return RETURN_OK;
+}
+
+void pmgrDiagDeletePrecopyTaskImpl(poolid_t poolId, diskid_t diskId, uint64_t taskId);
+void pmgrDiagDeletePrecopyTask(int32_t argc, char *argv[])
+{
+    DBG_OPT_S opt;
+    poolid_t poolId = INVALID_POOL_ID;
+    diskid_t diskId = INVALID_DISK_ID;
+    uint64_t taskId = INVALID_VALUE64;
+    int32_t result;
+    while ((result = DBG_GetOpt(argc, &argv[0], "p:d:t:",  &opt)) != -1) {
+        if ('p' == result) {
+            poolId = (poolid_t)LVOS_StrToU64(opt.szOptArg);
+        } else if ('d' == result){
+            diskId = (diskid_t)LVOS_StrToU64(opt.szOptArg);
+        } else if ('t' == result) {
+            taskId = LVOS_StrToU64(opt.szOptArg);
+        } else {
+            DBG_ShowUsageAndErrMsg("%s", opt.szErrMsg);
+            return;
+        }
+    }
+    if (pmgrDiagDelTaskCheckArg(poolId, diskId) != RETURN_OK) {
+        return;
+    }
+    pmgrDiagDeletePrecopyTaskImpl(poolId, diskId, taskId);
+    DBG_Print("\n");
+}
+
+int32_t pmgrDiagCheckRecoverDiskStatusArg(poolid_t poolId, diskid_t diskId)
+{
+    PMGR_DISK_INFO_S *diskInfo = NULL;
+    if (pmgrCheckInputPoolAndDisk(poolId, diskId) != RETURN_OK) {
+        return RETURN_ERROR;
+    }
+    diskInfo = getLocalDiskInfo(diskId);
+    spin_lock(&diskInfo->diskLock);
+    if (diskInfo->diskPoolId != poolId) {
+        spin_unlock(&diskInfo->diskLock);
+        DBG_PrintBuf("This disk %u is not pool %u member disk, can not recover status.\n", diskId, poolId);
+        return RETURN_ERROR;
+    }
+    if (diskInfo->diskState != DISKPOOL_MEMBER_DISK_NORMAL || !diskInfo->isReconFinish) {
+        DBG_PrintBuf("This disk(poolid %u state %u recon %u) status check failed.\n", diskInfo->diskPoolId,
+            diskInfo->diskState, diskInfo->isReconFinish);
+        spin_unlock(&diskInfo->diskLock);
+        return RETURN_ERROR;
+    }
+    spin_unlock(&diskInfo->diskLock);
+    return RETURN_OK;
+}
+
+void sendPmgrPostMsg2Peer(poolid_t poolId, uint32_t opCode, void *data,
+                          uint32_t dataLength, void *context);
+void pmgrDiagRecoverDiskReconStatus(poolid_t poolId, diskid_t diskId)
+{
+    PMGR_DISK_INFO_S syncDiskInfo = {0};
+    PMGR_DISK_INFO_S *diskInfo = NULL;
+    diskInfo = getLocalDiskInfo(diskId);
+    spin_lock(&diskInfo->diskLock);
+    diskInfo->isReconFinish = FALSE;
+    SYNC_DISK_INFO(syncDiskInfo, diskInfo);
+    spin_unlock(&diskInfo->diskLock);
+
+    if (hasOtherNodeInChassis()) {
+        sendPmgrPostMsg2Peer(poolId, PMGR_MSG_CODE_SYNC_LOCAL_DISK_STATUS, &syncDiskInfo, sizeof(PMGR_DISK_INFO_S), NULL);
+    }
+    DBG_PrintBuf("Recover disk(poolid %u diskid %u) recon status success.\n", poolId, diskId);
+}
+
+void pmgrDiagRecoverReconStatus(int32_t argc, char *argv[])
+{
+    DBG_OPT_S opt;
+    poolid_t poolId = INVALID_POOL_ID;
+    diskid_t diskId = INVALID_DISK_ID;
+    int32_t result;
+    while ((result = DBG_GetOpt(argc, &argv[0], "p:d:",  &opt)) != -1) {
+        if ('p' == result) {
+            poolId = (poolid_t)LVOS_StrToU64(opt.szOptArg);
+        } else if ('d' == result){
+            diskId = (diskid_t)LVOS_StrToU64(opt.szOptArg);
+        } else {
+            DBG_ShowUsageAndErrMsg("%s", opt.szErrMsg);
+            return;
+        }
+    }
+
+    if (pmgrDiagCheckRecoverDiskStatusArg(poolId, diskId) != RETURN_OK) {
+        return;
+    }
+    pmgrDiagRecoverDiskReconStatus(poolId, diskId);
+    DBG_Print("\n");
+}
--- ./source/private_module/pmgr/pmgr_event_handle.c	2018-03-23 03:46:56.000000000 +0000
+++ ./source/private_module/pmgr/pmgr_event_handle.c.hotpatch	2022-11-30 09:40:51.000000000 +0000
@@ -433,7 +433,7 @@
     
     return ret;
 }
-
+bool CheckDiskPrecopyAndReconComplete(diskid_t diskId);
 /**************************************************************************
     :  ظϱ¼
 :  task    taskеtaskṹ
@@ -445,21 +445,15 @@
 {
     uint64_t taskId = 0;
     PMGR_EH_TASK *ehTask = NULL;
-    
     ehTask = (PMGR_EH_TASK *)task; 
-
-    if (PRE_COPY == ehTask->taskType)
-    {
+    if (PRE_COPY == ehTask->taskType) {
         /* diskӦԤID */
         taskId = GEN_RECON_TASK_ID(PRE_COPY, ehTask->diskId);
     }
-
-    if (PARTY_RECON == ehTask->taskType)
-    {
+    if (PARTY_RECON == ehTask->taskType) {
         /* disk+ckӦľֲعID */
         taskId = GEN_PARTY_RECON_TASK_ID(PARTY_RECON, ehTask->diskId, ehTask->ckId);
     }
-
     /* taskֱtask */
     if (isTaskRcdExist(taskId))
     {
@@ -467,7 +461,13 @@
         TASK_CALL_ACTION_DONE_ASYNC_WITH_RESULT(task, RETURN_OK);
         return RETURN_OK;
     }
-
+    if (ehTask->eventType == DISK_FAILING_EVENT && ehTask->taskType == PRE_COPY) {
+        if (CheckDiskPrecopyAndReconComplete(ehTask->diskId)) {
+            SET_GOTO_TASK_OVER_FLAG(task, TRUE);
+            TASK_CALL_ACTION_DONE_ASYNC_WITH_RESULT(task, RETURN_OK);
+            return RETURN_OK;
+        }
+    }
     TASK_CALL_ACTION_DONE_ASYNC(task);
     return RETURN_OK;
 }
@@ -3328,5 +3328,16 @@
     return;    
 }
 
-
-
+bool CheckDiskPrecopyAndReconComplete(diskid_t diskId)
+{
+    PMGR_DISK_INFO_S *diskInfo = getLocalDiskInfo(diskId);
+    spin_lock(&diskInfo->diskLock);
+    if (diskInfo->isReconFinish && diskInfo->diskState == DISKPOOL_MEMBER_DISK_HALFLIFE) {
+        spin_unlock(&diskInfo->diskLock);
+        DBG_LogInfo(DBG_LOGID_NEW, "The pool %u disk %u %u is halflife and recon complete, need not handle task.",
+            diskInfo->diskPoolId, diskInfo->diskId, diskId);
+        return B_TRUE;
+    }
+    spin_unlock(&diskInfo->diskLock);
+    return B_FALSE;
+}
--- ./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	2022-11-30 09:40:51.000000000 +0000
@@ -5682,3 +5682,37 @@
     return;
 }
 
+void pmgrDiagDeletePrecopyTaskImpl(poolid_t poolId, diskid_t diskId, uint64_t taskId)
+{
+    struct list_head *pos = NULL;
+    struct list_head *next = NULL;
+    TASK_RECORD_S *taskRcd = NULL;
+    bool isFind = FALSE;
+    
+    spin_lock(&g_taskRcdListLockArray[TASK_LIST_PRECOPY]);
+    list_for_each_safe(pos, next, &g_taskRcdListArray[TASK_LIST_PRECOPY])
+    {
+        taskRcd = list_entry(pos, TASK_RECORD_S, list);
+        if (poolId != taskRcd->poolId || diskId != taskRcd->diskId || taskId != taskRcd->taskId) {
+            continue;
+        }
+        isFind = TRUE;
+        if (taskRcd->taskState != PMGR_TASK_STOP) {
+            DBG_PrintBuf("The task state %u is not stop.\n", taskRcd->taskState);
+            break;
+        }
+        /* ɾ */
+        if (hasOtherNodeInChassis()) {
+            sendPmgrPostMsg2Peer(taskRcd->poolId, MSG_PMGR_CODE_DEL_TASK_NODE, taskRcd, sizeof(TASK_RECORD_S), NULL);
+        }
+        DBG_PrintBuf("Delete a task record(task id 0x%llx, poolid %u disk %u, task name %s) success.", taskRcd->taskId,
+            taskRcd->poolId, taskRcd->diskId, getTaskName(taskRcd->taskType));
+        /* ɾ */
+        list_del(&taskRcd->list);
+        FREE_STRUCTURE(taskRcd, g_taskRcdPoolId);
+    }
+    spin_unlock(&g_taskRcdListLockArray[TASK_LIST_PRECOPY]);
+    if (!isFind) {
+        DBG_PrintBuf("Can not find task(task id 0x%llx, poolid %u disk %u).", taskId, poolId, diskId);
+    }
+}
