osaf/libs/common/cpsv/include/cpd_cb.h   |    2 +
 osaf/libs/common/cpsv/include/cpd_proc.h |    7 +-
 osaf/libs/common/cpsv/include/cpd_red.h  |   14 ++
 osaf/libs/common/cpsv/include/cpsv_evt.h |    8 +
 osaf/services/saf/cpsv/cpd/cpd_amf.c     |    5 +-
 osaf/services/saf/cpsv/cpd/cpd_db.c      |   20 +++-
 osaf/services/saf/cpsv/cpd/cpd_evt.c     |   10 +-
 osaf/services/saf/cpsv/cpd/cpd_mbcsv.c   |   86 +++++++++++++++-
 osaf/services/saf/cpsv/cpd/cpd_proc.c    |  156 ++++++++++++++++++++++++++++++-
 osaf/services/saf/cpsv/cpd/cpd_red.c     |   32 ++++-
 osaf/services/saf/cpsv/cpd/cpd_sbevt.c   |   72 +++++++++++++-
 11 files changed, 384 insertions(+), 28 deletions(-)


Problem:
-------
The saCkptCheckpointNumOpeners is not updated when a node which has a 
checkpoint client restarts.

Solution:
--------
Currently CPD doesn't store number of user on each node. This patch updates CPD 
to update information
about users on each node for each checkpoint. When a node restarts, the CPD 
update the total number of
users for a checkpoint accordingly. This is reflected on 
saCkptCheckpointNumOpeners attribute correctly.

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
@@ -90,6 +90,8 @@ typedef struct cpd_ckpt_info_node {
        uint32_t num_users;
        uint32_t num_readers;
        uint32_t num_writers;
+       uint32_t node_users_cnt;
+       CPD_NODE_USER_INFO *node_users;
 
        /* for imm */
        SaUint32T ckpt_used_size;
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
@@ -60,7 +60,7 @@ uint32_t cpd_noncolloc_ckpt_rep_create(C
                                             CPD_CKPT_INFO_NODE *ckpt_node, 
CPD_CKPT_MAP_INFO *map_info);
 uint32_t cpd_noncolloc_ckpt_rep_delete(CPD_CB *cb, CPD_CKPT_INFO_NODE 
*ckpt_node, CPD_CKPT_MAP_INFO *map_info);
 
-uint32_t cpd_process_cpnd_down(CPD_CB *cb, MDS_DEST *cpnd_dest);
+uint32_t cpd_proc_node_down(CPD_CB *cb, MDS_DEST *cpnd_dest);
 
 uint32_t cpd_proc_active_set(CPD_CB *cb, SaCkptCheckpointHandleT ckpt_id,
                                   MDS_DEST mds_dest, CPD_CKPT_INFO_NODE 
**ckpt_node);
@@ -93,7 +93,7 @@ uint32_t cpd_mbcsv_decode_proc(NCS_MBCSV
 uint32_t cpd_mbcsv_enc_warm_sync_resp(CPD_CB *cb, NCS_MBCSV_CB_ARG *arg);
 uint32_t cpd_mbcsv_encode_proc(NCS_MBCSV_CB_ARG *arg);
 uint32_t cpd_mbcsv_dec_sync_resp(CPD_CB *cb, NCS_MBCSV_CB_ARG *arg);
-uint32_t cpd_process_cpnd_del(CPD_CB *cb, MDS_DEST *cpnd_dest);
+uint32_t cpd_process_cpnd_del_on_standby(CPD_CB *cb, MDS_DEST *cpnd_dest);
 uint32_t cpd_get_slot_sub_id_from_mds_dest(MDS_DEST dest);
 uint32_t cpd_get_slot_sub_slot_id_from_node_id(NCS_NODE_ID i_node_id);
 uint32_t cpd_mbcsv_register(CPD_CB *cb);
@@ -102,4 +102,7 @@ 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);
+void cpd_proc_increase_node_user_info(CPD_CKPT_INFO_NODE *ckpt_node, MDS_DEST 
cpnd_dest, SaCkptCheckpointOpenFlagsT open_flags);
+void cpd_proc_decrease_node_user_info(CPD_CKPT_INFO_NODE *ckpt_node, MDS_DEST 
cpnd_dest, SaCkptCheckpointOpenFlagsT open_flags);
+void cpd_proc_update_user_info_when_node_down(CPD_CB *cb, NODE_ID node_id);
 #endif
diff --git a/osaf/libs/common/cpsv/include/cpd_red.h 
b/osaf/libs/common/cpsv/include/cpd_red.h
--- a/osaf/libs/common/cpsv/include/cpd_red.h
+++ b/osaf/libs/common/cpsv/include/cpd_red.h
@@ -28,6 +28,7 @@ typedef enum cpd_mbcsv_msg_type {
        CPD_A2S_MSG_CKPT_UNLINK,
        CPD_A2S_MSG_CKPT_USR_INFO,
        CPD_A2S_MSG_CKPT_DEST_DOWN,
+       CPD_A2S_MSG_CKPT_USR_INFO_2,
        CPD_A2S_MSG_MAX_EVT
 } CPD_MBCSV_MSG_TYPE;
 
@@ -64,6 +65,18 @@ typedef struct cpd_a2s_ckpt_usr_info {
 
 } CPD_A2S_CKPT_USR_INFO;
 
+typedef struct cpd_a2s_ckpt_usr_info_2 {
+       SaCkptCheckpointHandleT ckpt_id;
+       uint32_t num_user;
+       uint32_t num_writer;
+       uint32_t num_reader;
+       uint32_t num_sections;
+       uint32_t ckpt_on_scxb1;
+       uint32_t ckpt_on_scxb2;
+       uint32_t node_users_cnt;
+       CPD_NODE_USER_INFO *node_list;
+} CPD_A2S_CKPT_USR_INFO_2;
+
 typedef struct cpd_mbcsv_msg {
        CPD_MBCSV_MSG_TYPE type;
        union {
@@ -76,6 +89,7 @@ typedef struct cpd_mbcsv_msg {
                CPD_A2S_CKPT_UNLINK ckpt_ulink;
                CPD_A2S_CKPT_USR_INFO usr_info;
                CPSV_CKPT_DEST_INFO dest_down;
+               CPD_A2S_CKPT_USR_INFO_2 usr_info_2;
        } info;
 } CPD_MBCSV_MSG;
 
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
@@ -821,6 +821,14 @@ typedef struct cpd_tmr_info {
        } info;
 } CPD_TMR_INFO;
 
+typedef struct cpd_node_user_info {
+       MDS_DEST dest;
+       uint32_t num_users;
+       uint32_t num_writers;
+       uint32_t num_readers;
+       struct cpd_node_user_info *next;
+} CPD_NODE_USER_INFO;
+
 /******************************************************************************
  CPD Event Data Structures
  
******************************************************************************/
diff --git a/osaf/services/saf/cpsv/cpd/cpd_amf.c 
b/osaf/services/saf/cpsv/cpd/cpd_amf.c
--- a/osaf/services/saf/cpsv/cpd/cpd_amf.c
+++ b/osaf/services/saf/cpsv/cpd/cpd_amf.c
@@ -226,9 +226,8 @@ void cpd_saf_csi_set_cb(SaInvocationT in
                        while (node_info) {
                                prev_dest = node_info->cpnd_dest;
                                if (node_info->timer_state == 2) {
-                                       TRACE   
-                                               ("THE TIMER STATE IS 2 MEANS 
TIMER EXPIRED BUT STILL DID NOT GET ACTIVE STATE");
-                                       cpd_process_cpnd_down(cb, 
&node_info->cpnd_dest);
+                                       TRACE("THE TIMER STATE IS 2 MEANS TIMER 
EXPIRED BUT STILL DID NOT GET ACTIVE STATE");
+                                       cpd_proc_node_down(cb, 
&node_info->cpnd_dest);
                                }
                                cpd_cpnd_info_node_getnext(&cb->cpnd_tree, 
&prev_dest, &node_info);
 
diff --git a/osaf/services/saf/cpsv/cpd/cpd_db.c 
b/osaf/services/saf/cpsv/cpd/cpd_db.c
--- a/osaf/services/saf/cpsv/cpd/cpd_db.c
+++ b/osaf/services/saf/cpsv/cpd/cpd_db.c
@@ -137,6 +137,7 @@ uint32_t cpd_ckpt_node_delete(CPD_CB *cb
 {
        uint32_t rc = NCSCC_RC_SUCCESS;
        CPD_NODE_REF_INFO *nref_info, *next_info;
+       CPD_NODE_USER_INFO *node_user, *next_node_user;
 
        TRACE_ENTER();
 
@@ -153,6 +154,13 @@ uint32_t cpd_ckpt_node_delete(CPD_CB *cb
                nref_info = next_info;
        }
 
+       node_user = ckpt_node->node_users;
+       while (node_user) {
+               next_node_user = node_user->next;
+               free(node_user);
+               node_user = next_node_user;
+       }
+       
        /* delete imm ckpt runtime object */
        if ((cb->ha_state == SA_AMF_HA_ACTIVE) && (ckpt_node->is_unlink_set != 
true)) {
                if (immutil_saImmOiRtObjectDelete(cb->immOiHandle, 
&ckpt_node->ckpt_name) != SA_AIS_OK) {
@@ -780,6 +788,8 @@ uint32_t cpd_cpnd_info_node_find_add(NCS
        /*MDS_DEST key; */
        NODE_ID key;
 
+       TRACE_ENTER();
+
        memset(&key, 0, sizeof(NODE_ID));
        /* Fill the Key */
        key = m_NCS_NODE_ID_FROM_MDS_DEST((*dest));
@@ -790,6 +800,7 @@ uint32_t cpd_cpnd_info_node_find_add(NCS
                *cpnd_info_node = m_MMGR_ALLOC_CPD_CPND_INFO_NODE;
                if (*cpnd_info_node == NULL) {
                        LOG_CR("cpd cpnd info node memory allocation failed");
+                       TRACE_LEAVE();
                        return NCSCC_RC_FAILURE;
                }
                memset((*cpnd_info_node), '\0', sizeof(CPD_CPND_INFO_NODE));
@@ -802,11 +813,13 @@ uint32_t cpd_cpnd_info_node_find_add(NCS
 
                if (ncs_patricia_tree_add(cpnd_tree, 
&(*cpnd_info_node)->patnode) != NCSCC_RC_SUCCESS) {
                        LOG_ER("cpd cpnd info node failed for mds_dest 
%"PRIu64,*dest);
+                       TRACE_LEAVE();
                        return NCSCC_RC_FAILURE;
                }
                *add_flag = false;
        }
 
+       TRACE_LEAVE();
        return NCSCC_RC_SUCCESS;
 }
 
@@ -1129,7 +1142,7 @@ void cpd_node_ref_info_del(CPD_CKPT_INFO
 *
 * 
 
*******************************************************************************************************/
-uint32_t cpd_process_cpnd_del(CPD_CB *cb, MDS_DEST *cpnd_dest)
+uint32_t cpd_process_cpnd_del_on_standby(CPD_CB *cb, MDS_DEST *cpnd_dest)
 {
        CPD_CPND_INFO_NODE *cpnd_info = NULL;
        CPD_CKPT_REF_INFO *cref_info, *temp;
@@ -1266,11 +1279,14 @@ void cpd_clm_cluster_track_cb(const SaCl
                        if 
(notificationBuffer->notification[counter].clusterChange == SA_CLM_NODE_LEFT) {
                                if (cb->ha_state == SA_AMF_HA_ACTIVE) {
                                        node_id = 
notificationBuffer->notification[counter].clusterNode.nodeId;
+
+                                       
cpd_proc_update_user_info_when_node_down(cb, node_id);
+
                                        key = node_id;
                                        cpnd_info_node = (CPD_CPND_INFO_NODE *)
                                            
ncs_patricia_tree_get(&cb->cpnd_tree, (uint8_t *)&key);
                                        if (cpnd_info_node) {
-                                               cpd_process_cpnd_down(cb, 
&cpnd_info_node->cpnd_dest);
+                                               cpd_proc_node_down(cb, 
&cpnd_info_node->cpnd_dest);
                                        }
                                } else if (cb->ha_state == SA_AMF_HA_STANDBY) {
                                        node_id = 
notificationBuffer->notification[counter].clusterNode.nodeId;
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
@@ -237,6 +237,7 @@ static uint32_t cpd_evt_proc_ckpt_create
                ckpt_node->num_writers++;
 
        ckpt_node->num_users++;
+       cpd_proc_increase_node_user_info(ckpt_node, sinfo->dest, 
ckpt_create->ckpt_flags);
 
        cb->is_db_upd = true;
 
@@ -435,6 +436,8 @@ static uint32_t cpd_evt_proc_ckpt_usr_in
                        ckpt_node->num_readers++;
                if (evt->info.ckpt_usr_info.ckpt_flags & 
SA_CKPT_CHECKPOINT_WRITE)
                        ckpt_node->num_writers++;
+
+               cpd_proc_increase_node_user_info(ckpt_node, sinfo->dest, 
evt->info.ckpt_usr_info.ckpt_flags);
        }
        else if (evt->info.ckpt_usr_info.info_type == CPSV_USR_INFO_CKPT_OPEN) {
 
@@ -444,6 +447,8 @@ static uint32_t cpd_evt_proc_ckpt_usr_in
                        ckpt_node->num_readers++;
                if (evt->info.ckpt_usr_info.ckpt_flags & 
SA_CKPT_CHECKPOINT_WRITE)
                        ckpt_node->num_writers++;
+
+               cpd_proc_increase_node_user_info(ckpt_node, sinfo->dest, 
evt->info.ckpt_usr_info.ckpt_flags);
        }
        
        if (evt->info.ckpt_usr_info.info_type == CPSV_USR_INFO_CKPT_CLOSE_LAST) 
{
@@ -481,6 +486,8 @@ static uint32_t cpd_evt_proc_ckpt_usr_in
                        ckpt_node->num_readers--;
                if (evt->info.ckpt_usr_info.ckpt_flags & 
SA_CKPT_CHECKPOINT_WRITE)
                        ckpt_node->num_writers--;
+
+               cpd_proc_decrease_node_user_info(ckpt_node, sinfo->dest, 
evt->info.ckpt_usr_info.ckpt_flags);
        }
        else if (evt->info.ckpt_usr_info.info_type == CPSV_USR_INFO_CKPT_CLOSE) 
{
 
@@ -491,6 +498,7 @@ static uint32_t cpd_evt_proc_ckpt_usr_in
                if (evt->info.ckpt_usr_info.ckpt_flags & 
SA_CKPT_CHECKPOINT_WRITE)
                        ckpt_node->num_writers--;
 
+               cpd_proc_decrease_node_user_info(ckpt_node, sinfo->dest, 
evt->info.ckpt_usr_info.ckpt_flags);
        }
 
        cpd_a2s_ckpt_usr_info(cb, ckpt_node);
@@ -875,7 +883,7 @@ static uint32_t cpd_evt_proc_timer_expir
                if (cb->ha_state == SA_AMF_HA_ACTIVE) {
                        cpd_cpnd_info_node_get(&cb->cpnd_tree, 
&tmr_info->info.cpnd_dest, &node_info);
                        if (node_info) {
-                               (void)cpd_process_cpnd_down(cb, 
&tmr_info->info.cpnd_dest);
+                               (void)cpd_proc_node_down(cb, 
&tmr_info->info.cpnd_dest);
                        }
                }
                if (cb->ha_state == SA_AMF_HA_STANDBY) {
diff --git a/osaf/services/saf/cpsv/cpd/cpd_mbcsv.c 
b/osaf/services/saf/cpsv/cpd/cpd_mbcsv.c
--- a/osaf/services/saf/cpsv/cpd/cpd_mbcsv.c
+++ b/osaf/services/saf/cpsv/cpd/cpd_mbcsv.c
@@ -23,6 +23,8 @@
 ******************************************************************************/
 
 #include "cpd.h"
+static void cpd_mbcsv_enc_a2s_usr_info_2(NCS_UBAID *io_uba, 
CPD_A2S_CKPT_USR_INFO_2 *usr_info);
+static void cpd_mbcsv_dec_a2s_usr_info_2(NCS_UBAID *io_uba, 
CPD_A2S_CKPT_USR_INFO_2 *usr_info);
 
 
/**********************************************************************************************
  * Name                   : cpd_mbcsv_async_update
@@ -437,14 +439,9 @@ uint32_t cpd_mbcsv_enc_async_update(CPD_
                }
                break;
 
-       case CPD_A2S_MSG_CKPT_USR_INFO:
+       case CPD_A2S_MSG_CKPT_USR_INFO_2:
                cpd_msg = (CPD_MBCSV_MSG 
*)NCS_INT64_TO_PTR_CAST(arg->info.encode.io_reo_hdl);
-               rc = m_NCS_EDU_EXEC(&cb->edu_hdl, 
FUNC_NAME(CPD_A2S_CKPT_USR_INFO), &arg->info.encode.io_uba,
-                                   EDP_OP_TYPE_ENC, &cpd_msg->info.usr_info, 
&ederror);
-               if (rc != NCSCC_RC_SUCCESS) {
-                       TRACE_4("edu exec async userinfo failed ");
-                       rc = NCSCC_RC_FAILURE;
-               }
+               cpd_mbcsv_enc_a2s_usr_info_2(&arg->info.encode.io_uba, 
&cpd_msg->info.usr_info_2);
                break;
 
        case CPD_A2S_MSG_CKPT_DEST_DOWN:
@@ -907,6 +904,17 @@ uint32_t cpd_mbcsv_dec_async_update(CPD_
                }
                break;
 
+       case CPD_A2S_MSG_CKPT_USR_INFO_2:
+               cpd_msg->type = evt_type;
+               cpd_mbcsv_dec_a2s_usr_info_2(&arg->info.decode.i_uba, 
&cpd_msg->info.usr_info_2);
+               rc = cpd_process_sb_msg(cb, cpd_msg);
+
+               if (rc != NCSCC_RC_SUCCESS) {
+                       TRACE_4("cpd standby dest del evt failed");
+                       goto end;
+               }
+               break;
+
        case CPD_A2S_MSG_CKPT_DEST_DOWN:
                ckpt_dest_down = &cpd_msg->info.dest_down;
                rc = m_NCS_EDU_EXEC(&cb->edu_hdl, 
FUNC_NAME(CPSV_CKPT_DEST_INFO), &arg->info.decode.i_uba,
@@ -1154,3 +1162,67 @@ uint32_t cpd_mbcsv_decode_proc(NCS_MBCSV
        }
 
 }
+
+/**********************************************************************************************
+ * Name                   : cpd_mbcsv_enc_a2s_usr_info_2
+ *
+ * Description            : This function encodes the message 
CPD_A2S_MSG_CKPT_USR_INFO_2
+ *
+ * Return Values          : None
+ *
+ * Notes                  : None
+**********************************************************************************************/
+void cpd_mbcsv_enc_a2s_usr_info_2(NCS_UBAID *io_uba, CPD_A2S_CKPT_USR_INFO_2 
*usr_info)
+{
+       TRACE_ENTER();
+
+       osaf_encode_uint32(io_uba, usr_info->num_user);
+       osaf_encode_uint32(io_uba, usr_info->num_writer);
+       osaf_encode_uint32(io_uba, usr_info->num_reader);
+       osaf_encode_uint32(io_uba, usr_info->ckpt_on_scxb1);
+       osaf_encode_uint32(io_uba, usr_info->ckpt_on_scxb2);
+       osaf_encode_uint32(io_uba, usr_info->node_users_cnt);
+
+       int i = 0;
+       for (i = 0; i < usr_info->node_users_cnt; i++) {
+               osaf_encode_uint64(io_uba, usr_info->node_list[i].dest);
+               osaf_encode_uint32(io_uba, usr_info->node_list[i].num_users);
+               osaf_encode_uint32(io_uba, usr_info->node_list[i].num_writers);
+               osaf_encode_uint32(io_uba, usr_info->node_list[i].num_readers);
+       }
+
+       TRACE_LEAVE();
+}
+
+/**********************************************************************************************
+ * Name                   : cpd_mbcsv_dec_a2s_usr_info_2
+ *
+ * Description            : This function decodes the message 
CPD_A2S_MSG_CKPT_USR_INFO_2
+ *
+ *
+ * Return Values          : None
+ *
+ * Notes                  : None
+**********************************************************************************************/
+void cpd_mbcsv_dec_a2s_usr_info_2(NCS_UBAID *io_uba, CPD_A2S_CKPT_USR_INFO_2 
*usr_info)
+{
+       TRACE_ENTER();
+
+       osaf_decode_uint32(io_uba, &usr_info->num_user);
+       osaf_decode_uint32(io_uba, &usr_info->num_writer);
+       osaf_decode_uint32(io_uba, &usr_info->num_reader);
+       osaf_decode_uint32(io_uba, &usr_info->ckpt_on_scxb1);
+       osaf_decode_uint32(io_uba, &usr_info->ckpt_on_scxb2);
+       osaf_decode_uint32(io_uba, &usr_info->node_users_cnt);
+
+       int i = 0;
+       CPD_NODE_USER_INFO *node_list = malloc(usr_info->node_users_cnt * 
sizeof(CPD_NODE_USER_INFO));
+       for (i = 0; i < usr_info->node_users_cnt; i++) {
+               osaf_decode_uint64(io_uba, &node_list[i].dest);
+               osaf_decode_uint32(io_uba, &node_list[i].num_users);
+               osaf_decode_uint32(io_uba, &node_list[i].num_writers);
+               osaf_decode_uint32(io_uba, &node_list[i].num_readers);
+       }
+
+       TRACE_LEAVE();
+}
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
@@ -148,6 +148,8 @@ uint32_t cpd_ckpt_db_entry_update(CPD_CB
        CPD_REP_KEY_INFO key_info;
        bool noncoll_rep_on_payload = false;
 
+       TRACE_ENTER();
+
        memset(&ckpt_name, 0, sizeof(SaNameT));
        memset(&cluster_node, 0, sizeof(SaClmClusterNodeT));
        memset(&key_info, 0, sizeof(CPD_REP_KEY_INFO));
@@ -651,15 +653,15 @@ uint32_t cpd_process_ckpt_delete(CPD_CB 
 }
 
 /****************************************************************************
- * Name          : cpd_process_cpnd_down
+ * Name          : cpd_process_node_down
  *
- * Description   : This routine will process the CPND down event.
+ * Description   : This routine will process the node down event.
  *
  * Return Values : NCSCC_RC_SUCCESS/Error.
  *
  * Notes         : None.
  *****************************************************************************/
-uint32_t cpd_process_cpnd_down(CPD_CB *cb, MDS_DEST *cpnd_dest)
+uint32_t cpd_proc_node_down(CPD_CB *cb, MDS_DEST *cpnd_dest)
 {
        CPD_CPND_INFO_NODE *cpnd_info = NULL;
        CPD_CKPT_REF_INFO *cref_info;
@@ -1272,3 +1274,151 @@ void cpd_proc_broadcast_rdset_stop(SaCkp
        send_evt.info.cpnd.info.rdset.type = CPSV_CKPT_RDSET_STOP;
        cpd_mds_bcast_send(cb, &send_evt, NCSMDS_SVC_ID_CPND);
 }
+
+/******************************************************************************************
+ * Name          : cpd_proc_increase_node_ref_user_info
+ *
+ * Description   : This routine increases number of user, writer and reader 
for 
+ *                 the specified cpnd node reference
+ *
+ * Return Values : None 
+ *
+ * Notes         : None
+******************************************************************************************/
+void cpd_proc_increase_node_user_info(CPD_CKPT_INFO_NODE *ckpt_node, MDS_DEST 
cpnd_dest, 
+               SaCkptCheckpointOpenFlagsT open_flags)
+{
+       CPD_NODE_USER_INFO *node_user = ckpt_node->node_users;
+       CPD_NODE_USER_INFO *last_node_user = NULL;
+
+       TRACE_ENTER();
+
+       if (ckpt_node->node_users_cnt == 0) {
+               node_user = malloc(sizeof(CPD_NODE_USER_INFO));
+               memset(node_user, 0, sizeof(CPD_NODE_USER_INFO));
+               node_user->dest = cpnd_dest;
+
+               if (open_flags & SA_CKPT_CHECKPOINT_READ)
+                       node_user->num_readers++;
+               if (open_flags & SA_CKPT_CHECKPOINT_WRITE)
+                       node_user->num_writers++;
+
+               node_user->num_users++;
+               node_user->next = NULL;
+               ckpt_node->node_users = node_user;
+               ckpt_node->node_users_cnt++;
+               TRACE_LEAVE();
+               return;
+       }
+
+       while (node_user) {
+               if (node_user->dest == cpnd_dest) {
+                       if (open_flags & SA_CKPT_CHECKPOINT_READ)
+                               node_user->num_readers++;
+                       if (open_flags & SA_CKPT_CHECKPOINT_WRITE)
+                               node_user->num_writers++;
+
+                       node_user->num_users++;
+                       TRACE_LEAVE();
+                       return;
+               }
+               last_node_user = node_user;
+               node_user = node_user->next;
+       }
+
+       /* Add node user */
+       node_user = malloc(sizeof(CPD_NODE_USER_INFO));
+       memset(node_user, 0, sizeof(CPD_NODE_USER_INFO));
+       node_user->dest = cpnd_dest;
+
+       if (open_flags & SA_CKPT_CHECKPOINT_READ)
+               node_user->num_readers++;
+       if (open_flags & SA_CKPT_CHECKPOINT_WRITE)
+               node_user->num_writers++;
+
+       node_user->num_users++;
+       node_user->next = NULL;
+       last_node_user->next = node_user;
+       ckpt_node->node_users_cnt++;
+
+       TRACE_LEAVE();
+}
+
+/******************************************************************************************
+ * Name          : cpd_proc_decrease_node_ref_user_info
+ *
+ * Description   : This routine decreases number of user, writer and reader 
for 
+ *                 the specified cpnd node reference
+ *
+ * Return Values : None 
+ *
+ * Notes         : None
+******************************************************************************************/
+void cpd_proc_decrease_node_user_info(CPD_CKPT_INFO_NODE *ckpt_node, MDS_DEST 
cpnd_dest, 
+               SaCkptCheckpointOpenFlagsT open_flags)
+{
+       CPD_NODE_USER_INFO *node_user = ckpt_node->node_users;
+
+       TRACE_ENTER();
+
+       while (node_user) {
+               if (node_user->dest == cpnd_dest) {
+                       if (node_user->num_users == 0) {
+                               LOG_ER("cpd_proc_decrease_node_user_info failed 
- no user on node id 0x%X", 
+                                               
m_NCS_NODE_ID_FROM_MDS_DEST(cpnd_dest));
+                               TRACE_LEAVE();
+                               return;
+                       }
+
+                       if (open_flags & SA_CKPT_CHECKPOINT_READ)
+                               node_user->num_readers--;
+                       if (open_flags & SA_CKPT_CHECKPOINT_WRITE)
+                               node_user->num_writers--;
+
+                       node_user->num_users--;
+                       TRACE_LEAVE();
+                       return;
+               }
+               node_user = node_user->next;
+       }
+
+       TRACE_LEAVE();
+}
+
+/******************************************************************************************
+ * Name          : cpd_proc_update_user_info_when_node_down
+ *
+ * Description   : This routine updates number of user, writer and reader in 
case node down 
+ *
+ * Return Values : None 
+ *
+ * Notes         : None
+******************************************************************************************/
+void cpd_proc_update_user_info_when_node_down(CPD_CB *cb, NODE_ID node_id)
+{
+       CPD_CKPT_INFO_NODE *ckpt_node;
+       TRACE_ENTER();
+       
+       cpd_ckpt_node_getnext(&cb->ckpt_tree, NULL, &ckpt_node);
+       while (ckpt_node) {
+               SaCkptCheckpointHandleT prev_ckpt_hdl = ckpt_node->ckpt_id;
+               CPD_NODE_USER_INFO *node_user;
+
+               for (node_user = ckpt_node->node_users; node_user != NULL; 
node_user = node_user->next) {
+                       if (node_id == 
m_NCS_NODE_ID_FROM_MDS_DEST(node_user->dest)) {
+                               ckpt_node->num_users -= node_user->num_users;
+                               ckpt_node->num_writers -= 
node_user->num_writers;
+                               ckpt_node->num_readers -= 
node_user->num_readers;
+
+                               node_user->num_users = 0;
+                               node_user->num_writers = 0;
+                               node_user->num_readers = 0;
+                               break;
+                       }
+               }
+
+               cpd_ckpt_node_getnext(&cb->ckpt_tree, &prev_ckpt_hdl, 
&ckpt_node);
+       }
+
+       TRACE_LEAVE();
+}
diff --git a/osaf/services/saf/cpsv/cpd/cpd_red.c 
b/osaf/services/saf/cpsv/cpd/cpd_red.c
--- a/osaf/services/saf/cpsv/cpd/cpd_red.c
+++ b/osaf/services/saf/cpsv/cpd/cpd_red.c
@@ -301,18 +301,34 @@ void cpd_a2s_ckpt_dest_del(CPD_CB *cb, S
 void cpd_a2s_ckpt_usr_info(CPD_CB *cb, CPD_CKPT_INFO_NODE *ckpt_node)
 {
        CPD_MBCSV_MSG cpd_msg;
+       int count = 0;
        uint32_t rc = SA_AIS_OK;
        memset(&cpd_msg, '\0', sizeof(CPD_MBCSV_MSG));
 
        TRACE_ENTER();
-       cpd_msg.type = CPD_A2S_MSG_CKPT_USR_INFO;
-       cpd_msg.info.usr_info.ckpt_id = ckpt_node->ckpt_id;
-       cpd_msg.info.usr_info.num_user = ckpt_node->num_users;
-       cpd_msg.info.usr_info.num_writer = ckpt_node->num_writers;
-       cpd_msg.info.usr_info.num_reader = ckpt_node->num_readers;
-       cpd_msg.info.usr_info.num_sections = ckpt_node->num_sections;
-       cpd_msg.info.usr_info.ckpt_on_scxb1 = ckpt_node->ckpt_on_scxb1;
-       cpd_msg.info.usr_info.ckpt_on_scxb2 = ckpt_node->ckpt_on_scxb2;
+       cpd_msg.type = CPD_A2S_MSG_CKPT_USR_INFO_2;
+       cpd_msg.info.usr_info_2.ckpt_id = ckpt_node->ckpt_id;
+       cpd_msg.info.usr_info_2.num_user = ckpt_node->num_users;
+       cpd_msg.info.usr_info_2.num_writer = ckpt_node->num_writers;
+       cpd_msg.info.usr_info_2.num_reader = ckpt_node->num_readers;
+       cpd_msg.info.usr_info_2.num_sections = ckpt_node->num_sections;
+       cpd_msg.info.usr_info_2.ckpt_on_scxb1 = ckpt_node->ckpt_on_scxb1;
+       cpd_msg.info.usr_info_2.ckpt_on_scxb2 = ckpt_node->ckpt_on_scxb2;
+
+       if (ckpt_node->node_users_cnt) {
+               CPD_NODE_USER_INFO *node_user = ckpt_node->node_users;
+               cpd_msg.info.usr_info_2.node_users_cnt = 
ckpt_node->node_users_cnt;
+               cpd_msg.info.usr_info_2.node_list = 
malloc(ckpt_node->node_users_cnt * sizeof(CPD_NODE_USER_INFO));
+               memset(cpd_msg.info.usr_info_2.node_list, '\0', 
(sizeof(CPD_NODE_USER_INFO) * ckpt_node->node_users_cnt));
+
+               for (count = 0; count < ckpt_node->node_users_cnt; count++) {
+                       cpd_msg.info.usr_info_2.node_list[count].dest = 
node_user->dest;
+                       cpd_msg.info.usr_info_2.node_list[count].num_users = 
node_user->num_users;
+                       cpd_msg.info.usr_info_2.node_list[count].num_readers = 
node_user->num_readers;
+                       cpd_msg.info.usr_info_2.node_list[count].num_writers = 
node_user->num_writers;
+                       node_user = node_user->next;
+               }
+       }
 
        rc = cpd_mbcsv_async_update(cb, &cpd_msg);
        if (rc != SA_AIS_OK)
diff --git a/osaf/services/saf/cpsv/cpd/cpd_sbevt.c 
b/osaf/services/saf/cpsv/cpd/cpd_sbevt.c
--- a/osaf/services/saf/cpsv/cpd/cpd_sbevt.c
+++ b/osaf/services/saf/cpsv/cpd/cpd_sbevt.c
@@ -34,6 +34,7 @@ static uint32_t cpd_sb_proc_ckpt_rd_set(
 static uint32_t cpd_sb_proc_ckpt_dest_add(CPD_CB *cb, CPD_MBCSV_MSG *msg);
 static uint32_t cpd_sb_proc_ckpt_dest_del(CPD_CB *cb, CPD_MBCSV_MSG *msg);
 static uint32_t cpd_sb_proc_ckpt_usrinfo(CPD_CB *cb, CPD_MBCSV_MSG *msg);
+static uint32_t cpd_sb_proc_ckpt_usrinfo_2(CPD_CB *cb, CPD_MBCSV_MSG *msg);
 static uint32_t cpd_sb_proc_ckpt_dest_down(CPD_CB *cb, CPD_MBCSV_MSG *msg);
 
 const CPDS_EVT_HANDLER cpds_evt_dispatch_tbl[CPD_A2S_MSG_MAX_EVT - 
CPD_A2S_MSG_BASE] = {
@@ -45,6 +46,7 @@ const CPDS_EVT_HANDLER cpds_evt_dispatch
        cpd_sb_proc_ckpt_unlink,
        cpd_sb_proc_ckpt_usrinfo,
        cpd_sb_proc_ckpt_dest_down,
+       cpd_sb_proc_ckpt_usrinfo_2,
 };
 
 /***************************************************************************
@@ -280,7 +282,7 @@ uint32_t cpd_sb_proc_ckpt_dest_del(CPD_C
 
        /* IF CPND IS DOWN THEN CKPT_ID = 0 , DELETE THAT NODE INFO */
        if (msg->info.dest_del.ckpt_id == 0) {
-               cpd_process_cpnd_del(cb, &msg->info.dest_del.mds_dest);
+               cpd_process_cpnd_del_on_standby(cb, 
&msg->info.dest_del.mds_dest);
                return proc_rc;
        }
 
@@ -549,7 +551,7 @@ uint32_t cpd_sb_proc_ckpt_dest_add(CPD_C
 
/**********************************************************************************
 *  Name :  cpd_sb_proc_ckpt_usrinfo
 *
-*  Description : This routine will set the active replica flag of the 
checkpoint
+*  Description : This routine will update user information of the checkpoint
 *
 *  Arguments   : CPD_MBCSV_MSG - mbcsv message
                                                                                
                                              
@@ -581,6 +583,72 @@ uint32_t cpd_sb_proc_ckpt_usrinfo(CPD_CB
 }
 
 
/**********************************************************************************
+*  Name :  cpd_sb_proc_ckpt_usrinfo_2
+*
+*  Description : This routine will update user information of the checkpoint
+*                This version includes user information of each node
+*
+*  Arguments   : CPD_MBCSV_MSG - mbcsv message
+                                                                               
                                              
+*  Return Values : Success / Error
+                                                                               
                                              
+*  Notes : None
+                                                                               
                                              
+**********************************************************************************/
+uint32_t cpd_sb_proc_ckpt_usrinfo_2(CPD_CB *cb, CPD_MBCSV_MSG *msg)
+{
+       CPD_CKPT_INFO_NODE *ckpt_node = NULL;
+
+       TRACE_ENTER();
+       cpd_ckpt_node_get(&cb->ckpt_tree, &msg->info.dest_add.ckpt_id, 
&ckpt_node);
+       if (ckpt_node == NULL) {
+               TRACE_4("cpd ckpt info node get failed for ckpt_id: 
%llx",msg->info.dest_add.ckpt_id);
+               return NCSCC_RC_FAILURE;
+       }
+
+       ckpt_node->num_users = msg->info.usr_info_2.num_user;
+       ckpt_node->num_writers = msg->info.usr_info_2.num_writer;
+       ckpt_node->num_readers = msg->info.usr_info_2.num_reader;
+       ckpt_node->num_sections = msg->info.usr_info_2.num_sections;
+       ckpt_node->ckpt_on_scxb1 = msg->info.usr_info_2.ckpt_on_scxb1;
+       ckpt_node->ckpt_on_scxb2 = msg->info.usr_info_2.ckpt_on_scxb2;
+
+       /* Free the old node_users */
+       CPD_NODE_USER_INFO *node_user = ckpt_node->node_users;
+       CPD_NODE_USER_INFO *prev_node_user = NULL;
+
+       while (node_user) {
+               CPD_NODE_USER_INFO *prev_node_user = node_user;
+               node_user = node_user->next;
+               free(prev_node_user);
+       }
+       ckpt_node->node_users = NULL;
+
+       /* Update the node_users */
+       int i = 0;
+       for (i = 0; i < msg->info.usr_info_2.node_users_cnt; i++) {
+               CPD_NODE_USER_INFO *node_user = 
malloc(sizeof(CPD_NODE_USER_INFO));
+               if (prev_node_user != NULL)
+                       prev_node_user->next = node_user;
+
+               node_user->dest = msg->info.usr_info_2.node_list[i].dest; 
+               node_user->num_users = 
msg->info.usr_info_2.node_list[i].num_users;
+               node_user->num_readers = 
msg->info.usr_info_2.node_list[i].num_readers;
+               node_user->num_writers = 
msg->info.usr_info_2.node_list[i].num_writers;
+               node_user->next = NULL;
+               prev_node_user = node_user;
+
+               if (i == 0)
+                       ckpt_node->node_users = node_user;
+       }
+
+       free(msg->info.usr_info_2.node_list);
+
+       TRACE_LEAVE();
+       return NCSCC_RC_SUCCESS;
+}
+
+/**********************************************************************************
 *  Name :  cpd_sb_proc_ckpt_dest_down
 *
 *  Description : This routine will start the timer

------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=267308311&iu=/4140
_______________________________________________
Opensaf-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensaf-devel

Reply via email to