--- ./source/private_module/lun_remote_mirror/deliver/rm_dlv_receive.c	2018-04-10 14:10:38.000000000 +0000
+++ ./source/private_module/lun_remote_mirror/deliver/rm_dlv_receive.c.hotpatch	2021-03-10 03:04:06.000000000 +0000
@@ -1334,11 +1334,10 @@
 * : 
 *   ֵ:  1)RETURN_OK: ִгɹ
 *          2): ִʧ
-* ע: 
 **********************************************************************/
+int32_t syncCgUsrMsgHandleRm(void *rmMsg);
 int32_t processPairUsrMsgRm(void *rmMsg)
 {
-    /* ֲ */
     int32_t result = RETURN_ERROR;
     int32_t innerRst = RETURN_ERROR;
     uint32_t pairOperCode = INVALID_VALUE32;
@@ -1347,21 +1346,22 @@
     recvRmMsg = (RM_MSG_HEAD_S*)rmMsg;
     pairOperCode = recvRmMsg->buffer[RM_MPO_USR_PAIR_CMD];
     DBG_LogInfo(RM_LOG_ID_0103, "Receive pair operate command.(command code %u).",pairOperCode);
-
-    /*ԶϢɿŲ*/
     if ((RM_PME_USR_PAIR_CMD_BUTT <= pairOperCode)||(0 == pairOperCode))
     {
         DBG_LogError(RM_LOG_ID_0E89, "Receive invalid pair operate command.(%u).",pairOperCode);
         return RETURN_ERROR;
     }
-    /*ԶϢɿŲ*/
-
-    /*ִУִн*/
     SYS_BUG_EXP(NULL != g_pairUsrMsgIntf[pairOperCode].pairUsrMsgIntf ,SYS_BUG_NORM, MODULE_FUNC_END, "Contex is NULL.");
-    if (NULL == g_pairUsrMsgIntf[pairOperCode].pairUsrMsgIntf)
-    {
-        DBG_LogError(RM_LOG_ID_0E89, "The exec func is null, opcode.(%u).",pairOperCode);
-        return RETURN_ERROR;
+    if (NULL == g_pairUsrMsgIntf[pairOperCode].pairUsrMsgIntf){
+        if (pairOperCode == RM_PME_USR_PAIR_CMD_UPDATE_CG) {
+            result = syncCgUsrMsgHandleRm(recvRmMsg);
+            sysRstToRmRst((OSP_U32)result,(OSP_U32 *) &innerRst);
+            recvRmMsg->uiReceiveRst = (uint32_t)innerRst;
+            return result;
+        } else {
+            DBG_LogError(RM_LOG_ID_0E89, "The exec func is null, opcode.(%u).",pairOperCode);
+            return RETURN_ERROR;
+        }
     }
     result = g_pairUsrMsgIntf[pairOperCode].pairUsrMsgIntf(recvRmMsg);
     if (unlikely(RETURN_OK != result))
@@ -4191,5 +4191,75 @@
 }
 EXPORT_SYMBOL(printWaitRspList);
 
+int32_t updateCgSecIntfRm(RM_INTF_PARAM_S *param);
+#define RM_IBC_INTF_MSG_UPDATE_CG (38)
+/*********************************************************************
+*     : CGͬûϢ
+* : 1)rmMsg   :  Ϣ
+* : 
+*   ֵ: 1)RETURN_OK : ִгɹ
+*           2)RETURN_ERROR : ִʧ
+ 
+* ע:
+**********************************************************************/
+int32_t syncCgUsrMsgHandleRm(void *rmMsg)
+{
+    int32_t ret;
+    uint64_t cgId;
+   
+    RM_MSG_HEAD_S *recvRmMsg = NULL;
+    RM_INTF_PARAM_S *param = NULL;
+
+    recvRmMsg = (RM_MSG_HEAD_S *)rmMsg;
+    cgId = RM_GET_LONG_ID(recvRmMsg->buffer[RM_MPO_USR_CG_ID_HIGH],   /* СID, λ */
+                                   recvRmMsg->buffer[RM_MPO_USR_CG_ID_LOW]);
+
+    param = getIntfParamStruRm();
+    if (NULL == param)
+    {
+    
+        DBG_LogError(RM_LOG_ID_0143,  "Receive remote command to RM CG , (cg id %llx).",cgId);
+        return RETURN_RM_SYS_BUSY;
+    }
+
+    
+    ret = getCgParamFromDlvMsgRm(param, recvRmMsg, OM_OPCODE_SYNCHRONIZE_CONSISTENCY_GROUP);
+    if (unlikely(RETURN_OK != ret))
+    {
+        putIntfParamStruRm(param);
+        DBG_LogError(RM_LOG_ID_0144, "Get param from dlv msg failed.");
+        return ret;
+    }
+    
+    ret = updateCgSecIntfRm(param);
+    if (RETURN_RM_MNG_NEED_EXEC_IN_OTHER_CTRL == ret)
+    {
+        ret = sendParamToMstCtrlRm(param, RM_IBC_INTF_MSG_UPDATE_CG);
+        if (RETURN_OK != ret)
+        {
+             DBG_LogError(RM_LOG_ID_0145,  "Send remote update cg command to master controller"
+                " failed, (cg id %llx).", cgId);
+        }
+        putIntfParamStruRm(param);
+        return ret;
+    }
+    
+    else if (RETURN_OK != ret)
+    {
+        DBG_LogError(RM_LOG_ID_050B, "Update cg(%llx) failed.",
+            param->cgId);
+  
+        putIntfParamStruRm(param);
+        return ret;
+    }
+
+    DBG_LogInfo(RM_LOG_ID_0147,  "Start to execute split cg role on local controller"
+        ", (cg id %llx).", cgId);
+    putIntfParamStruRm(param);
+    return ret;
+  
+
+}
+
 
 
--- ./source/private_module/lun_remote_mirror/interface/V3/rm_intf_msg_cg_ext.c	2018-03-10 06:52:19.000000000 +0000
+++ ./source/private_module/lun_remote_mirror/interface/V3/rm_intf_msg_cg_ext.c.hotpatch	2021-03-10 03:04:06.000000000 +0000
@@ -2422,7 +2422,12 @@
 
     cgId = param->cgId;
     localCgId = param->localCgId;
-    
+    if (! isThisMasterController())
+    {
+        DBG_LogError(RM_LOG_ID_04F2, "Spliting cg(id: %llx) need to execute on master controller.",
+            cgId);  
+        return RETURN_RM_MNG_NEED_EXEC_IN_OTHER_CTRL;
+    }
     ret = receiveCgUsrAffairRm(localCgId);
     if (RETURN_OK != ret)
     {
@@ -2465,7 +2470,7 @@
         return ret;
     }
     ret = checkUpdateCgExpandingRm(localCgId,TRUE);
-    
+
     if(RETURN_OK != ret)
     {
         unlockGroupLunRm(cgId, localCgId, NULL, 0);
@@ -2483,7 +2488,6 @@
             param->cgId);
         return ret;
     }
-
     ret = tryDlvCgUsrCmdToMstNodeRm(param, RM_PME_USR_PAIR_CMD_CHECK_UPDATE_CG);
     if (RETURN_OK != ret)
     {
@@ -2491,14 +2495,12 @@
         quitRmCgAffair(localCgId);
         DBG_LogError(RM_LOG_ID_04FA, "Relation check of updating cg(id: %llx)  "
             "operation on slave node failed.", cgId);
-        /* ׳·Ͽ¼ֹpcieʱ״̬ûб޸ */
         if (RETURN_RM_COMMUNICATE_REMOTE_ERR == ret)
         {
             sendCgLinkDownEvent(cgId);
         }
         return ret;
     }
-
     /* for async+async 3DC */
     chkFuncSet = getCgUpdUsrMsg3DcChkFuncSetRm();
     ret = check3dc3ndCgUpdateRm(localCgId, chkFuncSet);
@@ -2508,7 +2510,6 @@
         quitRmCgAffair(localCgId);
         return ret;
     }
-
     ret = fillCgDbParamRm(param, localCgId);
     if (RETURN_OK != ret)
     {
@@ -2516,7 +2517,6 @@
         quitRmCgAffair(localCgId);
         return ret;
     }
-
     ret = doCgUsrCmdExecIntfRm(param);
     if (RETURN_OK != ret)
     {
@@ -2770,33 +2770,33 @@
 int32_t updateCgIntfRm(RM_INTF_PARAM_S *param)
 {
     int32_t ret;
-   
+    uint32_t arrayId = INVALID_VALUE32;   
     ret = checkLicenseByOpCodeRm(param->opCode, INVALID_LUN_ID);
-    if (RETURN_OK != ret)
-    {
-        OSP_TRACE(PID_RM, OSP_DBL_MAJOR, 
-            "RM_ERR: Check lisense failed when updating cg.");
+    if (RETURN_OK != ret) {
+        OSP_TRACE(PID_RM, OSP_DBL_MAJOR,"RM_ERR: Check lisense failed when updating cg.");
         DBG_LogError(RM_LOG_ID_0509, "Check license failed when updating cg.");
         return ret;
     }
-
     ret = checkExtCgParamRm(param);
-    if (RETURN_OK != ret)
-    {
-        DBG_LogError(RM_LOG_ID_050A, "Check param failed when updating cg(%llx).",
-            param->cgId);
+    getArrayIdByCgIdRm(&arrayId, param->cgId);
+    if (RETURN_RM_CAN_NOT_EXECUTE_AT_SLV_NODE == ret) {
+        if (param->isCombCli) {
+            return RETURN_ERROR;}
+        ret = tryDlvCgUsrCmdToMstNodeRm(param, RM_PME_USR_PAIR_CMD_UPDATE_CG);
+        if (RETURN_OK != ret) {
+            DBG_LogError(RM_LOG_ID_0506, "Deliver sync cg(%llx) role cmd to master node(%llx) failed.", param->cgId, param->rmtArrayWwn);
+        }
+        return ret;
+    }
+    if (RETURN_OK != ret) {
+        DBG_LogError(RM_LOG_ID_050A, "Check param failed when updating cg(%llx).",param->cgId);
         return ret;
     }
-
     ret = updateCgSecIntfRm(param);
-    if (RETURN_OK != ret)
-    {
-        DBG_LogError(RM_LOG_ID_050B, "Update cg(%llx) failed.",
-            param->cgId);               
+    if (RETURN_OK != ret) {
+        DBG_LogError(RM_LOG_ID_050B, "Update cg(%llx) failed.",param->cgId); 
     }
-        
     return ret;
-        
 }
 
 /**********************************************************************
--- ./source/private_module/lun_remote_mirror/interface/V3/rm_intf_msg_check_value.c	2018-03-22 07:59:40.000000000 +0000
+++ ./source/private_module/lun_remote_mirror/interface/V3/rm_intf_msg_check_value.c.hotpatch	2021-03-09 10:09:01.000000000 +0000
@@ -2331,7 +2331,11 @@
             "cg id(%llx) health state(%u).", param->cgId, dbCfg.cgHealth);
         return RETURN_RM_CG_INVALID_NOT_OPERATION;
     }
-
+    /*ж·״̬·ϿʱڴӶ˲ᱨӶ˲Ĵ*/
+    ret = checkLinkForExtCgOp(param, &isEplLinkUp);
+    if (RETURN_OK != ret) {
+        return ret;
+    }
     /* Ӷ˲ܲҪת */
     if (INVALID_VALUE32 != dbCfg.pArrayId)
     {
@@ -2348,11 +2352,7 @@
         return ret;
     }
 
-    ret = checkLinkForExtCgOp(param, &isEplLinkUp);
-    if (RETURN_OK != ret)
-    {
-        return ret;
-    }
+
     
     /* ·OKʱԶLicense */
     if (isEplLinkUp)
--- ./source/private_module/lun_remote_mirror/interface/V3/rm_intf_msg_rss.c	2018-04-10 14:10:38.000000000 +0000
+++ ./source/private_module/lun_remote_mirror/interface/V3/rm_intf_msg_rss.c.hotpatch	2021-02-19 02:53:05.000000000 +0000
@@ -6189,5 +6189,34 @@
     return ret;
 }
 
+int32_t updateCgSecIntfRm(RM_INTF_PARAM_S *param);
+/**********************************************************************
+*     : cgͬתϢ
+* : ibcMsg: IBCϢ
+* : 
+*   ֵ: Ϣ
+* ע: 
+**********************************************************************/
+void doUpdateCgIbcReq(RSS_IBC_MSG_HEAD_S *pIbcMsg)
+{
+    RM_INTF_PARAM_S *pIntfParam = NULL;
+    RM_INTF_PARAM_S *paramInMsg = NULL;
 
+    pIntfParam = getIntfParamStruRm();
+    if (NULL == pIntfParam)
+    {
+        DBG_LogError(RM_LOG_ID_0CCE, "Alloc RM_INTF_PARAM_S structure failed.");
+        pIbcMsg->ulIBCResult = RETURN_NO_MEM;
+        return;
+    }
+
+    paramInMsg =  (RM_INTF_PARAM_S *)(void *)pIbcMsg->acData;
+/*for no stop upgrade*/
+    copyRmtIntfParamRm(pIntfParam, paramInMsg);
+/*for no stop upgrade*/
+    pIbcMsg->ulIBCResult = (OSP_U32)updateCgSecIntfRm(pIntfParam);
+
+    putIntfParamStruRm(pIntfParam);
+    return;
+}
 
--- ./source/private_module/lun_remote_mirror/main/V3/rm_base.c	2018-04-10 14:10:38.000000000 +0000
+++ ./source/private_module/lun_remote_mirror/main/V3/rm_base.c.hotpatch	2021-03-10 03:04:06.000000000 +0000
@@ -1798,36 +1798,36 @@
 {
     return g_pRmGDB;
 }
-
+#define RM_IBC_INTF_MSG_UPDATE_CG (38)
 /**********************************************************************
 *     : ͬIBCϢӿ
 * :     1)ibcMsg: IBCϢ
 * : 
 * ֵ      : 1)RETURN_OK:ִгɹ
 *               2)RETURN_ERROR:ִʧܣطͶ
-* ע:
-**********************************************************************/
+*********************************************************************/
+void doUpdateCgIbcReq(RSS_IBC_MSG_HEAD_S *pIbcMsg);
 uint32_t syncIbcMsgHandleRm(RSS_IBC_MSG_HEAD_S *ibcMsg)
 {
     uint32_t tableLen;
     RM_IBCREQ_OPS_S *doReqOps = NULL;
-  
+
 
     tableLen = sizeof(g_rmSyncIbcHandleReq)/sizeof(RM_IBCREQ_OPS_S);
     doReqOps = getRmIbcOps(g_rmSyncIbcHandleReq, tableLen, ibcMsg->ulIBCFunctionId);
-    if (NULL == doReqOps)
-    {
-        DBG_LogError(RM_LOG_ID_0001, "Invalid IbcFunctionid %u.", ibcMsg->ulIBCFunctionId);
+    if (NULL == doReqOps) {
+        if (RM_IBC_INTF_MSG_UPDATE_CG == ibcMsg->ulIBCFunctionId) {
+            doUpdateCgIbcReq(ibcMsg);
+        } else {
+            DBG_LogError(RM_LOG_ID_0001, "Invalid IbcFunctionid %u.", ibcMsg->ulIBCFunctionId);
             ibcMsg->ulIBCResult = (uint32_t)RETURN_UNKNOWN_MSG_BETWEEN_BOARD;
+        }
     }
     else
     {
-        /*modify by wangxiuwu ־ begin*/
-        DBG_LogDebug(RM_LOG_ID_0E73, "Rm begin to handle sysnc ibc msg,(funcId:%u %s).", 
-            ibcMsg->ulIBCFunctionId, doReqOps->name);
+        DBG_LogDebug(RM_LOG_ID_0E73, "Rm begin to handle sysnc ibc msg,(funcId:%u %s).", ibcMsg->ulIBCFunctionId, doReqOps->name);
         doReqOps->execute(ibcMsg);
     }
-
     return (uint32_t)RETURN_OK;
 }
 
