osaf/libs/common/cpsv/include/cpd_cb.h   |    2 +
 osaf/libs/common/cpsv/include/cpd_proc.h |    3 +
 osaf/libs/common/cpsv/include/cpd_red.h  |   14 ++
 osaf/libs/common/cpsv/include/cpsv_evt.h |    8 +
 osaf/services/saf/cpsv/cpd/cpd_db.c      |   14 ++-
 osaf/services/saf/cpsv/cpd/cpd_evt.c     |    8 +
 osaf/services/saf/cpsv/cpd/cpd_mbcsv.c   |   90 +++++++++++++++++-
 osaf/services/saf/cpsv/cpd/cpd_proc.c    |  148 +++++++++++++++++++++++++++++++
 osaf/services/saf/cpsv/cpd/cpd_red.c     |   32 +++++-
 osaf/services/saf/cpsv/cpd/cpd_sbevt.c   |   68 ++++++++++++++
 10 files changed, 370 insertions(+), 17 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
@@ -92,6 +92,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
@@ -108,5 +108,8 @@ 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);
 uint32_t cpd_proc_ckpt_update_post(CPD_CB *cb);
 #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
@@ -840,6 +840,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_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) {
@@ -1258,8 +1266,11 @@ void cpd_clm_cluster_track_cb(const SaCl
                /* 2. Check the HA_STATE */
                for (counter = 0; counter < notificationBuffer->numberOfItems; 
counter++) {
                        if 
(notificationBuffer->notification[counter].clusterChange == SA_CLM_NODE_LEFT) {
+                               node_id = 
notificationBuffer->notification[counter].clusterNode.nodeId;
+
+                               cpd_proc_update_user_info_when_node_down(cb, 
node_id);
+
                                if (cb->ha_state == SA_AMF_HA_ACTIVE) {
-                                       node_id = 
notificationBuffer->notification[counter].clusterNode.nodeId;
                                        key = node_id;
                                        cpnd_info_node = (CPD_CPND_INFO_NODE *)
                                            
ncs_patricia_tree_get(&cb->cpnd_tree, (uint8_t *)&key);
@@ -1267,7 +1278,6 @@ void cpd_clm_cluster_track_cb(const SaCl
                                                cpd_process_cpnd_down(cb, 
&cpnd_info_node->cpnd_dest);
                                        }
                                } else if (cb->ha_state == SA_AMF_HA_STANDBY) {
-                                       node_id = 
notificationBuffer->notification[counter].clusterNode.nodeId;
                                        key = node_id;
                                        cpnd_info_node = (CPD_CPND_INFO_NODE *)
                                            
ncs_patricia_tree_get(&cb->cpnd_tree, (uint8_t *)&key);
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
@@ -249,6 +249,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;
 
@@ -447,6 +448,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) {
 
@@ -456,6 +459,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) 
{
@@ -493,6 +498,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) 
{
 
@@ -503,6 +510,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);
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,71 @@ 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_uint64(io_uba, usr_info->ckpt_id);
+       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_uint64(io_uba, (uint64_t *) &usr_info->ckpt_id);
+       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);
+       }
+
+       usr_info->node_list = node_list;
+
+       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
@@ -1581,3 +1581,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,
 };
 
 /***************************************************************************
@@ -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

------------------------------------------------------------------------------
Find and fix application performance issues faster with Applications Manager
Applications Manager provides deep performance insights into multiple tiers of
your business applications. It resolves application problems quickly and
reduces your MTTR. Get your free trial!
https://ad.doubleclick.net/ddm/clk/302982198;130105516;z
_______________________________________________
Opensaf-devel mailing list
Opensaf-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/opensaf-devel

Reply via email to