osaf/libs/agents/saf/cpa/cpa_proc.c       |   52 ++++
 osaf/libs/common/cpsv/cpsv_edu.c          |   43 ++++
 osaf/libs/common/cpsv/include/cpd_cb.h    |    3 +
 osaf/libs/common/cpsv/include/cpd_imm.h   |    1 +
 osaf/libs/common/cpsv/include/cpd_proc.h  |    7 +
 osaf/libs/common/cpsv/include/cpd_tmr.h   |    3 +-
 osaf/libs/common/cpsv/include/cpnd_cb.h   |    1 +
 osaf/libs/common/cpsv/include/cpnd_init.h |    2 +
 osaf/libs/common/cpsv/include/cpsv_evt.h  |   20 +
 osaf/services/saf/cpsv/cpd/Makefile.am    |    3 +-
 osaf/services/saf/cpsv/cpd/cpd_evt.c      |  229 +++++++++++++++++++++
 osaf/services/saf/cpsv/cpd/cpd_imm.c      |  112 ++++++++++
 osaf/services/saf/cpsv/cpd/cpd_init.c     |   20 +-
 osaf/services/saf/cpsv/cpd/cpd_proc.c     |  309 +++++++++++++++++++++++++++++
 osaf/services/saf/cpsv/cpd/cpd_tmr.c      |    7 +
 osaf/services/saf/cpsv/cpnd/cpnd_db.c     |   16 +
 osaf/services/saf/cpsv/cpnd/cpnd_evt.c    |   22 ++
 osaf/services/saf/cpsv/cpnd/cpnd_init.c   |   23 ++-
 osaf/services/saf/cpsv/cpnd/cpnd_mds.c    |   13 +
 osaf/services/saf/cpsv/cpnd/cpnd_proc.c   |  314 +++++++++++++++++++++++++++++-
 20 files changed, 1189 insertions(+), 11 deletions(-)


Background:
----------
This enhancement supports to preserve checkpoint replicas in case both SCs down 
(headless state)
and recover replicas in case one of SCs up again. If both SCs goes down, 
checkpoint replicas
on surviving nodes still remain. When a SC is available again, surviving 
replicas are
automatically registered to the SC checkpoint database. Content in surviving 
replicas are
intacted and synchronized to new replicas.

When no SC is available, client API calls changing checkpoint configuration 
which requires
SC communication, are rejected. Client API calls reading and writing existing 
checkpoint
replicas still work.

Limitation:
The CKPT service does not support recovering checkpoints in following cases:
 - The checkpoint which is unlinked before headless.
 - The non-collocated checkpoint has active replica locating on SC.
 - The non-collocated checkpoint has active replica locating on a PL and this 
PL restarts
   during headless state. In this cases, the checkpoint replica is destroyed.
The fault code SA_AIS_ERR_BAD_HANDLE is returned when the client accesses the 
checkpoint in
these cases. The client must re-open the checkpoint.

While in headless state, accessing checkpoint replicas does not work if the 
node which
hosts the active replica goes down. It will back working when a SC available 
again.

Solution:
---------
The solution for this enhancement includes 2 parts:

1. To destroy un-recoverable checkpoint described above when both SCs are down:
When both SCs are down, the CPND deletes un-recoverable checkpoint nodes and 
replicas on PLs. Then it
requests CPA to destroy corresponding checkpoint node by using new message 
CPA_EVT_ND2A_CKPT_DESTROY

2. To update CPD with checkpoint information
When an active SC is up after headless, CPND will update CPD with checkpoint 
information by using
new message CPD_EVT_ND2D_CKPT_INFO_UPDATE instead of using 
CPD_EVT_ND2D_CKPT_CREATE. This is
because the CPND will create new ckpt_id for the checkpoint which might be 
different with the
current ckpt id if the CPD_EVT_ND2D_CKPT_CREATE is used. The CPD collects 
checkpoint information
within 6s. During this updating time, following requests is rejected with fault 
code SA_AIS_ERR_TRY_AGAIN:
- CPD_EVT_ND2D_CKPT_CREATE
- CPD_EVT_ND2D_CKPT_UNLINK
- CPD_EVT_ND2D_ACTIVE_SET
- CPD_EVT_ND2D_CKPT_RDSET

diff --git a/osaf/libs/agents/saf/cpa/cpa_proc.c 
b/osaf/libs/agents/saf/cpa/cpa_proc.c
--- a/osaf/libs/agents/saf/cpa/cpa_proc.c
+++ b/osaf/libs/agents/saf/cpa/cpa_proc.c
@@ -701,6 +701,53 @@ static void cpa_proc_active_ckpt_info_bc
 }
 
 /****************************************************************************
+  Name          : cpa_proc_ckpt_destroy 
+  Description   : This function clean up all information in db relating 
+                  to the destroyed ckpt
+  Arguments     : cb - CPA CB.
+                  evt - CPA_EVT.
+  Return Values : None
+  Notes         : None
+******************************************************************************/
+static void cpa_proc_ckpt_destroy(CPA_CB *cb, CPA_EVT *evt)
+{
+       CPA_GLOBAL_CKPT_NODE *gc_node = NULL;
+       CPA_LOCAL_CKPT_NODE *lc_node = NULL;
+       CPA_SECT_ITER_NODE *sect_iter_node = NULL;
+       bool add_flag = false;
+
+       m_NCS_LOCK(&cb->cb_lock, NCS_LOCK_WRITE);
+
+       /* Destroy section iteration node */
+       cpa_sect_iter_node_getnext(&cb->sect_iter_tree, NULL, &sect_iter_node);
+       while (sect_iter_node != NULL) {
+               SaCkptSectionIterationHandleT prev_iter_id = 
sect_iter_node->iter_id;
+               
+               if (sect_iter_node->gbl_ckpt_hdl == 
evt->info.ckpt_destroy.ckpt_id)
+                       cpa_sect_iter_node_delete(cb, sect_iter_node);
+
+               cpa_sect_iter_node_getnext(&cb->sect_iter_tree, &prev_iter_id, 
&sect_iter_node);
+       }
+
+       /* Destroy local node connection to the destroy ckpt id */
+       cpa_lcl_ckpt_node_getnext(cb, NULL, &lc_node);
+       while (lc_node != NULL) {
+               SaCkptCheckpointHandleT prev_lcl_ckpt_hdl = 
lc_node->lcl_ckpt_hdl;
+
+               if (lc_node->gbl_ckpt_hdl == evt->info.ckpt_destroy.ckpt_id)
+                       cpa_lcl_ckpt_node_delete(cb, lc_node);
+
+               cpa_lcl_ckpt_node_getnext(cb, &prev_lcl_ckpt_hdl, &lc_node);
+       }
+
+       /* Destroy global node */
+       cpa_gbl_ckpt_node_find_add(&cb->gbl_ckpt_tree, 
&evt->info.ckpt_destroy.ckpt_id, &gc_node, &add_flag);
+       cpa_gbl_ckpt_node_delete(cb, gc_node);
+
+       m_NCS_UNLOCK(&cb->cb_lock, NCS_LOCK_WRITE);
+}
+
+/****************************************************************************
   Name          : cpa_proc_active_nd_down_bcast 
   Description   : This function will process the bcast from  cpd.
   Arguments     : cb - CPA CB.
@@ -762,12 +809,17 @@ uint32_t cpa_process_evt(CPA_CB *cb, CPS
        case CPA_EVT_D2A_NDRESTART:
                cpa_proc_active_nd_down_bcast(cb, &evt->info.cpa);
                break;
+
        case CPA_EVT_ND2A_CKPT_CLM_NODE_LEFT:
        case CPA_EVT_ND2A_CKPT_CLM_NODE_JOINED:
                if (cpa_proc_ckpt_clm_status_changed(cb, evt) != 
NCSCC_RC_SUCCESS)
                        rc = NCSCC_RC_FAILURE;
                break;
 
+       case CPA_EVT_ND2A_CKPT_DESTROY:
+               cpa_proc_ckpt_destroy(cb, &evt->info.cpa);
+               break;
+
        default:
                break;
        }
diff --git a/osaf/libs/common/cpsv/cpsv_edu.c b/osaf/libs/common/cpsv/cpsv_edu.c
--- a/osaf/libs/common/cpsv/cpsv_edu.c
+++ b/osaf/libs/common/cpsv/cpsv_edu.c
@@ -54,6 +54,7 @@ FUNC_DECLARATION(CPSV_ND2A_SYNC_RSP);
 FUNC_DECLARATION(CPSV_ND2A_ARRIVAL_MSG);
 FUNC_DECLARATION(CPSV_ND2D_USR_INFO);
 FUNC_DECLARATION(CPSV_ND2D_CKPT_CREATE);
+FUNC_DECLARATION(CPSV_ND2D_CKPT_INFO_UPD);
 FUNC_DECLARATION(CPSV_CKPT_SEC_INFO_UPD);
 FUNC_DECLARATION(CPSV_CKPT_ID_INFO);
 FUNC_DECLARATION(CPSV_ND2D_CKPT_UNLINK);
@@ -703,6 +704,34 @@ FUNC_DECLARATION(DS)
 
 #undef DS
 
+#define DS  CPSV_ND2D_CKPT_INFO_UPD
+FUNC_DECLARATION(DS)
+{
+       uint16_t ver_compare = 0;
+       ver_compare = 3;        /* 
CPD_MDS_PVT_SUBPART_VERSION/CPND_MDS_PVT_SUBPART_VERSION */
+       NCS_ENC_DEC_DECLARATION(DS);
+       NCS_ENC_DEC_ARRAY(DS) {
+
+               {
+               EDU_START, FUNC_NAME(CPSV_ND2D_CKPT_INFO_UPD), 0, 0, 0, 
sizeof(DS), 0, NULL}, {
+               EDU_EXEC, ncs_edp_uns64, 0, 0, 0, (long)&((DS *) 0)->ckpt_id, 
0, NULL}, {
+               EDU_EXEC, ncs_edp_sanamet, 0, 0, 0, (long)&((DS *) 
0)->ckpt_name, 0, NULL}, {
+               EDU_EXEC, FUNC_NAME(SaCkptCheckpointCreationAttributesT), 0, 0, 
0,
+                           (long)&((DS *) 0)->attributes, 0, NULL}, {
+               EDU_EXEC, ncs_edp_uns32, 0, 0, 0, (long)&((DS *) 
0)->ckpt_flags, 0, NULL}, {
+               EDU_VER_GE, NULL, 0, 0, 2, 0, 0, (EDU_EXEC_RTINE)((uint16_t 
*)(&(ver_compare)))}, {
+               EDU_EXEC, FUNC_NAME(SaVersionT), 0, 0, 0, (long)&((DS *) 
0)->client_version, 0, NULL}, {
+               EDU_EXEC, ncs_edp_ncs_bool, 0, 0, 0, (long)&((DS *) 
0)->is_active, 0, NULL}, {
+               EDU_EXEC, ncs_edp_uns32, 0, 0, 0, (long)&((DS *) 0)->num_users, 
0, NULL}, {
+               EDU_EXEC, ncs_edp_uns32, 0, 0, 0, (long)&((DS *) 
0)->num_writers, 0, NULL}, {
+               EDU_EXEC, ncs_edp_uns32, 0, 0, 0, (long)&((DS *) 
0)->num_readers, 0, NULL}, {
+               EDU_EXEC, ncs_edp_ncs_bool, 0, 0, 0, (long)&((DS *) 
0)->is_last, 0, NULL}, {
+               EDU_EXEC, ncs_edp_ncs_bool, 0, 0, 0, (long)&((DS *) 
0)->is_unlink, 0, NULL}, {
+       EDU_END, 0, 0, 0, 0, 0, 0, NULL},};
+       NCS_ENC_DEC_REM_FLOW(DS)
+}
+#undef DS
+
 #define DS CPSV_CKPT_SEC_INFO_UPD
 FUNC_DECLARATION(DS)
 {
@@ -1318,6 +1347,7 @@ TEST_FUNC_DECLARATION(DS)
                LCL_TEST_JUMP_OFFSET_CPND_EVT_D2ND_CKPT_NUM_SECTIONS,
                LCL_TEST_JUMP_OFFSET_CPND_EVT_A2ND_CKPT_LIST_UPDATE,
                LCL_TEST_JUMP_OFFSET_CPND_EVT_A2ND_ARRIVAL_CB_UNREG,
+               LCL_TEST_JUMP_OFFSET_CPND_EVT_D2ND_CKPT_INFO_UPDATE_ACK,
 
        };
 
@@ -1435,6 +1465,8 @@ TEST_FUNC_DECLARATION(DS)
                return LCL_TEST_JUMP_OFFSET_CPND_EVT_A2ND_CKPT_LIST_UPDATE;
        case CPND_EVT_A2ND_ARRIVAL_CB_UNREG:
                return LCL_TEST_JUMP_OFFSET_CPND_EVT_A2ND_ARRIVAL_CB_UNREG;
+       case CPND_EVT_D2ND_CKPT_INFO_UPDATE_ACK:
+               return LCL_TEST_JUMP_OFFSET_CPND_EVT_D2ND_CKPT_INFO_UPDATE_ACK;
        default:
                return EDU_FAIL;
        }
@@ -1540,6 +1572,7 @@ FUNC_DECLARATION(DS)
                            (long)&((DS *) 0)->info.ckpt_sections, 0, NULL}, {
                EDU_EXEC, FUNC_NAME(CPSV_A2ND_CKPT_LIST_UPDATE), 0, 0, 
EDU_EXIT, (long)&((DS *) 0)->info.ckptListUpdate, 0, NULL},{
                        EDU_EXEC, FUNC_NAME(CPSV_A2ND_ARRIVAL_UNREG), 0, 0, 
EDU_EXIT, (long)&((DS *) 0)->info.arr_ntfy, 0, NULL},{
+               EDU_EXEC, FUNC_NAME(CPSV_SAERR_INFO), 0, 0, EDU_EXIT, 
(long)&((DS *) 0)->info.ckpt_info_update_ack, 0, NULL}, {
        EDU_END, 0, 0, 0, 0, 0, 0, NULL},};
        NCS_ENC_DEC_REM_FLOW(DS)
 }
@@ -1563,6 +1596,7 @@ TEST_FUNC_DECLARATION(DS)
                LCL_TEST_JUMP_OFFSET_CPD_EVT_ND2D_CKPT_MEM_USED,
                LCL_TEST_JUMP_OFFSET_CPD_EVT_ND2D_CKPT_DESTROY_BYNAME,
                LCL_TEST_JUMP_OFFSET_CPD_EVT_ND2D_CKPT_CREATED_SECTIONS,
+               LCL_TEST_JUMP_OFFSET_CPD_EVT_ND2D_CKPT_INFO_UPDATE,
 
        };
 
@@ -1598,6 +1632,8 @@ TEST_FUNC_DECLARATION(DS)
                return LCL_TEST_JUMP_OFFSET_CPD_EVT_ND2D_CKPT_CREATED_SECTIONS;
        case CPD_EVT_ND2D_CKPT_DESTROY_BYNAME:
                return LCL_TEST_JUMP_OFFSET_CPD_EVT_ND2D_CKPT_DESTROY_BYNAME;
+       case CPD_EVT_ND2D_CKPT_INFO_UPDATE:
+               return LCL_TEST_JUMP_OFFSET_CPD_EVT_ND2D_CKPT_INFO_UPDATE;
        default:
                return EDU_FAIL;
        }
@@ -1636,6 +1672,8 @@ FUNC_DECLARATION(DS)
                            (long)&((DS *) 0)->info.ckpt_destroy_byname, 0, 
NULL}, {
                EDU_EXEC, FUNC_NAME(CPSV_CKPT_NUM_SECTIONS), 0, 0, EDU_EXIT,
                            (long)&((DS *) 0)->info.ckpt_created_sections, 0, 
NULL}, {
+               EDU_EXEC, FUNC_NAME(CPSV_ND2D_CKPT_INFO_UPD), 0, 0, EDU_EXIT, 
(long)&((DS *) 0)->info.ckpt_info,
+                           0, NULL}, {
        EDU_END, 0, 0, 0, 0, 0, 0, NULL},};
        NCS_ENC_DEC_REM_FLOW(DS)
 }
@@ -1668,6 +1706,7 @@ TEST_FUNC_DECLARATION(DS)
                LC_TEST_JUMP_OFFSET_CPA_EVT_D2A_ACT_CKPT_INFO_BCAST_SEND,
                LC_TEST_JUMP_OFFSET_CPA_EVT_ND2A_CKPT_ARRIVAL_NTFY,
                LC_TEST_JUMP_OFFSET_CPA_EVT_ND2A_ACT_CKPT_INFO_BCAST_SEND,
+               LC_TEST_JUMP_OFFSET_CPA_EVT_ND2A_CKPT_DESTROY,
                /* add new event hear */
                LC_TEST_JUMP_OFFSET_END
        };
@@ -1725,6 +1764,8 @@ TEST_FUNC_DECLARATION(DS)
                return LC_TEST_JUMP_OFFSET_END;
        case CPA_EVT_ND2A_SEC_ITER_RSP:
                return LC_TEST_JUMP_OFFSET_END;
+       case CPA_EVT_ND2A_CKPT_DESTROY:
+               return LC_TEST_JUMP_OFFSET_CPA_EVT_ND2A_CKPT_DESTROY;
        default:
                return EDU_FAIL;
        }
@@ -1768,6 +1809,8 @@ FUNC_DECLARATION(DS)
                {
                EDU_EXEC, FUNC_NAME(CPSV_CKPT_DEST_INFO), 0, 0, EDU_EXIT, 
(long)&((DS *) 0)->info.ackpt_info, 0, NULL},
                {
+               EDU_EXEC, FUNC_NAME(CPSV_CKPT_ID_INFO), 0, 0, EDU_EXIT, 
(long)&((DS *) 0)->info.ckpt_destroy, 0, NULL},
+               {
        EDU_END, 0, 0, 0, 0, 0, 0, NULL},};
        NCS_ENC_DEC_REM_FLOW(DS)
 }
diff --git a/osaf/libs/common/cpsv/include/cpd_cb.h 
b/osaf/libs/common/cpsv/include/cpd_cb.h
--- a/osaf/libs/common/cpsv/include/cpd_cb.h
+++ b/osaf/libs/common/cpsv/include/cpd_cb.h
@@ -207,6 +207,9 @@ typedef struct cpd_cb_tag {
        SaImmOiHandleT immOiHandle;     /* IMM OI Handle */
        SaSelectionObjectT imm_sel_obj; /*Selection object to wait for IMM 
events */
 
+       CPD_TMR ckpt_update_timer;
+       bool is_ckpt_updating;
+
 } CPD_CB;
 
 #define CPD_CB_NULL  ((CPD_CB *)0)
diff --git a/osaf/libs/common/cpsv/include/cpd_imm.h 
b/osaf/libs/common/cpsv/include/cpd_imm.h
--- a/osaf/libs/common/cpsv/include/cpd_imm.h
+++ b/osaf/libs/common/cpsv/include/cpd_imm.h
@@ -6,3 +6,4 @@ extern void cpd_imm_declare_implementer(
 extern SaAisErrorT create_runtime_ckpt_object(CPD_CKPT_INFO_NODE *ckpt_node, 
SaImmOiHandleT immOiHandle);
 extern SaAisErrorT create_runtime_replica_object(CPD_CKPT_REPLOC_INFO 
*ckpt_reploc_node, SaImmOiHandleT immOiHandle);
 extern void cpd_create_association_class_dn(const SaNameT *child_dn, const 
SaNameT *parent_dn, const char *rdn_tag, SaNameT *dn);
+extern SaAisErrorT cpd_clean_checkpoint_objects(CPD_CB *cb);
diff --git a/osaf/libs/common/cpsv/include/cpd_proc.h 
b/osaf/libs/common/cpsv/include/cpd_proc.h
--- a/osaf/libs/common/cpsv/include/cpd_proc.h
+++ b/osaf/libs/common/cpsv/include/cpd_proc.h
@@ -20,6 +20,7 @@
 
 /* CPD definations */
 #define CPD_CPND_DOWN_RETENTION_TIME 600       /* 100 Milli Sec */
+#define CPD_CKPT_UPDATE_TIME 600       /* 10 Milli Sec */
 #define CPD_CLM_API_TIMEOUT 10000000000LL
 /* The count of non colloc replicas created by CPSv (Policy) */
 #define CPD_NON_COLLOC_CREATED_REPLICA_CNT 1
@@ -50,6 +51,11 @@ uint32_t cpd_ckpt_db_entry_update(CPD_CB
                                        CPSV_ND2D_CKPT_CREATE *ckpt_create,
                                        CPD_CKPT_INFO_NODE **o_ckpt_node, 
CPD_CKPT_MAP_INFO **io_map_info);
 
+uint32_t cpd_ckpt_db_update_after_headless(CPD_CB *cb,
+                                       MDS_DEST *cpnd_dest,
+                                       CPSV_ND2D_CKPT_INFO_UPD *ckpt_info,
+                                       CPD_CKPT_INFO_NODE **o_ckpt_node, 
CPD_CKPT_MAP_INFO **io_map_info);
+
 uint32_t cpd_process_ckpt_delete(CPD_CB *cb,
                                       CPD_CKPT_INFO_NODE *ckpt_node,
                                       CPSV_SEND_INFO *sinfo,
@@ -102,4 +108,5 @@ uint32_t cpd_mbcsv_enc_async_update(CPD_
 uint32_t cpd_mbcsv_close(CPD_CB *cb);
 bool cpd_is_noncollocated_replica_present_on_payload(CPD_CB *cb, 
CPD_CKPT_INFO_NODE *ckpt_node);
 uint32_t cpd_ckpt_reploc_imm_object_delete(CPD_CB *cb,  CPD_CKPT_REPLOC_INFO 
*ckpt_reploc_node ,bool is_unlink_set);
+uint32_t cpd_proc_ckpt_update_post(CPD_CB *cb);
 #endif
diff --git a/osaf/libs/common/cpsv/include/cpd_tmr.h 
b/osaf/libs/common/cpsv/include/cpd_tmr.h
--- a/osaf/libs/common/cpsv/include/cpd_tmr.h
+++ b/osaf/libs/common/cpsv/include/cpd_tmr.h
@@ -22,7 +22,8 @@
 
 typedef enum cpd_tmr_type {
        CPD_TMR_TYPE_CPND_RETENTION = 1,
-       CPD_TMR_TYPE_MAX = CPD_TMR_TYPE_CPND_RETENTION,
+       CPD_TMR_TYPE_CKPT_UPDATE,
+       CPD_TMR_TYPE_MAX = CPD_TMR_TYPE_CKPT_UPDATE,
 } CPD_TMR_TYPE;
 
 typedef struct cpd_tmr {
diff --git a/osaf/libs/common/cpsv/include/cpnd_cb.h 
b/osaf/libs/common/cpsv/include/cpnd_cb.h
--- a/osaf/libs/common/cpsv/include/cpnd_cb.h
+++ b/osaf/libs/common/cpsv/include/cpnd_cb.h
@@ -277,6 +277,7 @@ typedef struct cpnd_cb_tag {
        /* Information about the CPD */
        MDS_DEST cpd_mdest_id;
        bool is_cpd_up;
+       bool is_cpd_need_update; /* This flag indicates if cpd needs updating 
after headless state */
        bool is_joined_cl;
        uint32_t num_rep;               /* Number of shared memory segments */
 
diff --git a/osaf/libs/common/cpsv/include/cpnd_init.h 
b/osaf/libs/common/cpsv/include/cpnd_init.h
--- a/osaf/libs/common/cpsv/include/cpnd_init.h
+++ b/osaf/libs/common/cpsv/include/cpnd_init.h
@@ -85,6 +85,7 @@ uint32_t cpnd_ckpt_client_del(CPND_CKPT_
 uint32_t cpnd_client_ckpt_info_add(CPND_CKPT_CLIENT_NODE *cl_node, 
CPND_CKPT_NODE *cp_node);
 uint32_t cpnd_client_ckpt_info_del(CPND_CKPT_CLIENT_NODE *cl_node, 
CPND_CKPT_NODE *cp_node);
 uint32_t cpnd_ckpt_replica_destroy(CPND_CB *cb, CPND_CKPT_NODE *cp_node, 
SaAisErrorT *error);
+void cpnd_ckpt_replica_delete(CPND_CB *cb, CPND_CKPT_NODE *ckpt_node);
 uint32_t cpnd_ckpt_replica_create(CPND_CB *cb, CPND_CKPT_NODE *cp_node);
 uint32_t cpnd_ckpt_remote_cpnd_add(CPND_CKPT_NODE *cp_node, MDS_DEST mds_info);
 uint32_t cpnd_ckpt_remote_cpnd_del(CPND_CKPT_NODE *cp_node, MDS_DEST mds_info);
@@ -153,6 +154,7 @@ void cpnd_ckpt_node_getnext(CPND_CB *cb,
 uint32_t cpnd_ckpt_node_add(CPND_CB *cb, CPND_CKPT_NODE *ckpt_node);
 uint32_t cpnd_ckpt_node_del(CPND_CB *cb, CPND_CKPT_NODE *ckpt_node);
 void cpnd_client_node_get(CPND_CB *cb, SaCkptHandleT ckpt_client_hdl, 
CPND_CKPT_CLIENT_NODE **ckpt_client_node);
+uint32_t cpnd_number_of_clients_get(CPND_CB *cb);
 void cpnd_client_node_getnext(CPND_CB *cb, SaCkptHandleT ckpt_client_hdl, 
CPND_CKPT_CLIENT_NODE **ckpt_client_node);
 uint32_t cpnd_client_node_add(CPND_CB *cb, CPND_CKPT_CLIENT_NODE *ckpt_node);
 uint32_t cpnd_client_node_del(CPND_CB *cb, CPND_CKPT_CLIENT_NODE 
*ckpt_client_node);
diff --git a/osaf/libs/common/cpsv/include/cpsv_evt.h 
b/osaf/libs/common/cpsv/include/cpsv_evt.h
--- a/osaf/libs/common/cpsv/include/cpsv_evt.h
+++ b/osaf/libs/common/cpsv/include/cpsv_evt.h
@@ -94,6 +94,7 @@ typedef enum cpa_evt_type {
        CPA_EVT_ND2A_CKPT_CLM_NODE_LEFT,
        CPA_EVT_ND2A_CKPT_CLM_NODE_JOINED,
        CPA_EVT_ND2A_ACT_CKPT_INFO_BCAST_SEND,
+       CPA_EVT_ND2A_CKPT_DESTROY,
        CPA_EVT_MAX
 } CPA_EVT_TYPE;
 
@@ -189,6 +190,7 @@ typedef enum cpnd_evt_type {
    CPND_EVT_A2ND_CKPT_REFCNTSET,        /* ref cont opener's set call */
    CPND_EVT_A2ND_CKPT_LIST_UPDATE,     /* Checkpoint ckpt list update Call */
    CPND_EVT_A2ND_ARRIVAL_CB_UNREG,     /* Checkpoint Arrival Callback 
Un-Register*/
+   CPND_EVT_D2ND_CKPT_INFO_UPDATE_ACK, /* Checkpoint information update ack */
    CPND_EVT_MAX
 
 }CPND_EVT_TYPE;
@@ -218,6 +220,7 @@ typedef enum cpd_evt_type {
        CPD_EVT_ND2D_CKPT_DESTROY_BYNAME,
        CPD_EVT_ND2D_CKPT_CREATED_SECTIONS,
        CPD_EVT_TIME_OUT,
+       CPD_EVT_ND2D_CKPT_INFO_UPDATE,   /* Checkpoint information update */
        CPD_EVT_MAX
 } CPD_EVT_TYPE;
 
@@ -663,6 +666,20 @@ typedef struct cpsv_nd2d_ckpt_name {
        SaNameT ckpt_name;
 } CPSV_CKPT_NAME_INFO;
 
+typedef struct cpsv_nd2d_ckpt_info_update {
+       SaCkptCheckpointHandleT ckpt_id;
+       SaNameT ckpt_name;
+       SaCkptCheckpointCreationAttributesT attributes;
+       SaCkptCheckpointOpenFlagsT ckpt_flags;
+       SaVersionT client_version;
+       bool is_active;
+       uint32_t num_users;
+       uint32_t num_writers;
+       uint32_t num_readers;
+       bool is_last;
+       bool is_unlink;
+} CPSV_ND2D_CKPT_INFO_UPD;
+
 /* CPA Local Events */
 typedef struct cpa_tmr_info {
        uint32_t type;
@@ -701,6 +718,7 @@ typedef struct cpa_evt {
                CPSV_SAERR_INFO readackRsp;
                CPA_TMR_INFO tmr_info;
                CPSV_CKPT_DEST_INFO ackpt_info;
+               CPSV_CKPT_ID_INFO ckpt_destroy;
        } info;
 
 } CPA_EVT;
@@ -771,6 +789,7 @@ typedef struct cpnd_evt
                CPSV_SAERR_INFO crset_ack;      /* How about get rid of this 
ACK */
                CPSV_SAERR_INFO arep_ack;
                CPSV_SAERR_INFO destroy_ack;
+               CPSV_SAERR_INFO ckpt_info_update_ack;
 
                CPSV_CKPT_ID_INFO cpnd_restart;
                CPSV_CKPT_DESTLIST_INFO cpnd_restart_done;
@@ -842,6 +861,7 @@ typedef struct cpd_evt {
                CPSV_CKPT_DEST_INFO arep_set;
                CPD_TMR_INFO tmr_info;
                CPSV_MDS_INFO mds_info;
+               CPSV_ND2D_CKPT_INFO_UPD ckpt_info;
 
        } info;
 } CPD_EVT;
diff --git a/osaf/services/saf/cpsv/cpd/Makefile.am 
b/osaf/services/saf/cpsv/cpd/Makefile.am
--- a/osaf/services/saf/cpsv/cpd/Makefile.am
+++ b/osaf/services/saf/cpsv/cpd/Makefile.am
@@ -51,4 +51,5 @@ osafckptd_LDADD = \
        $(top_builddir)/osaf/libs/saf/libSaAmf/libSaAmf.la \
        $(top_builddir)/osaf/libs/saf/libSaClm/libSaClm.la \
        $(top_builddir)/osaf/libs/saf/libSaImm/libSaImmOi.la \
-       $(top_builddir)/osaf/libs/saf/libSaImm/libSaImmOm.la
+       $(top_builddir)/osaf/libs/saf/libSaImm/libSaImmOm.la \
+       $(top_builddir)/osaf/libs/agents/infrastructure/rda/librda.la
diff --git a/osaf/services/saf/cpsv/cpd/cpd_evt.c 
b/osaf/services/saf/cpsv/cpd/cpd_evt.c
--- a/osaf/services/saf/cpsv/cpd/cpd_evt.c
+++ b/osaf/services/saf/cpsv/cpd/cpd_evt.c
@@ -43,6 +43,7 @@ static uint32_t cpd_evt_proc_timer_expir
 static uint32_t cpd_evt_proc_mds_evt(CPD_CB *cb, CPD_EVT *evt);
 
 static uint32_t cpd_evt_mds_quiesced_ack_rsp(CPD_CB *cb, CPD_EVT *evt, 
CPSV_SEND_INFO *sinfo);
+static uint32_t cpd_evt_proc_ckpt_info_upd(CPD_CB *cb, CPD_EVT *evt, 
CPSV_SEND_INFO *sinfo);
 
 #if ( CPSV_DEBUG == 1)
 static char *cpd_evt_str[] = {
@@ -133,6 +134,9 @@ void cpd_process_evt(CPSV_EVT *evt)
        case CPD_EVT_MDS_QUIESCED_ACK_RSP:
                (void)cpd_evt_mds_quiesced_ack_rsp(cb, &evt->info.cpd, 
&evt->sinfo);
                break;
+       case CPD_EVT_ND2D_CKPT_INFO_UPDATE:
+               (void)cpd_evt_proc_ckpt_info_upd(cb, &evt->info.cpd, 
&evt->sinfo);
+               break;
 
        case CPD_EVT_CB_DUMP:
                (void)cpd_evt_proc_cb_dump(cb);
@@ -175,6 +179,14 @@ static uint32_t cpd_evt_proc_ckpt_create
        bool is_first_rep = false, is_new_noncol = false;
        
        TRACE_ENTER();
+
+       /* Verify if the CKPT Info is updating after headless state */
+       if (cb->is_ckpt_updating == true) {
+               LOG_IN("cpd ckpt info is updating after headless state - 
rc=SA_AIS_ERR_TRY_AGAIN");
+               rc = SA_AIS_ERR_TRY_AGAIN;
+               goto send_rsp;
+       }
+
        cpd_ckpt_map_node_get(&cb->ckpt_map_tree, &ckpt_create->ckpt_name, 
&map_info);
        if (map_info) {
 
@@ -548,6 +560,14 @@ static uint32_t cpd_evt_proc_ckpt_unlink
        CPSV_EVT send_evt;
 
        TRACE_ENTER();
+
+       /* Verify if the CKPT Info is updating after headless state */
+       if (cb->is_ckpt_updating == true) {
+               LOG_IN("cpd ckpt info is updating after headless state 
rc=SA_AIS_ERR_TRY_AGAIN");
+               rc = SA_AIS_ERR_TRY_AGAIN;
+               goto send_rsp;
+       }
+
        rc = cpd_proc_unlink_set(cb, &ckpt_node, map_info, ckpt_name);
        if (rc != SA_AIS_OK)
                goto send_rsp;
@@ -606,6 +626,14 @@ static uint32_t cpd_evt_proc_ckpt_rdset(
        uint32_t proc_rc = NCSCC_RC_SUCCESS;
 
        TRACE_ENTER();
+
+       /* Verify if the CKPT Info is updating after headless state */
+       if (cb->is_ckpt_updating == true) {
+               LOG_IN("cpd ckpt info is updating after headless state 
rc=SA_AIS_ERR_TRY_AGAIN");
+               rc = SA_AIS_ERR_TRY_AGAIN;
+               goto send_rsp;
+       }
+
        rc = cpd_proc_retention_set(cb, evt->info.rd_set.ckpt_id, 
evt->info.rd_set.reten_time, &ckpt_node);
        if (rc != SA_AIS_OK)
                goto send_rsp;
@@ -656,6 +684,14 @@ static uint32_t cpd_evt_proc_active_set(
        uint32_t proc_rc = NCSCC_RC_SUCCESS;
 
        TRACE_ENTER();
+
+       /* Verify if the CKPT Info is updating after headless state */
+       if (cb->is_ckpt_updating == true) {
+               LOG_IN("cpd ckpt info is updating after headless state 
rc=SA_AIS_ERR_TRY_AGAIN");
+               rc = SA_AIS_ERR_TRY_AGAIN;
+               goto send_rsp;
+       }
+
        rc = cpd_proc_active_set(cb, evt->info.arep_set.ckpt_id, 
evt->info.arep_set.mds_dest, &ckpt_node);
        if (rc != SA_AIS_OK)
                goto send_rsp;
@@ -885,6 +921,15 @@ static uint32_t cpd_evt_proc_timer_expir
                        }
                }
                break;
+       case CPD_TMR_TYPE_CKPT_UPDATE:
+               if (cb->ha_state == SA_AMF_HA_ACTIVE && cb->is_ckpt_updating == 
true)
+                       cpd_proc_ckpt_update_post(cb);
+
+               cb->is_ckpt_updating = false;
+               cpd_tmr_stop(&cb->ckpt_update_timer);
+               LOG_NO("cpd_evt_proc_timer_expiry::is_ckpt_updating = %s", 
cb->is_ckpt_updating ? "true" : "false");
+               break;
+
        default:
                break;
        }
@@ -917,6 +962,8 @@ static uint32_t cpnd_down_process(CPD_CB
        cpnd_info->cpnd_ret_timer.type = CPD_TMR_TYPE_CPND_RETENTION;
        cpnd_info->cpnd_ret_timer.info.cpnd_dest = mds_info->dest;
        cpd_tmr_start(&cpnd_info->cpnd_ret_timer, CPD_CPND_DOWN_RETENTION_TIME);
+       LOG_NO("cpnd_down_process:: Start CPND_RETENTION timer id = %p, arg=%p",
+               cpnd_info->cpnd_ret_timer.tmr_id, &cpnd_info->cpnd_ret_timer);
 
        cref_info = cpnd_info->ckpt_ref_list;
 
@@ -1165,6 +1212,22 @@ static uint32_t cpd_evt_proc_mds_evt(CPD
 
        memset(&phy_slot_sub_slot, 0, sizeof(uint32_t));
 
+       /* CKPT Update state handling */
+       if (cb->node_id == mds_info->node_id && mds_info->svc_id == 
NCSMDS_SVC_ID_CPD) 
+               switch (mds_info->change) {
+               case NCSMDS_UP: /* Both SCs restarted, ckpt needs updating so 
wait for time out */
+                       cb->is_ckpt_updating = true;
+                       cb->ckpt_update_timer.tmr_id = 0;
+                       cb->ckpt_update_timer.type = CPD_TMR_TYPE_CKPT_UPDATE;
+                       cpd_tmr_start(&cb->ckpt_update_timer, 
CPD_CKPT_UPDATE_TIME);
+                       LOG_NO("cpd_evt_proc_mds_evt::Start CKPT UPDATE timer 
tmr_id=%p, arg=%p",
+                               cb->ckpt_update_timer.tmr_id, 
&cb->ckpt_update_timer);
+                       break;
+
+               default: /* Ignore other states */
+                       break;
+               }
+
        switch (mds_info->change) {
 
        case NCSMDS_RED_UP:
@@ -1411,3 +1474,169 @@ static uint32_t cpd_evt_proc_mds_evt(CPD
        TRACE_LEAVE();
        return NCSCC_RC_SUCCESS;
 }
+
+/****************************************************************************
+ * Name          : cpd_evt_proc_ckpt_info_upd
+ *
+ * Description   : Function to process update ckpt info receiving from CPND.
+ *
+ * Arguments     : CPND_CB *cb - CPND CB pointer
+ *                 CPSV_EVT *evt - Received Event structure
+ *
+ * Return Values : NCSCC_RC_SUCCESS/Error.
+ *
+ * Notes         : None.
+ *****************************************************************************/
+static uint32_t cpd_evt_proc_ckpt_info_upd(CPD_CB *cb, CPD_EVT *evt, 
CPSV_SEND_INFO *sinfo)
+{
+       CPSV_EVT send_evt;
+       SaAisErrorT rc = SA_AIS_OK;
+       uint32_t proc_rc = NCSCC_RC_SUCCESS;
+       CPD_CKPT_INFO_NODE *ckpt_node = 0;
+       CPD_CKPT_MAP_INFO *map_info = NULL;
+       CPSV_ND2D_CKPT_INFO_UPD *ckpt_info = &evt->info.ckpt_info;
+       bool is_first_rep = false, is_new_noncol = false;
+       
+       TRACE_ENTER();
+
+       /* Check if Ckpt updating was done or time-out */
+       if (cb->is_ckpt_updating == false) {
+               LOG_ER("cpd ckpt update - Updating ckpt was done or time-out");
+               rc = SA_AIS_ERR_TIMEOUT;
+               goto send_rsp;
+       }
+
+       /* Verify if the checkpoint exist in the database */
+       cpd_ckpt_map_node_get(&cb->ckpt_map_tree, &ckpt_info->ckpt_name, 
&map_info);
+       if (map_info) {
+               if (!m_COMPARE_CREATE_ATTR(&ckpt_info->attributes, 
&map_info->attributes)) {
+                       /* TODO: There is difference in checkpoint attribute 
betweent replicas.
+                        * This should never happen */
+                       LOG_ER("cpd ckpt update - Difference in checkpoint 
attribute, ckpt name,dest :%s,%"PRIu64,ckpt_info->ckpt_name.value, sinfo->dest);
+                       rc = SA_AIS_ERR_EXIST;
+                       goto send_rsp;
+               }
+       } else {
+               is_first_rep = true;
+       }
+
+       /* Add/Update the entries in ckpt DB, ckpt_map DB, ckpt_node DB */
+       proc_rc = cpd_ckpt_db_update_after_headless(cb, &sinfo->dest, 
ckpt_info, &ckpt_node, &map_info);
+       if (proc_rc == NCSCC_RC_OUT_OF_MEM) {
+               LOG_ER("cpd ckpt update failure ckpt name,dest :  %s, 
%"PRIu64,ckpt_info->ckpt_name.value, sinfo->dest);
+               rc = SA_AIS_ERR_NO_MEMORY;
+               goto send_rsp;
+       } else if (proc_rc != NCSCC_RC_SUCCESS) {
+               LOG_ER("cpd ckpt update failure ckpt name,dest :  %s, 
%"PRIu64,ckpt_info->ckpt_name.value, sinfo->dest);
+               rc = SA_AIS_ERR_LIBRARY;
+               goto send_rsp;
+       }
+
+       /* Update active replica info */
+       if (ckpt_info->is_active) {
+               if (ckpt_node->is_active_exists == false) {
+                       ckpt_node->is_active_exists = true;
+                       ckpt_node->active_dest = sinfo->dest;
+               } else {
+                       /* TODO: There are 2 active replicas existing same 
time. This should not happen */
+                       LOG_ER("cpd ckpt update - There are 2 active replica 
existing on 2 nodes 0x%X and 0x%X",
+                               
m_NCS_NODE_ID_FROM_MDS_DEST(ckpt_node->active_dest),
+                               m_NCS_NODE_ID_FROM_MDS_DEST(sinfo->dest));
+               }
+       }
+
+       /* Update ckpt_node with user info */
+       ckpt_node->num_readers += ckpt_info->num_readers;
+       ckpt_node->num_writers += ckpt_info->num_writers;
+       ckpt_node->num_users += ckpt_info->num_users;
+
+       /* Redundancy A2S This is for async update   */
+       /* Only for 1st replica we send the entire info , for later openings we 
send dest_add */
+       if (is_first_rep) { 
+               cpd_a2s_ckpt_create(cb, ckpt_node);
+               cpd_a2s_ckpt_usr_info(cb, ckpt_node);
+       } else {
+               /* Send the dest info to the Standby SCXB This is for async 
update */
+               cpd_a2s_ckpt_dest_add(cb, ckpt_node, &sinfo->dest);
+               cpd_a2s_ckpt_usr_info(cb, ckpt_node);
+       }
+
+       /* Non-colocated processing */
+       if ((ckpt_info->is_active == true) && 
(!(map_info->attributes.creationFlags & SA_CKPT_CHECKPOINT_COLLOCATED))) {
+               /* Policy is to create the replica on both active & standby 
SCXB's CPND 
+                  Right now replica exists only on the active (local) SCXB */
+               /* if(cb->is_loc_cpnd_up && 
(cpd_get_slot_sub_id_from_mds_dest(sinfo->dest) != ckpt_node->ckpt_on_scxb1)) */
+               if (cb->is_loc_cpnd_up
+                   && (!m_CPND_IS_ON_SCXB(cb->cpd_self_id, 
cpd_get_slot_sub_id_from_mds_dest(sinfo->dest)))) {
+                       proc_rc = cpd_noncolloc_ckpt_rep_create(cb, 
&cb->loc_cpnd_dest, ckpt_node, map_info);
+                       if (proc_rc == NCSCC_RC_SUCCESS)
+                               LOG_IN("cpd non coloc ckpt update success ckpt 
name %s, loc_cpnd_dest:%"PRIu64,ckpt_info->ckpt_name.value, cb->loc_cpnd_dest);
+                       else 
+                               LOG_ER("cpd non coloc ckpt update failure ckpt 
name %s, loc_cpnd_dest:%"PRIu64,ckpt_info->ckpt_name.value, cb->loc_cpnd_dest);
+               }
+               /*  if(cb->is_rem_cpnd_up && 
(cpd_get_slot_sub_id_from_mds_dest(sinfo->dest) != ckpt_node->ckpt_on_scxb2)) */
+               if (cb->is_rem_cpnd_up
+                   && (!m_CPND_IS_ON_SCXB(cb->cpd_remote_id, 
cpd_get_slot_sub_id_from_mds_dest(sinfo->dest)))) {
+                       proc_rc = cpd_noncolloc_ckpt_rep_create(cb, 
&cb->rem_cpnd_dest, ckpt_node, map_info);
+                       if (proc_rc == NCSCC_RC_SUCCESS)
+                               LOG_IN("cpd non coloc ckpt update success 
ckpt_name %s and rem_cpnd 
%"PRIu64,ckpt_info->ckpt_name.value,cb->rem_cpnd_dest);
+                       else
+                               LOG_ER("cpd non coloc ckpt update failure 
ckpt_name %s and rem_cpnd 
%"PRIu64,ckpt_info->ckpt_name.value,cb->rem_cpnd_dest);
+               }
+               /* ND on SCXB has created the same checkpoint, so is_new_noncol 
must be made to true */
+               is_new_noncol = true;
+       }
+
+       /* Ckpt info successfully updated at CPD, send it to all CPNDs */
+       /* Broadcast the ckpt add info to all the CPNDs, only the relevent 
CPNDs 
+          will process this message */
+       if ((is_first_rep == false) || (is_new_noncol == true)) {
+               memset(&send_evt, 0, sizeof(CPSV_EVT));
+               send_evt.type = CPSV_EVT_TYPE_CPND;
+               send_evt.info.cpnd.type = CPND_EVT_D2ND_CKPT_REP_ADD;
+               send_evt.info.cpnd.info.ckpt_add.ckpt_id = ckpt_node->ckpt_id;
+               send_evt.info.cpnd.info.ckpt_add.mds_dest = sinfo->dest;
+               send_evt.info.cpnd.info.ckpt_add.is_cpnd_restart = false;
+
+               proc_rc = cpd_mds_bcast_send(cb, &send_evt, NCSMDS_SVC_ID_CPND);
+               if (proc_rc != NCSCC_RC_SUCCESS) {
+                       rc = SA_AIS_ERR_LIBRARY;
+                       LOG_ER("cpd non coloc ckpt update - broadcast REP_ADD 
failed rc=%u", proc_rc);
+               } else 
+                       LOG_IN("cpd rep add success for ckpt_id:%llx,dest 
:%"PRIu64,map_info->ckpt_id,sinfo->dest);
+       }
+
+       /* Sync the non-collocated checkpoint. Although the ckpt was 
synchronized when the replica created
+        * that synchronization didn't take effect because the SC replica 
hasn't been added yet */
+       if ((ckpt_info->is_active == true) && 
(!(map_info->attributes.creationFlags & SA_CKPT_CHECKPOINT_COLLOCATED))) {
+               memset(&send_evt, '\0', sizeof(CPSV_EVT));
+               send_evt.type = CPSV_EVT_TYPE_CPND;
+               send_evt.info.cpnd.type = CPND_EVT_ND2ND_CKPT_SYNC_REQ;
+               send_evt.info.cpnd.info.sync_req.ckpt_id = ckpt_node->ckpt_id;
+
+               proc_rc = cpd_mds_msg_send(cb, NCSMDS_SVC_ID_CPND, 
ckpt_node->active_dest, &send_evt);
+               if (proc_rc != NCSCC_RC_SUCCESS) {
+                       rc = SA_AIS_ERR_LIBRARY;
+                       LOG_ER("cpd non coloc ckpt update - sync failed rc=%u", 
proc_rc);
+               }
+
+       }
+
+       if (is_first_rep)
+               LOG_IN("cpd ckpt update success for first replica 
ckpt_id:%llx,dest :%"PRIu64,map_info->ckpt_id,sinfo->dest);
+       else
+               LOG_IN("cpd ckpt update success ckpt_id:%llx,dest 
:%"PRIu64,map_info->ckpt_id,sinfo->dest);
+
+ send_rsp:
+       /* Send the response to the creater of this ckpt */
+       /* Populate & Send the Open Event to CPND */
+       memset(&send_evt, 0, sizeof(CPSV_EVT));
+       send_evt.info.cpnd.info.ckpt_info_update_ack.error = rc;
+
+       send_evt.type = CPSV_EVT_TYPE_CPND;
+       send_evt.info.cpnd.type = CPND_EVT_D2ND_CKPT_INFO_UPDATE_ACK;
+       proc_rc = cpd_mds_send_rsp(cb, sinfo, &send_evt);
+
+       TRACE_LEAVE2("Ret val %d",proc_rc);
+       return proc_rc;
+}
diff --git a/osaf/services/saf/cpsv/cpd/cpd_imm.c 
b/osaf/services/saf/cpsv/cpd/cpd_imm.c
--- a/osaf/services/saf/cpsv/cpd/cpd_imm.c
+++ b/osaf/services/saf/cpsv/cpd/cpd_imm.c
@@ -20,6 +20,7 @@
 #include "immutil.h"
 #include "saImm.h"
 
+extern const SaImmOiImplementerNameT implementer_name;
 extern struct ImmutilWrapperProfile immutilWrapperProfile;
 #define CPSV_IMM_IMPLEMENTER_NAME (SaImmOiImplementerNameT) 
"safCheckPointService"
 const SaImmOiImplementerNameT implementer_name = CPSV_IMM_IMPLEMENTER_NAME;
@@ -703,3 +704,114 @@ void cpd_imm_reinit_bg(CPD_CB * cb)
        TRACE_LEAVE();
 }
 
+/**
+ * @Brief
+ * Search for old runtime checkpoint objects and delete them
+ *
+ * If the checkpoint server on both SC nodes is stopped, runtime IMM
+ * objects for application checkpoints may be left.
+ * This has to be cleaned up when the checkpoint server is started again.
+ *
+ *
+ */
+SaAisErrorT cpd_clean_checkpoint_objects(CPD_CB *cb)
+{
+       SaAisErrorT rc = SA_AIS_OK;
+       SaImmHandleT immOmHandle;
+       SaImmSearchHandleT immSearchHandle;
+
+       TRACE_ENTER();
+
+       /* Save immutil settings and reconfigure */
+       struct ImmutilWrapperProfile tmp_immutilWrapperProfile;
+       tmp_immutilWrapperProfile.errorsAreFatal = 
immutilWrapperProfile.errorsAreFatal;
+       tmp_immutilWrapperProfile.nTries = immutilWrapperProfile.nTries;
+       tmp_immutilWrapperProfile.retryInterval = 
immutilWrapperProfile.retryInterval;
+
+       immutilWrapperProfile.errorsAreFatal = 0;
+       immutilWrapperProfile.nTries = 500;
+       immutilWrapperProfile.retryInterval = 1000;
+
+       /* Intialize Om API
+        */
+       rc = immutil_saImmOmInitialize(&immOmHandle, NULL, &imm_version);
+       if (rc != SA_AIS_OK) {
+               LOG_ER("%s saImmOmInitialize FAIL %d", __FUNCTION__, rc);
+               goto done;
+       }
+
+       rc = immutil_saImmOiImplementerSet(cb->immOiHandle, implementer_name);
+       if (rc != SA_AIS_OK){
+               LOG_ER("cpd immOiImplmenterSet failed with err = %u", rc);
+               goto done;
+       }
+
+       /* Initialize search for application checkpoint runtime objects
+        * Search for all objects of class 'SaCkptCheckpoint'
+        * Search criteria:
+        * Attribute SaImmAttrClassName == SaCkptCheckpoint
+        */
+       SaImmSearchParametersT_2 searchParam;
+       const char* class_name = "SaCkptCheckpoint";
+       searchParam.searchOneAttr.attrName = "SaImmAttrClassName";
+       searchParam.searchOneAttr.attrValueType = SA_IMM_ATTR_SASTRINGT;
+       searchParam.searchOneAttr.attrValue = &class_name;
+       SaNameT root_name;
+       root_name.value[0] = '\0';
+       root_name.length = 1;
+
+       rc = immutil_saImmOmSearchInitialize_2(
+                       immOmHandle,
+                       &root_name,
+                       SA_IMM_SUBTREE,
+                       SA_IMM_SEARCH_ONE_ATTR | SA_IMM_SEARCH_GET_NO_ATTR,
+                       &searchParam,
+                       NULL,
+                       &immSearchHandle);
+       if (rc != SA_AIS_OK) {
+               LOG_ER("%s saImmOmSearchInitialize FAIL %d", __FUNCTION__, rc);
+               goto done;
+       }
+
+       /* Iterate the search until all objects found
+        * When an object is found it is deleted
+        */
+       SaNameT object_name;
+       SaImmAttrValuesT_2 **attributes;
+
+       while ((rc = immutil_saImmOmSearchNext_2(immSearchHandle, &object_name, 
&attributes)) == SA_AIS_OK) {
+               /* Delete the runtime object and its children. */
+               rc = immutil_saImmOiRtObjectDelete(cb->immOiHandle, 
&object_name);
+               if (rc == SA_AIS_OK) {
+                       TRACE("Object \"%s\" deleted", (char *) 
object_name.value);
+               } else {
+                       LOG_ER("%s saImmOiRtObjectDelete for \"%s\" FAILED %d",
+                                       __FUNCTION__, (char *) 
object_name.value, rc);
+               }
+       }
+
+       if (rc != SA_AIS_ERR_NOT_EXIST) {
+               LOG_ER("%s saImmOmSearchNext FAILED %d", __FUNCTION__, rc);
+       }
+
+done:
+       rc = immutil_saImmOiImplementerClear(cb->immOiHandle);
+       if (rc != SA_AIS_OK) {
+               LOG_ER("saImmOiImplementerClear FAIL %d", rc);
+       }
+
+       /* Finalize the Om API
+        */
+       rc = immutil_saImmOmFinalize(immOmHandle);
+       if (rc != SA_AIS_OK) {
+               LOG_ER("saImmOmFinalize FAIL %d", rc);
+       }
+
+       /* Restore immutil settings */
+       immutilWrapperProfile.errorsAreFatal = 
tmp_immutilWrapperProfile.errorsAreFatal;
+       immutilWrapperProfile.nTries = tmp_immutilWrapperProfile.nTries;
+       immutilWrapperProfile.retryInterval = 
tmp_immutilWrapperProfile.retryInterval;
+
+       TRACE_LEAVE();
+       return rc;
+}
diff --git a/osaf/services/saf/cpsv/cpd/cpd_init.c 
b/osaf/services/saf/cpsv/cpd/cpd_init.c
--- a/osaf/services/saf/cpsv/cpd/cpd_init.c
+++ b/osaf/services/saf/cpsv/cpd/cpd_init.c
@@ -32,6 +32,7 @@
 #include <daemon.h>
 #include "cpd.h"
 #include "cpd_imm.h"
+#include <rda_papi.h>
 
 enum {
        FD_TERM = 0,
@@ -430,6 +431,7 @@ void cpd_main_process(CPD_CB *cb)
        SaSelectionObjectT amf_sel_obj, clm_sel_obj;
        SaAisErrorT error = SA_AIS_OK;
        int term_fd;
+       SaAmfHAStateT rda_role = SA_AMF_HA_STANDBY;
 
        mbx_fd = ncs_ipc_get_sel_obj(&cb->cpd_mbx);
        error = saAmfSelectionObjectGet(cb->amf_hdl, &amf_sel_obj);
@@ -444,13 +446,27 @@ void cpd_main_process(CPD_CB *cb)
        }
 
        daemon_sigterm_install(&term_fd);
-       
+
        error = saClmClusterTrack(cb->clm_hdl, SA_TRACK_CHANGES_ONLY, NULL);
-        if (error != SA_AIS_OK) {
+       if (error != SA_AIS_OK) {
                LOG_ER("cpd clm cluster track failed %u",error);
                 return;
         }
 
+       /* Get the role. If role=SA_AMF_HA_ACTIVE, this is the first checkpoint 
director
+        *    starting after both directors have been down.
+        *    In this case delete old checkpoint runtime objects */
+       if (rda_get_role(&rda_role) != NCSCC_RC_SUCCESS) {
+               LOG_ER("cpd rda_get_role FAILED");
+               return;
+       }
+       if (rda_role == SA_AMF_HA_ACTIVE) {
+               LOG_NO("cpd RDA role is active, clean old checkpoint runtime 
objects");
+               if (cpd_clean_checkpoint_objects(cb)!= NCSCC_RC_SUCCESS) {
+                       LOG_ER("cpd_clean_checkpoint_objects FAILED");
+                       return;
+               }
+       }
 
        /* Set up all file descriptors to listen to */
        fds[FD_TERM].fd = term_fd;
diff --git a/osaf/services/saf/cpsv/cpd/cpd_proc.c 
b/osaf/services/saf/cpsv/cpd/cpd_proc.c
--- a/osaf/services/saf/cpsv/cpd/cpd_proc.c
+++ b/osaf/services/saf/cpsv/cpd/cpd_proc.c
@@ -1252,6 +1252,315 @@ uint32_t cpd_ckpt_reploc_imm_object_dele
        return NCSCC_RC_SUCCESS;
 }
 
+/****************************************************************************
+ * Name          : cpd_ckpt_db_update_after_headless
+ *
+ * Description   : This routine will update the CPD database when a new ckpt
+ *                 got created.
+ *
+ * Return Values : NCSCC_RC_SUCCESS/Error.
+ *
+ * Notes         : None.
+ *****************************************************************************/
+uint32_t cpd_ckpt_db_update_after_headless(CPD_CB *cb,
+                              MDS_DEST *cpnd_dest,
+                              CPSV_ND2D_CKPT_INFO_UPD *ckpt_info,
+                              CPD_CKPT_INFO_NODE **o_ckpt_node, 
CPD_CKPT_MAP_INFO **io_map_info)
+{
+       CPD_CPND_INFO_NODE *node_info = NULL;
+       CPD_CKPT_INFO_NODE *ckpt_node = NULL;
+       CPD_CKPT_MAP_INFO *map_info = NULL;
+       CPD_CKPT_REPLOC_INFO *reploc_info = NULL;
+       uint32_t proc_rc = NCSCC_RC_SUCCESS;
+       SaCkptCheckpointHandleT ckpt_id = 0;
+       bool add_flag = true;
+       SaClmClusterNodeT cluster_node;
+       NODE_ID key;
+       SaClmNodeIdT node_id;
+       SaNameT ckpt_name;
+       CPD_REP_KEY_INFO key_info;
+
+       TRACE_ENTER();
+
+       if (ckpt_info == NULL) {
+               LOG_ER("cpd ckpt_info = NULL");
+               return NCSCC_RC_FAILURE;
+       }
+
+       memset(&ckpt_name, 0, sizeof(SaNameT));
+       memset(&cluster_node, 0, sizeof(SaClmClusterNodeT));
+       memset(&key_info, 0, sizeof(CPD_REP_KEY_INFO));
+       
+       /* -------------------------------------------------------
+        * Update database with MAP_INFO and CKPT_NODE information 
+        * ------------------------------------------------------- */
+       if (*io_map_info == NULL) { 
+       /* There is no map information (i.e this is a first time the checkpoint 
updated)
+        * Thus the map_info and ckpt_node must be created and add into the db 
*/
+
+               /* Fill the MAP INFO Node and add it into the ckpt_map_tree */
+               map_info = m_MMGR_ALLOC_CPD_CKPT_MAP_INFO;
+               if (map_info == NULL) {
+                       LOG_ER("CPD CPD_CKPT_MAP_INFO alloc failed"); 
+                       goto free_mem;
+               }
+
+               memset(map_info, 0, sizeof(CPD_CKPT_MAP_INFO));
+               map_info->ckpt_name = ckpt_info->ckpt_name;
+               map_info->attributes = ckpt_info->attributes;
+               map_info->client_version = ckpt_info->client_version;
+               map_info->ckpt_id = ckpt_info->ckpt_id;
+
+               proc_rc = cpd_ckpt_map_node_add(&cb->ckpt_map_tree, map_info);
+               if (proc_rc != NCSCC_RC_SUCCESS) {
+                       LOG_IN("cpd db add failed for 
ckpt_id:%llx",map_info->ckpt_id);
+                       goto free_mem;
+               }
+
+               /* Update nxt_ckpt_id accordingly so that ID is created 
correctly in next creation */
+               if (cb->nxt_ckpt_id <= ckpt_info->ckpt_id)
+                      cb->nxt_ckpt_id = ckpt_info->ckpt_id + 1;        
+
+               /* Fill the CKPT NODE and add it into the ckpt_tree */
+               ckpt_node = m_MMGR_ALLOC_CPD_CKPT_INFO_NODE;
+               if (ckpt_node == NULL) {
+                       LOG_ER("CPD_CKPT_INFO_NODE alloc failed ");
+                       goto free_mem;
+               }
+
+               memset(ckpt_node, 0, sizeof(CPD_CKPT_INFO_NODE));
+               ckpt_node->ckpt_id = map_info->ckpt_id;
+               ckpt_node->ckpt_name = ckpt_info->ckpt_name;
+               ckpt_node->is_unlink_set = ckpt_info->is_unlink;
+               ckpt_node->attributes = ckpt_info->attributes;
+               if (ckpt_node->attributes.maxSections == 1)
+                       ckpt_node->num_sections = 1;
+               ckpt_node->ret_time = ckpt_info->attributes.retentionDuration;
+               m_GET_TIME_STAMP(ckpt_node->create_time);
+               ckpt_node->ckpt_flags = ckpt_info->ckpt_flags;
+                       
+               if 
((!m_IS_SA_CKPT_CHECKPOINT_COLLOCATED(&ckpt_info->attributes))
+                   && (m_CPND_IS_ON_SCXB(cb->cpd_self_id, 
cpd_get_slot_sub_id_from_mds_dest(*cpnd_dest)))) {
+                       if (!ckpt_node->ckpt_on_scxb1)
+                               ckpt_node->ckpt_on_scxb1 = 
(uint32_t)cpd_get_slot_sub_id_from_mds_dest(*cpnd_dest);
+                       else
+                               ckpt_node->ckpt_on_scxb2 = 
(uint32_t)cpd_get_slot_sub_id_from_mds_dest(*cpnd_dest);
+               }
+               if 
((!m_IS_SA_CKPT_CHECKPOINT_COLLOCATED(&ckpt_info->attributes))
+                   && m_CPND_IS_ON_SCXB(cb->cpd_remote_id, 
cpd_get_slot_sub_id_from_mds_dest(*cpnd_dest))) {
+                       if (!ckpt_node->ckpt_on_scxb1)
+                               ckpt_node->ckpt_on_scxb1 = 
(uint32_t)cpd_get_slot_sub_id_from_mds_dest(*cpnd_dest);
+                       else
+                               ckpt_node->ckpt_on_scxb2 = 
(uint32_t)cpd_get_slot_sub_id_from_mds_dest(*cpnd_dest);
+               }
+
+               proc_rc = cpd_ckpt_node_add(&cb->ckpt_tree, ckpt_node, 
cb->ha_state, cb->immOiHandle);
+               if (proc_rc != NCSCC_RC_SUCCESS) {
+                       LOG_ER("cpd db add failed for 
ckpt_id:%llx",ckpt_node->ckpt_id);
+                       goto free_mem;
+               }
+
+               *io_map_info = map_info;
+               *o_ckpt_node = ckpt_node;
+       } else {
+       /* The checkpoint data already exist in database */
+       
+               map_info = *io_map_info;
+               ckpt_id = (*io_map_info)->ckpt_id;
+
+               /* This checkpoint already available with CPD, Get the 
ckpt_node */
+               cpd_ckpt_node_get(&cb->ckpt_tree, &ckpt_id, &ckpt_node);
+               if (ckpt_node == NULL) {
+                       /* This should not happen, some thing seriously wrong 
with the CPD data base */
+                       /* TODO: The right thing is crash the CPD TBD */
+                       LOG_ER("cpd db maybe crashed for ckpt_id:%llx",ckpt_id);
+                       return NCSCC_RC_FAILURE;
+               }
+               *o_ckpt_node = ckpt_node;
+       }
+
+       /* ------------------------------------------
+        * Update database with CPND_NODE information 
+        * ------------------------------------------ */
+       /* Get the CPD_CPND_INFO_NODE (CPND from where this ckpt is created) */
+       proc_rc = cpd_cpnd_info_node_find_add(&cb->cpnd_tree, cpnd_dest, 
&node_info, &add_flag);
+       if (!node_info) {
+               LOG_ER("CPD DB add cpnd info node failed with return value:%u 
for cpnd_dest:0x%X", proc_rc ,
+                       m_NCS_NODE_ID_FROM_MDS_DEST(*cpnd_dest));
+               proc_rc = NCSCC_RC_OUT_OF_MEM;
+               goto free_mem;
+       }
+
+       /* --------------------------------------------
+        * Update database with REPLOC_NODE information 
+        * -------------------------------------------- */
+       /* Processing for the Node name with CLM  */
+       key = m_NCS_NODE_ID_FROM_MDS_DEST(*cpnd_dest);
+       node_id = key;
+
+       if (saClmClusterNodeGet(cb->clm_hdl, node_id, CPD_CLM_API_TIMEOUT, 
&cluster_node) != SA_AIS_OK) {
+               proc_rc = NCSCC_RC_FAILURE;
+               LOG_ER("saClmClusterNodeGet failed for node_id 0x%X",node_id);
+               goto free_mem;
+       }
+
+       node_info->node_name = cluster_node.nodeName;
+       key_info.node_name = cluster_node.nodeName;
+       key_info.ckpt_name = ckpt_info->ckpt_name;
+
+       /* Create and add the reploc node into ckpt_reploc_tree if it doesn't 
exist */
+       /* Only create reploc_node for Collocated and Non-collocated active 
replica */
+       cpd_ckpt_reploc_get(&cb->ckpt_reploc_tree, &key_info, &reploc_info);
+       if ((reploc_info == NULL) &&
+           ((m_IS_SA_CKPT_CHECKPOINT_COLLOCATED(&ckpt_info->attributes) || 
ckpt_info->is_active))) {
+
+               /* Allocate replica location node memory */
+               reploc_info = m_MMGR_ALLOC_CPD_CKPT_REPLOC_INFO;
+               if (reploc_info == NULL) {
+                       LOG_ER("Allocate replica location memory failed");
+                       goto free_mem;
+               }
+
+               /* Initialize the reploc info node */
+               memset(reploc_info, 0, sizeof(CPD_CKPT_REPLOC_INFO));
+               reploc_info->rep_key.node_name = cluster_node.nodeName;
+               reploc_info->rep_key.ckpt_name = ckpt_info->ckpt_name;
+
+               if (!m_IS_SA_CKPT_CHECKPOINT_COLLOCATED(&ckpt_info->attributes))
+                       reploc_info->rep_type = REP_NONCOLL;
+               else {
+                       if ((ckpt_info->attributes.creationFlags & 
SA_CKPT_WR_ALL_REPLICAS)
+                           && 
(m_IS_SA_CKPT_CHECKPOINT_COLLOCATED(&ckpt_info->attributes)))
+                               reploc_info->rep_type = REP_SYNCUPD;
+
+                       if ((ckpt_info->attributes.creationFlags & 
SA_CKPT_WR_ACTIVE_REPLICA)
+                           && 
(m_IS_SA_CKPT_CHECKPOINT_COLLOCATED(&ckpt_info->attributes)))
+                               reploc_info->rep_type = REP_NOTACTIVE;
+                       if ((ckpt_info->attributes.creationFlags & 
SA_CKPT_WR_ACTIVE_REPLICA_WEAK)
+                           && 
(m_IS_SA_CKPT_CHECKPOINT_COLLOCATED(&ckpt_info->attributes)))
+                               reploc_info->rep_type = REP_NOTACTIVE;
+               }
+
+               /* Add new reploc node into the ckpt_reploc_tree and create IMM 
Object for this replica */
+               proc_rc = cpd_ckpt_reploc_node_add(&cb->ckpt_reploc_tree, 
reploc_info, cb->ha_state, cb->immOiHandle);
+               if (proc_rc != NCSCC_RC_SUCCESS) {
+                       LOG_ER("cpd db add failed in db entry update");
+                       goto free_mem;
+               }
+
+               /* Add the CPND Details (CPND reference) to the ckpt node */
+               cpd_node_ref_info_add(ckpt_node, cpnd_dest);
+
+               /* Add the ckpt reference to the CPND node info */
+               cpd_ckpt_ref_info_add(node_info, ckpt_node);
+       }
+
+       TRACE_LEAVE();
+       return NCSCC_RC_SUCCESS;
+
+ free_mem:
+       if (*io_map_info == NULL) {
+               if (ckpt_node) {
+                       CPD_CKPT_INFO_NODE *tmp_ckpt_node;
+                       cpd_ckpt_node_get(&cb->ckpt_tree, &ckpt_info->ckpt_id, 
&tmp_ckpt_node);
+                       if (tmp_ckpt_node) /* The ckpt_node was added into the 
tree */
+                               cpd_ckpt_node_delete(cb, ckpt_node);
+                       else
+                               m_MMGR_FREE_CPD_CKPT_INFO_NODE(ckpt_node);
+               }
+
+               if (map_info) {
+                       CPD_CKPT_MAP_INFO *tmp_map_info;
+                       cpd_ckpt_map_node_get(&cb->ckpt_map_tree, 
&ckpt_info->ckpt_name, &tmp_map_info);
+                       if (tmp_map_info) /* The map info was added into the 
tree */
+                               cpd_ckpt_map_node_delete(cb, map_info);
+                       else
+                               m_MMGR_FREE_CPD_CKPT_MAP_INFO(map_info);
+               }
+       }
+
+       if (reploc_info)
+               m_MMGR_FREE_CPD_CKPT_REPLOC_INFO(reploc_info);
+
+       TRACE_LEAVE();
+       return proc_rc;
+}
+
+/****************************************************************************
+ * Name          : cpd_proc_ckpt_update_post
+ *
+ * Description   : This routine will process post activities after updating
+ *                ckpt at headless:
+ *                - Set active replica for write all collocated ckpt
+ *
+ * Return Values : NCSCC_RC_SUCCESS/Error.
+ *
+ * Notes         : None.
+ *****************************************************************************/
+uint32_t cpd_proc_ckpt_update_post(CPD_CB *cb)
+{
+       CPD_CKPT_INFO_NODE *ckpt_node = NULL;
+
+       TRACE_ENTER();
+
+       cpd_ckpt_node_getnext(&cb->ckpt_tree, NULL, &ckpt_node);
+       while(ckpt_node) {
+               SaCkptCheckpointHandleT prev_ckpt_id = ckpt_node->ckpt_id;
+               /* Start loop */
+
+               /* Set active replica for write all non-collocated checkpoints 
*/
+               if (m_IS_SA_CKPT_CHECKPOINT_COLLOCATED(&ckpt_node->attributes) 
&& 
+               !m_IS_ASYNC_UPDATE_OPTION(&ckpt_node->attributes)) {
+
+                       if (ckpt_node->is_active_exists == false) {
+                               CPSV_EVT send_evt;
+                               CPD_NODE_REF_INFO *nref_info = 
ckpt_node->node_list;
+
+                               /* The policy is to select the next replica as 
the active
+                                  replica, This is available at last node in 
the ckpt_node->node_list */
+                               while (nref_info) {
+                                       if (nref_info->next == NULL)
+                                               break;  /* This is the last 
node */
+                                       else
+                                               nref_info = nref_info->next;
+                               }
+
+                               if (nref_info) {
+                                       ckpt_node->is_active_exists = true;
+                                       ckpt_node->active_dest = 
nref_info->dest;
+                               } else {
+                                       LOG_ER("cpd ckpt_id %llu - node_list = 
NULL", ckpt_node->ckpt_id);
+                                       cpd_ckpt_node_getnext(&cb->ckpt_tree, 
&prev_ckpt_id, &ckpt_node);
+                                       continue;
+                               }
+
+                               /* broadcast to all CPNDs and CPAs */
+                               memset(&send_evt, 0, sizeof(CPSV_EVT));
+                               send_evt.type = CPSV_EVT_TYPE_CPND;
+                               send_evt.info.cpnd.type = 
CPND_EVT_D2ND_CKPT_ACTIVE_SET;
+                               send_evt.info.cpnd.info.active_set.ckpt_id = 
ckpt_node->ckpt_id;
+                               send_evt.info.cpnd.info.active_set.mds_dest = 
ckpt_node->active_dest;
+                               (void)cpd_mds_bcast_send(cb, &send_evt, 
NCSMDS_SVC_ID_CPND);
+
+                               memset(&send_evt, 0, sizeof(CPSV_EVT));
+                               send_evt.type = CPSV_EVT_TYPE_CPA;
+                               send_evt.info.cpa.type = 
CPA_EVT_D2A_ACT_CKPT_INFO_BCAST_SEND;
+                               send_evt.info.cpa.info.ackpt_info.ckpt_id = 
ckpt_node->ckpt_id;
+                               send_evt.info.cpa.info.ackpt_info.mds_dest = 
ckpt_node->active_dest;
+                               (void)cpd_mds_bcast_send(cb, &send_evt, 
NCSMDS_SVC_ID_CPA);
+
+                               LOG_NO("cpd ckpt active change success for 
ckpt_id:%llx,active_dest:0x%X",
+                               ckpt_node->ckpt_id, 
m_NCS_NODE_ID_FROM_MDS_DEST(ckpt_node->active_dest));
+                       }
+               }
+
+               /* End loop */
+               cpd_ckpt_node_getnext(&cb->ckpt_tree, &prev_ckpt_id, 
&ckpt_node);
+       }
+
+       return NCSCC_RC_SUCCESS;
+}
+
 
/******************************************************************************************
  * Name          : cpd_proc_broadcast_RDSET_STOP
  *
diff --git a/osaf/services/saf/cpsv/cpd/cpd_tmr.c 
b/osaf/services/saf/cpsv/cpd/cpd_tmr.c
--- a/osaf/services/saf/cpsv/cpd/cpd_tmr.c
+++ b/osaf/services/saf/cpsv/cpd/cpd_tmr.c
@@ -42,6 +42,8 @@ void cpd_timer_expiry(NCSCONTEXT uarg)
        CPSV_EVT *evt = NULL;
        uint32_t cpd_hdl = m_CPD_GET_CB_HDL;
 
+       TRACE("cpd_timer_expiry(uarg=%p, type=%u)", uarg, tmr->type);
+
        /* post a message to the corresponding component */
        if ((cb = (CPD_CB *)ncshm_take_hdl(NCS_SERVICE_ID_CPD, cpd_hdl)) == 
NULL)
                return;
@@ -60,6 +62,11 @@ void cpd_timer_expiry(NCSCONTEXT uarg)
                                evt->info.cpd.info.tmr_info.info.cpnd_dest = 
tmr->info.cpnd_dest;
                                break;
 
+                       case CPD_TMR_TYPE_CKPT_UPDATE:
+                               evt->info.cpd.info.tmr_info.type = 
CPD_TMR_TYPE_CKPT_UPDATE;
+                               evt->info.cpd.info.tmr_info.info.cpnd_dest = 0;
+                               break;
+
                        default:
                                break;
 
diff --git a/osaf/services/saf/cpsv/cpnd/cpnd_db.c 
b/osaf/services/saf/cpsv/cpnd/cpnd_db.c
--- a/osaf/services/saf/cpsv/cpnd/cpnd_db.c
+++ b/osaf/services/saf/cpsv/cpnd/cpnd_db.c
@@ -184,6 +184,22 @@ void cpnd_client_node_get(CPND_CB *cb, S
 }
 
 /****************************************************************************
+ * Name          : cpnd_number_of_clients_get
+ *
+ * Description   : Function to get the number of client nodes from client db 
Tree.
+ *
+ * Arguments     : CPND_CB *cb, - CPND Control Block
+ *
+ * Return Values : uint32_t, the number of clients in db Tree.
+ *
+ * Notes         : None.
+ *****************************************************************************/
+uint32_t cpnd_number_of_clients_get(CPND_CB *cb)
+{
+       return (uint32_t)ncs_patricia_tree_size(&cb->client_info_db);
+}
+
+/****************************************************************************
  * Name          : cpnd_client_node_getnext
  *
  * Description   : Function to get next ckpt node of a given ckpt from ckpt 
Tree.
diff --git a/osaf/services/saf/cpsv/cpnd/cpnd_evt.c 
b/osaf/services/saf/cpsv/cpnd/cpnd_evt.c
--- a/osaf/services/saf/cpsv/cpnd/cpnd_evt.c
+++ b/osaf/services/saf/cpsv/cpnd/cpnd_evt.c
@@ -28,6 +28,8 @@
 
 extern uint32_t cpnd_ckpt_non_collocated_rplica_close(CPND_CB *cb, 
CPND_CKPT_NODE *cp_node, SaAisErrorT *error);
 extern uint32_t cpnd_proc_non_colloc_rt_expiry(CPND_CB *cb, 
SaCkptCheckpointHandleT ckpt_id);
+extern void cpnd_proc_ckpt_info_update(CPND_CB *cb);
+extern void cpnd_proc_active_down_ckpt_node_del(CPND_CB *cb, MDS_DEST 
mds_dest);
 
 static uint32_t cpnd_evt_proc_cb_dump(CPND_CB *cb);
 static uint32_t cpnd_evt_proc_ckpt_init(CPND_CB *cb, CPND_EVT *evt, 
CPSV_SEND_INFO *sinfo);
@@ -1032,6 +1034,12 @@ static uint32_t cpnd_evt_proc_ckpt_close
        TRACE_ENTER();
        memset(&send_evt, '\0', sizeof(CPSV_EVT));
 
+       if (cpnd_number_of_clients_get(cb) == 0) {
+               /* The tree may have been cleaned up, if both controllers went 
down and NCSMDS_DOWN was received */
+               send_evt.info.cpa.info.closeRsp.error = SA_AIS_OK;
+               goto agent_rsp;
+       }
+
        if (!cpnd_is_cpd_up(cb)) {
                send_evt.info.cpa.info.closeRsp.error = SA_AIS_ERR_TRY_AGAIN;
                goto agent_rsp;
@@ -3844,6 +3852,8 @@ static uint32_t cpnd_evt_proc_mds_evt(CP
        if ((evt->info.mds_info.change == NCSMDS_DOWN) && 
evt->info.mds_info.svc_id == NCSMDS_SVC_ID_CPA) {
                cpnd_proc_cpa_down(cb, evt->info.mds_info.dest);
        } else if ((evt->info.mds_info.change == NCSMDS_DOWN) && 
evt->info.mds_info.svc_id == NCSMDS_SVC_ID_CPD) {
+               /* Headless state (both SCs are down) happens */
+               cb->is_cpd_need_update = true;
                cpnd_proc_cpd_down(cb);
        } else if ((evt->info.mds_info.change == NCSMDS_UP) && 
evt->info.mds_info.svc_id == NCSMDS_SVC_ID_CPA) {
                cpnd_proc_cpa_up(cb, evt->info.mds_info.dest);
@@ -3853,6 +3863,18 @@ static uint32_t cpnd_evt_proc_mds_evt(CP
        } else if ((evt->info.mds_info.change == NCSMDS_CHG_ROLE) &&
                   (evt->info.mds_info.role == V_DEST_RL_ACTIVE) && 
(evt->info.mds_info.svc_id == NCSMDS_SVC_ID_CPD)) {
                cpnd_proc_cpd_new_active(cb);
+
+               /* Update ckpt info to CPD after headless state */
+               if (cb->is_cpd_need_update == true) {
+                       cpnd_proc_ckpt_info_update(cb);
+                       cb->is_cpd_need_update = false;
+               }
+       } else if ((evt->info.mds_info.change == NCSMDS_DOWN) && 
evt->info.mds_info.svc_id == NCSMDS_SVC_ID_CPND) {
+               /* In headless state, when the cpnd is down the node also 
restart.
+                * Thus the non-collocated checkpoint which has active replica 
located on this node
+                * should be deleted */
+               if ((cb->is_cpd_need_update == true) && (cb->is_cpd_up == 
false))
+                       cpnd_proc_active_down_ckpt_node_del(cb, 
evt->info.mds_info.dest);
        }
 
        return rc;
diff --git a/osaf/services/saf/cpsv/cpnd/cpnd_init.c 
b/osaf/services/saf/cpsv/cpnd/cpnd_init.c
--- a/osaf/services/saf/cpsv/cpnd/cpnd_init.c
+++ b/osaf/services/saf/cpsv/cpnd/cpnd_init.c
@@ -560,8 +560,27 @@ void cpnd_main_process(CPND_CB *cb)
 
                if (fds[FD_CLM].revents & POLLIN) {
                        clm_error = saClmDispatch(cb->clm_hdl, SA_DISPATCH_ALL);
-                       if (clm_error != SA_AIS_OK) {
-                               LOG_ER("cpnd amf dispatch failure 
%u",clm_error);
+                       if (clm_error == SA_AIS_ERR_BAD_HANDLE) {
+                               SaVersionT clm_version;
+                               SaClmHandleT clmHandle;
+                               SaClmCallbacksT gen_cbk;
+
+                               LOG_NO("Bad CLM handle. Reinitializing.");
+                               usleep(100000);
+
+                               m_CPSV_GET_AMF_VER(clm_version);
+                               gen_cbk.saClmClusterNodeGetCallback = NULL;
+                               gen_cbk.saClmClusterTrackCallback = 
cpnd_clm_cluster_track_cb;
+
+                               clm_error = saClmInitialize(&clmHandle, 
&gen_cbk, &clm_version);
+                               if (clm_error != SA_AIS_OK) {
+                                        LOG_ER("cpnd clm init failed with 
return value:%d", clm_error);
+                                         TRACE_LEAVE();
+                                          return;
+                               }
+                               cb->clm_hdl = clmHandle;
+                       } else if (clm_error != SA_AIS_OK) {
+                               LOG_ER("cpnd clm dispatch failure %u", 
clm_error);
                        }
                }
                /* process the CPND Mail box */
diff --git a/osaf/services/saf/cpsv/cpnd/cpnd_mds.c 
b/osaf/services/saf/cpsv/cpnd/cpnd_mds.c
--- a/osaf/services/saf/cpsv/cpnd/cpnd_mds.c
+++ b/osaf/services/saf/cpsv/cpnd/cpnd_mds.c
@@ -152,6 +152,19 @@ uint32_t cpnd_mds_register(CPND_CB *cb)
                goto error1;
        }
 
+
+       /* STEP 5: Subscribe to CPND up/down events */
+       svc_id[0] = NCSMDS_SVC_ID_CPND;
+       svc_info.i_op = MDS_SUBSCRIBE;
+       svc_info.info.svc_subscribe.i_num_svcs = 1;
+       svc_info.info.svc_subscribe.i_scope = NCSMDS_SCOPE_NONE;
+       svc_info.info.svc_subscribe.i_svc_ids = svc_id;
+
+       if (ncsmds_api(&svc_info) == NCSCC_RC_FAILURE) {
+               LOG_ER("cpnd mds subscribe cpnd failed");
+               goto error1;
+       }
+
        TRACE_LEAVE();
        return NCSCC_RC_SUCCESS;
  error1:
diff --git a/osaf/services/saf/cpsv/cpnd/cpnd_proc.c 
b/osaf/services/saf/cpsv/cpnd/cpnd_proc.c
--- a/osaf/services/saf/cpsv/cpnd/cpnd_proc.c
+++ b/osaf/services/saf/cpsv/cpnd/cpnd_proc.c
@@ -35,6 +35,8 @@ static void cpnd_dump_replica_info(CPND_
 static void cpnd_dump_section_info(CPND_CKPT_SECTION_INFO *sec_info);
 static void cpnd_dump_shm_info(NCS_OS_POSIX_SHM_REQ_INFO *open);
 static void cpnd_dump_ckpt_attri(CPND_CKPT_NODE *cp_node);
+static void cpnd_ckpt_sc_cpnd_mdest_del(CPND_CB *cb);
+static void cpnd_headless_ckpt_node_del(CPND_CB *cb);
 
 /****************************************************************************
  * Name          : cpnd_ckpt_client_add
@@ -725,11 +727,11 @@ uint32_t cpnd_ckpt_sec_read(CPND_CKPT_NO
  *****************************************************************************/
 void cpnd_proc_cpd_down(CPND_CB *cb)
 {
-       /* cleanup ckpt node tree */
-       cpnd_ckpt_node_tree_cleanup(cb);
-
-       /* cleanup client node tree */
-       cpnd_client_node_tree_cleanup(cb);
+       /* cleanup all SC cpnd mdests in the ckpt node dest list */
+       cpnd_ckpt_sc_cpnd_mdest_del(cb);
+
+       /* cleanup ckpt_node and replica */
+       cpnd_headless_ckpt_node_del(cb);
 }
 
 /****************************************************************************
@@ -2363,3 +2365,305 @@ void cpnd_proc_free_read_data(CPSV_EVT *
                
m_MMGR_FREE_CPND_DEFAULT(evt->info.cpa.info.sec_data_rsp.info.read_data);
        }
 }
+
+/****************************************************************************************
+ * Name          : cpnd_ckpt_sc_cpnd_mdest_del
+ *
+ * Description   : This is the function delete sc cpnd mds dests on all ckpt 
node
+ * Arguments     : cb       - CPND Control Block pointer
+ * 
+ * Return Values : NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE
+ 
*****************************************************************************************/
+void cpnd_ckpt_sc_cpnd_mdest_del(CPND_CB *cb)
+{
+       CPND_CKPT_NODE *ckpt_node = NULL;
+
+       TRACE_ENTER();
+       cpnd_ckpt_node_getnext(cb, 0, &ckpt_node);
+       while (ckpt_node != NULL) {
+               CPSV_CPND_DEST_INFO *dest_list = NULL;
+       
+               dest_list = ckpt_node->cpnd_dest_list;
+
+               /* Delete SC cpnd mdests in the cpnd_dest_list */
+               while (dest_list) {
+                       if ((m_CPND_IS_ON_SCXB (cb->cpnd_active_id, 
cpnd_get_slot_sub_slot_id_from_mds_dest(dest_list->dest))) ||
+                           (m_CPND_IS_ON_SCXB (cb->cpnd_standby_id, 
cpnd_get_slot_sub_slot_id_from_mds_dest(dest_list->dest)))) 
+                               cpnd_ckpt_remote_cpnd_del(ckpt_node, 
dest_list->dest);
+
+                       dest_list = dest_list->next;
+               }
+
+               SaCkptCheckpointHandleT prev_ckpt_id;
+               prev_ckpt_id = ckpt_node->ckpt_id;
+               cpnd_ckpt_node_getnext(cb, prev_ckpt_id, &ckpt_node);
+       }
+       TRACE_LEAVE();
+}
+
+/****************************************************************************************
+ * Name          : cpnd_headless_ckpt_node_del
+ *
+ * Description   : This is the function delete following type of ckpt node:
+ *                 - ckpt node was unlinked
+ *                 - non-collocated ckpt node which has active replica located 
on SC
+ *
+ * Arguments     : cb       - CPND Control Block pointer
+ * 
+ * Return Values : NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE
+ 
*****************************************************************************************/
+void cpnd_headless_ckpt_node_del(CPND_CB *cb)
+{
+       CPND_CKPT_NODE *ckpt_node = NULL;
+       CPSV_EVT send_evt;
+
+       TRACE_ENTER();
+       cpnd_ckpt_node_getnext(cb, 0, &ckpt_node);
+       while (ckpt_node != NULL) {
+               SaCkptCheckpointHandleT prev_ckpt_id = ckpt_node->ckpt_id;
+               MDS_DEST active_mds_dest = ckpt_node->active_mds_dest;
+               bool destroy = false;
+
+               /* Unlink checkpoint */
+               if (ckpt_node->is_unlink == true)
+                       destroy = true;
+
+               /* Non collocated checkpoint with active replica located on SC 
*/
+               if 
(!m_CPND_IS_COLLOCATED_ATTR_SET(ckpt_node->create_attrib.creationFlags)){
+                       if ((m_CPND_IS_ON_SCXB (cb->cpnd_active_id, 
cpnd_get_slot_sub_slot_id_from_mds_dest(active_mds_dest))) ||
+                           (m_CPND_IS_ON_SCXB (cb->cpnd_standby_id, 
cpnd_get_slot_sub_slot_id_from_mds_dest(active_mds_dest))))
+                               destroy = true;
+               }
+
+               if (destroy == true) {
+                       /* Delete ckpt_node and replica */
+                       cpnd_ckpt_replica_delete(cb, ckpt_node);
+                       cpnd_restart_shm_ckpt_free(cb, ckpt_node);
+                       cpnd_ckpt_node_destroy(cb, ckpt_node);
+
+                       /* Broadcase CPA_EVT_ND2A_CKPT_DESTROY to CPA */
+                       memset(&send_evt, 0, sizeof(CPSV_EVT));
+                       send_evt.type = CPSV_EVT_TYPE_CPA;
+                       send_evt.info.cpa.type = CPA_EVT_ND2A_CKPT_DESTROY;
+                       send_evt.info.cpa.info.ckpt_destroy.ckpt_id = 
prev_ckpt_id;
+                       cpnd_mds_bcast_send(cb, &send_evt, NCSMDS_SVC_ID_CPA);
+
+                       LOG_IN("cpnd ckpt_node and replica destroy successful - 
cpkt_id - %llu", prev_ckpt_id);
+               }
+
+               cpnd_ckpt_node_getnext(cb, prev_ckpt_id, &ckpt_node);
+       }
+       TRACE_LEAVE();
+}
+
+/****************************************************************************************
+ * Name          : cpnd_proc_ckpt_info_update
+ *
+ * Description   : This is the function update cpd about ckpt info after 
headless
+ *
+ * Arguments     : cb       - CPND Control Block pointer
+ * 
+ * Return Values : NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE
+ 
*****************************************************************************************/
+void cpnd_proc_ckpt_info_update(CPND_CB *cb)
+{
+       uint32_t rc = NCSCC_RC_SUCCESS;
+       CPND_CKPT_NODE *ckpt_node = NULL;
+       CPSV_EVT send_evt;
+       SaVersionT client_version = {'B', 0x02, 0x02};
+       unsigned int remaining_node = cb->ckpt_info_db.n_nodes;
+
+       TRACE_ENTER();
+       memset(&send_evt, '\0', sizeof(CPSV_EVT));
+
+       cpnd_ckpt_node_getnext(cb, 0, &ckpt_node);
+       while (ckpt_node != NULL) {
+               SaCkptCheckpointHandleT prev_ckpt_id = ckpt_node->ckpt_id;
+               CPSV_EVT *out_evt = NULL;
+               bool update_success = false;
+               remaining_node--;
+
+               /* send info to cpd */
+               LOG_NO("cpnd_proc_update_cpd_data::ckpt_name = %s[%llu]", 
(char*)ckpt_node->ckpt_name.value,
+                       ckpt_node->ckpt_id);
+               send_evt.type = CPSV_EVT_TYPE_CPD;
+               send_evt.info.cpd.type = CPD_EVT_ND2D_CKPT_INFO_UPDATE;
+               send_evt.info.cpd.info.ckpt_info.ckpt_id = ckpt_node->ckpt_id;
+               send_evt.info.cpd.info.ckpt_info.ckpt_name = 
ckpt_node->ckpt_name;
+               send_evt.info.cpd.info.ckpt_info.attributes = 
ckpt_node->create_attrib;
+               send_evt.info.cpd.info.ckpt_info.ckpt_flags = 
ckpt_node->open_flags;
+               send_evt.info.cpd.info.ckpt_info.num_users = 
ckpt_node->ckpt_lcl_ref_cnt;
+               send_evt.info.cpd.info.ckpt_info.num_readers = 0;
+               send_evt.info.cpd.info.ckpt_info.num_writers = 0;
+               send_evt.info.cpd.info.ckpt_info.client_version = 
client_version;
+               send_evt.info.cpd.info.ckpt_info.is_unlink = 
ckpt_node->is_unlink; 
+               
+               if (ckpt_node->is_active_exist && 
m_NCS_MDS_DEST_EQUAL(&ckpt_node->active_mds_dest, &cb->cpnd_mdest_id)) {
+                       send_evt.info.cpd.info.ckpt_info.is_active = true;
+               } else
+                       send_evt.info.cpd.info.ckpt_info.is_active = false;
+
+               if (remaining_node == 0)
+                       send_evt.info.cpd.info.ckpt_info.is_last = true;
+               else
+                       send_evt.info.cpd.info.ckpt_info.is_last = false;
+
+               LOG_NO("cpnd_proc_update_cpd_data::send 
CPD_EVT_ND2D_CKPT_INFO_UPDATE");
+               rc = cpnd_mds_msg_sync_send(cb, NCSMDS_SVC_ID_CPD, 
cb->cpd_mdest_id, &send_evt, &out_evt,
+                                           CPSV_WAIT_TIME);
+
+               if (rc != NCSCC_RC_SUCCESS) {
+                       LOG_ER("cpnd_proc_update_cpd_data::fail to send 
CPD_EVT_ND2D_CKPT_INFO_UPDATE");
+               }
+
+               if (out_evt == NULL) {
+                       LOG_ER("cpnd_proc_update_cpd_data:: cpnd ckpt memory 
alloc failed");
+               } else {
+                       switch (out_evt->info.cpnd.type) {
+
+                               case CPND_EVT_D2ND_CKPT_INFO_UPDATE_ACK:
+                                       if 
(out_evt->info.cpnd.info.ckpt_info_update_ack.error == SA_AIS_OK) {
+                                               
LOG_NO("cpnd_proc_update_cpd_data::CPND_EVT_D2ND_CKPT_INFO_UPDATE_ACK 
received");
+                                               update_success = true;
+                                       }
+                                       else {
+                                               
LOG_ER("cpnd_proc_update_cpd_data::Fail to update CPD after headless rc=[%d]",
+                                                      
out_evt->info.cpnd.info.ckpt_info_update_ack.error);
+                                       }
+                                       break;
+                               default:
+                                       LOG_ER("cpnd_proc_update_cpd_data:: 
cpnd evt unknown type :%d",out_evt->info.cpnd.type);
+                                       break;
+                       }
+
+                       cpnd_evt_destroy(out_evt);
+               }
+
+               /* Update ckpt fail destroy the ckpt_node and replica */
+               if (update_success == false) {
+                       /* Delete ckpt_node and replica */
+                       cpnd_ckpt_replica_delete(cb, ckpt_node);
+                       cpnd_restart_shm_ckpt_free(cb, ckpt_node);
+                       cpnd_ckpt_node_destroy(cb, ckpt_node);
+
+                       /* Broadcase CPA_EVT_ND2A_CKPT_DESTROY to CPA */
+                       memset(&send_evt, 0, sizeof(CPSV_EVT));
+                       send_evt.type = CPSV_EVT_TYPE_CPA;
+                       send_evt.info.cpa.type = CPA_EVT_ND2A_CKPT_DESTROY;
+                       send_evt.info.cpa.info.ckpt_destroy.ckpt_id = 
ckpt_node->ckpt_id;
+                       cpnd_mds_bcast_send(cb, &send_evt, NCSMDS_SVC_ID_CPA);
+               } 
+
+               /* The SC is UP again and the checkpoint was recovered 
successfull. Re-initialize ckpt_node flags */ 
+               ckpt_node->is_restart = false;
+
+               /* end of loop */
+               cpnd_ckpt_node_getnext(cb, prev_ckpt_id, &ckpt_node);
+       }
+}
+
+/****************************************************************************************
+ * Name          : cpnd_ckpt_replica_delete
+ *
+ * Description   : This is the function delete replica without sending destroy 
signal to CPD
+ *
+ * Arguments     : cb       - CPND Control Block pointer
+ * 
+ * Return Values : NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE
+ 
*****************************************************************************************/
+void cpnd_ckpt_replica_delete(CPND_CB *cb, CPND_CKPT_NODE *ckpt_node)
+{
+       NCS_OS_POSIX_SHM_REQ_INFO shm_info;
+       uint32_t rc = NCSCC_RC_SUCCESS;
+
+       TRACE_ENTER();
+       if (ckpt_node->cpnd_rep_create) {
+
+               /* First delete all sections in the heckpoint about to be 
deleted */
+               cpnd_ckpt_delete_all_sect(ckpt_node);
+
+               memset(&shm_info, '\0', sizeof(shm_info));
+
+               shm_info.type = NCS_OS_POSIX_SHM_REQ_CLOSE;
+               shm_info.info.close.i_addr = 
ckpt_node->replica_info.open.info.open.o_addr;
+               shm_info.info.close.i_fd = 
ckpt_node->replica_info.open.info.open.o_fd;
+               shm_info.info.close.i_hdl = 
ckpt_node->replica_info.open.info.open.o_hdl;
+               shm_info.info.close.i_size = 
ckpt_node->replica_info.open.info.open.i_size;
+
+               rc = ncs_os_posix_shm(&shm_info);
+
+               if (rc == NCSCC_RC_FAILURE) {
+                       LOG_ER("cpnd ckpt close failed for 
ckpt_id:%llx",ckpt_node->ckpt_id);
+                       TRACE_LEAVE();
+                       return;
+               }
+
+               /* unlink the name */
+               shm_info.type = NCS_OS_POSIX_SHM_REQ_UNLINK;
+               shm_info.info.unlink.i_name = 
ckpt_node->replica_info.open.info.open.i_name;
+
+               rc = ncs_os_posix_shm(&shm_info);
+
+               if (rc == NCSCC_RC_FAILURE) {
+                       LOG_ER("cpnd ckpt unlink failed 
ckpt_id:%llx",ckpt_node->ckpt_id);
+                       TRACE_LEAVE();
+                       return;
+               }
+
+               if (cb->num_rep)
+                       cb->num_rep--;
+
+               
m_MMGR_FREE_CPND_DEFAULT(ckpt_node->replica_info.open.info.open.i_name);
+
+               /* freeing the sec_mapping memory */
+               if (ckpt_node->replica_info.shm_sec_mapping)
+                       
m_MMGR_FREE_CPND_DEFAULT(ckpt_node->replica_info.shm_sec_mapping);
+       }
+       TRACE_LEAVE();
+}
+
+/****************************************************************************************
+ * Name          : cpnd_proc_active_down_ckpt_node_del
+ *
+ * Description   : This is the function delete non-collocated ckpt node which 
has active
+ *                 replica node is down
+ *
+ * Arguments     : cb       - CPND Control Block pointer
+ *                 mds_dest - Active replica cpnd mds_dest
+ * 
+ * Return Values : NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE
+ 
*****************************************************************************************/
+void cpnd_proc_active_down_ckpt_node_del(CPND_CB *cb, MDS_DEST mds_dest)
+{
+       CPND_CKPT_NODE *ckpt_node = NULL;
+       CPSV_EVT send_evt;
+
+       TRACE_ENTER();
+       cpnd_ckpt_node_getnext(cb, 0, &ckpt_node);
+       while (ckpt_node != NULL) {
+               SaCkptCheckpointHandleT prev_ckpt_id = ckpt_node->ckpt_id;
+               MDS_DEST active_mds_dest = ckpt_node->active_mds_dest;
+
+               if 
(!m_CPND_IS_COLLOCATED_ATTR_SET(ckpt_node->create_attrib.creationFlags) &&
+               (active_mds_dest == mds_dest)){
+
+                       /* Delete ckpt_node and replica */
+                       cpnd_ckpt_replica_delete(cb, ckpt_node);
+                       cpnd_restart_shm_ckpt_free(cb, ckpt_node);
+                       cpnd_ckpt_node_destroy(cb, ckpt_node);
+
+                       /* Broadcase CPA_EVT_ND2A_CKPT_DESTROY to CPA */
+                       memset(&send_evt, 0, sizeof(CPSV_EVT));
+                       send_evt.type = CPSV_EVT_TYPE_CPA;
+                       send_evt.info.cpa.type = CPA_EVT_ND2A_CKPT_DESTROY;
+                       send_evt.info.cpa.info.ckpt_destroy.ckpt_id = 
prev_ckpt_id;
+                       cpnd_mds_bcast_send(cb, &send_evt, NCSMDS_SVC_ID_CPA);
+
+                       LOG_NO("cpnd node=0x%X DOWN - ckpt_node and replica 
destroy successful - cpkt_id - %llu",
+                               m_NCS_NODE_ID_FROM_MDS_DEST(mds_dest), 
prev_ckpt_id);
+               }
+
+               cpnd_ckpt_node_getnext(cb, prev_ckpt_id, &ckpt_node);
+       }
+       TRACE_LEAVE();
+}

------------------------------------------------------------------------------
_______________________________________________
Opensaf-devel mailing list
Opensaf-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/opensaf-devel

Reply via email to