osaf/libs/common/cpsv/include/cpsv_shm.h | 9 +- osaf/services/saf/cpsv/cpnd/cpnd_res.c | 565 ++++++++++++++++++++++++++++-- 2 files changed, 536 insertions(+), 38 deletions(-)
problem: In the case of CKPT osafckptnd increased 3,5Mb - 240 percent on all nodes CKPT_INFO size inscrease when support longDN lead to total size increase. solution: - From start, cpnd use small format shm. - Run time cpnd keep using small format shm until first longDN checkpoint is created. After that cpnd use big format shm. diff --git a/osaf/libs/common/cpsv/include/cpsv_shm.h b/osaf/libs/common/cpsv/include/cpsv_shm.h --- a/osaf/libs/common/cpsv/include/cpsv_shm.h +++ b/osaf/libs/common/cpsv/include/cpsv_shm.h @@ -27,7 +27,8 @@ #define SHM_NEXT -3 #define SHM_INIT -1 -#define CPSV_CPND_SHM_VERSION 1 +#define CPSV_CPND_SHM_VERSION_SHORT_DN 0 +#define CPSV_CPND_SHM_VERSION_LONG_DN 1 typedef struct cpsv_ckpt_hdr { SaCkptCheckpointHandleT ckpt_id; /* Index for identifying the checkpoint */ @@ -134,4 +135,10 @@ typedef enum cpnd_type_info { CPND_CKPT_INFO } CPND_TYPE_INFO; +#define cpsv_cpnd_shm_size(x) x == CPSV_CPND_SHM_VERSION_LONG_DN ? \ + sizeof(CLIENT_HDR) + (MAX_CLIENTS * sizeof(CLIENT_INFO)) + \ + sizeof(CKPT_HDR) + (MAX_CKPTS * sizeof(CKPT_INFO)) : \ + sizeof(CLIENT_HDR) + (MAX_CLIENTS * sizeof(CLIENT_INFO)) + \ + sizeof(CKPT_HDR) + (MAX_CKPTS * sizeof(CKPT_INFO_V0)) \ + #endif diff --git a/osaf/services/saf/cpsv/cpnd/cpnd_res.c b/osaf/services/saf/cpsv/cpnd/cpnd_res.c --- a/osaf/services/saf/cpsv/cpnd/cpnd_res.c +++ b/osaf/services/saf/cpsv/cpnd/cpnd_res.c @@ -44,20 +44,34 @@ #define m_CPND_CKPTINFO_UPDATE(addr,ckpt_info,offset) memcpy(addr+offset,&ckpt_info,sizeof(CKPT_INFO)) +#define m_CPND_CKPTINFO_V0_UPDATE(addr,ckpt_info,offset) memcpy(addr+offset,&ckpt_info,sizeof(CKPT_INFO_V0)) + #define m_CPND_CKPTHDR_UPDATE(ckpt_hdr,offset) memcpy(offset,&ckpt_hdr,sizeof(CKPT_HDR)) +void *cpnd_restart_shm(NCS_OS_POSIX_SHM_REQ_INFO *cpnd_open_req, CPND_CB *cb, SaClmNodeIdT nodeid); +uint32_t cpnd_update_ckpt_with_clienthdl_v1(CPND_CB *cb, CPND_CKPT_NODE *cp_node, SaCkptHandleT client_hdl); +uint32_t cpnd_update_ckpt_with_clienthdl_v0(CPND_CB *cb, CPND_CKPT_NODE *cp_node, SaCkptHandleT client_hdl); +uint32_t cpnd_write_ckpt_info_v1(CPND_CB *cb, CPND_CKPT_NODE *cp_node, int32_t offset, SaCkptHandleT client_hdl); +uint32_t cpnd_write_ckpt_info_v0(CPND_CB *cb, CPND_CKPT_NODE *cp_node, int32_t offset, SaCkptHandleT client_hdl); + static uint32_t cpnd_res_ckpt_sec_add(CPND_CKPT_SECTION_INFO *pSecPtr, CPND_CKPT_NODE *cp_node); static bool cpnd_find_exact_ckptinfo(CPND_CB *cb, CKPT_INFO *ckpt_info, uint32_t bitmap_offset, uint32_t *offset, uint32_t *prev_offset); +static bool cpnd_find_exact_ckptinfo_v0(CPND_CB *cb, CKPT_INFO_V0 *ckpt_info, uint32_t bitmap_offset, + uint32_t *offset, uint32_t *prev_offset); static void cpnd_clear_ckpt_info(CPND_CB *cb, CPND_CKPT_NODE *cp_node, uint32_t curr_offset, uint32_t prev_offset); static uint32_t cpnd_restore_client_info(CPND_CB *cb, uint8_t *cli_addr); static uint32_t cpnd_restore_ckpt_info_v1(CPND_CB *cb, uint8_t *ckpt_addr, SaClmNodeIdT nodeid); static uint32_t cpnd_restore_ckpt_info_v0(CPND_CB *cb, uint8_t *ckpt_addr, SaClmNodeIdT nodeid); +static void cpnd_restart_client_reset_v1(CPND_CB *cb, CPND_CKPT_NODE *cp_node, CPND_CKPT_CLIENT_NODE *cl_node); +static void cpnd_restart_client_reset_v0(CPND_CB *cb, CPND_CKPT_NODE *cp_node, CPND_CKPT_CLIENT_NODE *cl_node); static void cpnd_destroy_shm_cpnd_cp_info(NCS_OS_POSIX_SHM_REQ_OPEN_INFO *open_req); static void *cpnd_create_shm_cpnd_cp_info(NCS_OS_POSIX_SHM_REQ_INFO *req_info); static void cpnd_update_shm_cpnd_cp_info(CPND_CB *cb); static void cpnd_convert_cp_info_v0(CKPT_INFO_V0 *cp_info_v0, CKPT_INFO *cp_info); +static CPND_SHM_VERSION cpnd_shm_version; + /******************************************************************************* * * Name : cpnd_client_extract_bits * @@ -296,12 +310,21 @@ void cpnd_restart_update_timer(CPND_CB * CKPT_INFO ckpt_info; memset(&ckpt_info, '\0', sizeof(CKPT_INFO)); - if (cp_node->offset >= 0) { + if (cp_node->offset < 0) { + return; + } + if (cpnd_shm_version.shm_version == CPSV_CPND_SHM_VERSION_LONG_DN) { m_CPND_CKPTINFO_READ(ckpt_info, (char *)cb->shm_addr.ckpt_addr + sizeof(CKPT_HDR), cp_node->offset * sizeof(CKPT_INFO)); ckpt_info.close_time = closetime; m_CPND_CKPTINFO_UPDATE((char *)cb->shm_addr.ckpt_addr + sizeof(CKPT_HDR), ckpt_info, cp_node->offset * sizeof(CKPT_INFO)); + } else { + m_CPND_CKPTINFO_V0_READ(ckpt_info, (char *)cb->shm_addr.ckpt_addr + sizeof(CKPT_HDR), + cp_node->offset * sizeof(CKPT_INFO_V0)); + ((CKPT_INFO_V0 *)(&ckpt_info))->close_time = closetime; + m_CPND_CKPTINFO_V0_UPDATE((char *)cb->shm_addr.ckpt_addr + sizeof(CKPT_HDR), + ckpt_info, cp_node->offset * sizeof(CKPT_INFO_V0)); } return; } @@ -321,25 +344,52 @@ void cpnd_restart_update_timer(CPND_CB * shared memory and update the shared memory as and when the database gets updated * TBD : TO CHECK THE ERROR CONDITIONS ****************************************************************************************************/ +void *cpnd_restart_shm_create(NCS_OS_POSIX_SHM_REQ_INFO *cpnd_open_req, CPND_CB *cb, SaClmNodeIdT nodeid) +{ + TRACE_ENTER(); -void *cpnd_restart_shm_create(NCS_OS_POSIX_SHM_REQ_INFO *cpnd_open_req, CPND_CB *cb, SaClmNodeIdT nodeid) + /* Initializing shared memory version */ + memset(&cpnd_shm_version, '\0', sizeof(cpnd_shm_version)); + /* From start always init shm for short DN version */ + cpnd_shm_version.shm_version = CPSV_CPND_SHM_VERSION_SHORT_DN; + + void *ret = cpnd_restart_shm(cpnd_open_req, cb, nodeid); + + TRACE_LEAVE(); + + return ret; +} + +/**************************************************************************************************** + * Name : cpnd_restart_shm + * + * Description : To create the shared memory for CPND restart + * + * Arguments : NCS_OS_POSIX_SHM_REQ_INFO *open_req - Shared Memory Request Info pointer + * CPND_CB *cb - CPND CB pointer + * + * Return Values : void * - Returns the starting address of the shared memory + * Notes : If the shared memory is present - CPND has restarted , so CPND will update its database by + reading the information from the shared memory + If the shared memory is not present - CPND is coming up for the first time , so create a new + shared memory and update the shared memory as and when the database gets updated + * TBD : TO CHECK THE ERROR CONDITIONS +****************************************************************************************************/ +void *cpnd_restart_shm(NCS_OS_POSIX_SHM_REQ_INFO *cpnd_open_req, CPND_CB *cb, SaClmNodeIdT nodeid) { uint32_t rc = NCSCC_RC_SUCCESS; char *buf = NULL, *buffer = NULL; uint8_t size = 0, total_length; GBL_SHM_PTR gbl_shm_addr = {0, 0, 0, 0, 0}; - CPND_SHM_VERSION cpnd_shm_version; TRACE_ENTER(); - /* Initializing shared memory version */ - memset(&cpnd_shm_version, '\0', sizeof(cpnd_shm_version)); - cpnd_shm_version.shm_version = CPSV_CPND_SHM_VERSION; size = strlen("CPND_CHECKPOINT_INFO"); total_length = size + sizeof(nodeid) + 5; buffer = m_MMGR_ALLOC_CPND_DEFAULT(total_length); if (buffer == NULL) { LOG_ER("cpnd default memory allocation failed in cpnd_open in resart shm create"); + TRACE_LEAVE(); return NULL; } cb->cpnd_res_shm_name = (uint8_t*)buffer; @@ -349,9 +399,7 @@ void *cpnd_restart_shm_create(NCS_OS_POS /* 1. FIRST TRYING TO OPEN IN RDWR MODE */ cpnd_open_req->type = NCS_OS_POSIX_SHM_REQ_OPEN; - cpnd_open_req->info.open.i_size = - sizeof(CLIENT_HDR) + (MAX_CLIENTS * sizeof(CLIENT_INFO)) + sizeof(CKPT_HDR) + - (MAX_CKPTS * sizeof(CKPT_INFO)); + cpnd_open_req->info.open.i_size = cpsv_cpnd_shm_size(cpnd_shm_version.shm_version); if (cb->shm_alloc_guaranteed == true) cpnd_open_req->info.open.ensures_space = true; else @@ -370,12 +418,14 @@ void *cpnd_restart_shm_create(NCS_OS_POS if (NULL == cpnd_create_shm_cpnd_cp_info(cpnd_open_req)) { LOG_ER("cpnd open request fail for RDWR mode %s",buf); m_MMGR_FREE_CPND_DEFAULT(buffer); + TRACE_LEAVE(); return NULL; } cb->cpnd_first_time = true; TRACE_1("cpnd new shm create request success"); + TRACE_LEAVE(); return cpnd_open_req->info.open.o_addr; } @@ -390,7 +440,7 @@ void *cpnd_restart_shm_create(NCS_OS_POS /* Already the shared memory exists */ else { - CPND_SHM_VERSION shm_version; + CPND_SHM_VERSION shm_version; // Shm version of existing memory TRACE_1("cpnd restart already shared memory exits"); gbl_shm_addr.cli_addr = cpnd_open_req->info.open.o_addr + sizeof(cpnd_shm_version); /* Starting address of the shared memory */ gbl_shm_addr.ckpt_addr = (void *)((char *)gbl_shm_addr.cli_addr + sizeof(CLIENT_HDR) + @@ -403,10 +453,15 @@ void *cpnd_restart_shm_create(NCS_OS_POS TRACE("CPND IS RESTARTING WITH VERSION %d", shm_version.shm_version); cpnd_restore_client_info(cb, gbl_shm_addr.cli_addr); switch (shm_version.shm_version) { - case 0: + case CPSV_CPND_SHM_VERSION_SHORT_DN: { cpnd_restore_ckpt_info_v0(cb, gbl_shm_addr.ckpt_addr, nodeid); + /* Keep v0 format if both have same version */ + if (cpnd_shm_version.shm_version == shm_version.shm_version) { + break; + } + /* Destroy the CPND_CHECKPOINT_INFO version 0 */ cpnd_destroy_shm_cpnd_cp_info(&cpnd_open_req->info.open); @@ -414,6 +469,7 @@ void *cpnd_restart_shm_create(NCS_OS_POS if (NULL == cpnd_create_shm_cpnd_cp_info(cpnd_open_req)) { LOG_ER("cpnd open request fail for RDWR mode %s",buf); m_MMGR_FREE_CPND_DEFAULT(buffer); + TRACE_LEAVE(); return NULL; } @@ -426,7 +482,8 @@ void *cpnd_restart_shm_create(NCS_OS_POS break; } - case 1: + case CPSV_CPND_SHM_VERSION_LONG_DN: + shm_version.shm_version = CPSV_CPND_SHM_VERSION_LONG_DN; cpnd_restore_ckpt_info_v1(cb, gbl_shm_addr.ckpt_addr, nodeid); break; default: @@ -505,8 +562,13 @@ int32_t cpnd_find_free_loc(CPND_CB *cb, } read_req.type = NCS_OS_POSIX_SHM_REQ_READ; read_req.info.read.i_addr = (void *)((char *)cb->shm_addr.ckpt_addr + sizeof(CKPT_HDR)); - read_req.info.read.i_read_size = sizeof(CKPT_INFO); - read_req.info.read.i_offset = counter * sizeof(CKPT_INFO); + if (cpnd_shm_version.shm_version == CPSV_CPND_SHM_VERSION_LONG_DN) { + read_req.info.read.i_read_size = sizeof(CKPT_INFO); + read_req.info.read.i_offset = counter * sizeof(CKPT_INFO); + } else { + read_req.info.read.i_read_size = sizeof(CKPT_INFO_V0); + read_req.info.read.i_offset = counter * sizeof(CKPT_INFO_V0); + } read_req.info.read.i_to_buff = (CKPT_INFO *)&ckpt_info; rc = ncs_os_posix_shm(&read_req); if (rc != NCSCC_RC_SUCCESS) { @@ -515,7 +577,8 @@ int32_t cpnd_find_free_loc(CPND_CB *cb, return -2; } - if (1 == ((CKPT_INFO *)read_req.info.read.i_to_buff)->is_valid) { + if ((cpnd_shm_version.shm_version == CPSV_CPND_SHM_VERSION_LONG_DN && 1 == ckpt_info.is_valid) || + (cpnd_shm_version.shm_version == CPSV_CPND_SHM_VERSION_SHORT_DN && 1 == ((CKPT_INFO_V0 *)(&ckpt_info))->is_valid)) { counter++; memset(&ckpt_info, '\0', sizeof(CKPT_INFO)); if (counter == MAX_CKPTS) { @@ -738,25 +801,95 @@ bool cpnd_find_exact_ckptinfo(CPND_CB *c } +/************************************************************************************************ + * Name : cpnd_find_exact_ckptinfo_v0 + * + * Description : find if the checkpoint info v0 exists in the shared memory , + then findout the matching bm_offset offset value + * + * Arguments : CPND_CKPT_NODE - ckpt node + * + * Return Values : The offset( if same bm_pffset present) /prev offset( if same bm_offset is not present ) + where this checkpoint info is present + * +**************************************************************************************************/ + +bool cpnd_find_exact_ckptinfo_v0(CPND_CB *cb, CKPT_INFO_V0 *ckpt_info, uint32_t bitmap_offset, uint32_t *offset, + uint32_t *prev_offset) +{ + int32_t next; + CKPT_INFO_V0 prev_ckpt_info; + uint64_t i_offset; + bool found = false; + + TRACE_ENTER(); + memset(&prev_ckpt_info, 0, sizeof(CKPT_INFO_V0)); + memcpy(&prev_ckpt_info, ckpt_info, sizeof(CKPT_INFO_V0)); + next = ckpt_info->offset; + *prev_offset = prev_ckpt_info.offset; + + while (next >= 0) { + memset(&prev_ckpt_info, 0, sizeof(CKPT_INFO_V0)); + if ((next * sizeof(CKPT_INFO_V0)) > UINTMAX_MAX) { + LOG_ER("cpnd exact_ckptinf failed,exceeded the write limits(UINT64_MAX) "); + } + i_offset = next * sizeof(CKPT_INFO_V0); + m_CPND_CKPTINFO_V0_READ(prev_ckpt_info, (char *)cb->shm_addr.ckpt_addr + sizeof(CKPT_HDR), i_offset); + if (prev_ckpt_info.bm_offset == bitmap_offset) { + found = true; + *offset = prev_ckpt_info.offset; + break; + } + next = prev_ckpt_info.next; + *prev_offset = prev_ckpt_info.offset; + } + TRACE_LEAVE(); + return found; + +} + /******************************************************************************************************* * Name : cpnd_update_ckpt_with_clienthdl * * Description : To write the checkpoint data, which already exists in the shared memory, here we just change the bitmap * - * Arguments : CPND_CKPT_NODE - ckpt node , offset - to update the respective ckpt , client_hdl + * Arguments : CPND_CKPT_NODE - ckpt node , offset - to update the respective ckpt , client_hdl * * Return Values : Success / Error - * + * * Notes : None ******************************************************************************************************/ uint32_t cpnd_update_ckpt_with_clienthdl(CPND_CB *cb, CPND_CKPT_NODE *cp_node, SaCkptHandleT client_hdl) { + uint32_t rc = NCSCC_RC_SUCCESS; + if (cpnd_shm_version.shm_version == CPSV_CPND_SHM_VERSION_LONG_DN) { + rc = cpnd_update_ckpt_with_clienthdl_v1(cb, cp_node, client_hdl); + } else { + rc = cpnd_update_ckpt_with_clienthdl_v0(cb, cp_node, client_hdl); + } + return rc; +} + +/******************************************************************************************************* + * Name : cpnd_update_ckpt_with_clienthdl_v1 + * + * Description : To write the checkpoint data, which already exists in the shared memory, here we just change the bitmap + * + * Arguments : CPND_CKPT_NODE - ckpt node , offset - to update the respective ckpt , client_hdl + * + * Return Values : Success / Error + * + * Notes : None + ******************************************************************************************************/ + +uint32_t cpnd_update_ckpt_with_clienthdl_v1(CPND_CB *cb, CPND_CKPT_NODE *cp_node, SaCkptHandleT client_hdl) +{ CKPT_INFO ckpt_info, prev_ckpt_info, new_ckpt_info; uint32_t bitmap_offset = 0, bitmap_value = 0, prev_offset, offset, rc = NCSCC_RC_SUCCESS; bool found = false; - uint64_t i_offset; - + uint64_t i_offset; + TRACE_ENTER(); memset(&ckpt_info, '\0', sizeof(CKPT_INFO)); memset(&prev_ckpt_info, '\0', sizeof(CKPT_INFO)); @@ -837,20 +970,139 @@ uint32_t cpnd_update_ckpt_with_clienthdl return rc; } -/************************************************************************************************************ +/******************************************************************************************************* + * Name : cpnd_update_ckpt_with_clienthdl_v0 + * + * Description : To write the checkpoint data, which already exists in the shared memory, here we just change the bitmap + * + * Arguments : CPND_CKPT_NODE - ckpt node , offset - to update the respective ckpt , client_hdl + * + * Return Values : Success / Error + * + * Notes : None + ******************************************************************************************************/ + +uint32_t cpnd_update_ckpt_with_clienthdl_v0(CPND_CB *cb, CPND_CKPT_NODE *cp_node, SaCkptHandleT client_hdl) +{ + CKPT_INFO_V0 ckpt_info, prev_ckpt_info, new_ckpt_info; + uint32_t bitmap_offset = 0, bitmap_value = 0, prev_offset, offset, rc = NCSCC_RC_SUCCESS; + bool found = false; + uint64_t i_offset; + + TRACE_ENTER(); + memset(&ckpt_info, '\0', sizeof(CKPT_INFO_V0)); + memset(&prev_ckpt_info, '\0', sizeof(CKPT_INFO_V0)); + memset(&new_ckpt_info, '\0', sizeof(CKPT_INFO_V0)); + + /* Read the starting shared memory entry for this cp_node */ + prev_offset = cp_node->offset; + i_offset = prev_offset * sizeof(CKPT_INFO_V0); + m_CPND_CKPTINFO_V0_READ(ckpt_info, (char *)cb->shm_addr.ckpt_addr + sizeof(CKPT_HDR), i_offset); + + /* Findout the bitmap offset and bitmap value for the input client handle */ + bitmap_offset = client_hdl / 32; + + bitmap_value = cpnd_client_bitmap_set(client_hdl % 32); + + /*findout the ckpt_info with the exact bitmap_offset or findout prev ckpt_info if exact one not found */ + found = cpnd_find_exact_ckptinfo_v0(cb, &ckpt_info, bitmap_offset, &offset, &prev_offset); + + if (!found) { + CKPT_HDR ckpt_hdr; + uint32_t no_ckpts = 0; + /* Update the Next Location in the previous prev_ckpt_info.next as we have to find a new ckpt_info */ + if ((prev_offset * sizeof(CKPT_INFO_V0)) > UINTMAX_MAX) { + LOG_ER("cpnd update clienthdl failed,exceeded the write limits(UINT64_MAX) "); + } + i_offset = prev_offset * sizeof(CKPT_INFO_V0); + m_CPND_CKPTINFO_V0_READ(prev_ckpt_info, (char *)cb->shm_addr.ckpt_addr + sizeof(CKPT_HDR), i_offset); + + prev_ckpt_info.next = cpnd_find_free_loc(cb, CPND_CKPT_INFO); + if (prev_ckpt_info.next == -1) { + TRACE_4("cpnd client free block failed "); + TRACE_LEAVE(); + return NCSCC_RC_FAILURE; + } + if (prev_ckpt_info.next == -2) { + TRACE_LEAVE(); + return NCSCC_RC_FAILURE; + /* SHARED MEMORY READ ERROR */ + } + + /* Update the Header with incremented number of ckpt_info 's */ + memset(&ckpt_hdr, '\0', sizeof(CKPT_HDR)); + m_CPND_CKPTHDR_READ(ckpt_hdr, (char *)cb->shm_addr.ckpt_addr, 0); + no_ckpts = ++(ckpt_hdr.num_ckpts); + + if (no_ckpts >= MAX_CKPTS) + { + TRACE_LEAVE(); + return NCSCC_RC_FAILURE; + } + + /* write the checkpoint info (number of ckpts)in the header */ + cpnd_ckpt_write_header(cb, no_ckpts); + + m_CPND_CKPTINFO_V0_UPDATE((char *)cb->shm_addr.ckpt_addr + sizeof(CKPT_HDR), prev_ckpt_info, i_offset); + + /* Allocate New ckpt_info information */ + offset = prev_ckpt_info.next; + /* bitmap_value = cpnd_client_bitmap_set((client_hdl%32)+1); */ + memcpy(&new_ckpt_info, &prev_ckpt_info, sizeof(CKPT_INFO_V0)); + new_ckpt_info.offset = offset; + new_ckpt_info.client_bitmap = bitmap_value; + new_ckpt_info.bm_offset = bitmap_offset; + new_ckpt_info.is_valid = 1; + new_ckpt_info.is_first = false; + new_ckpt_info.next = SHM_NEXT; + + i_offset = offset * sizeof(CKPT_INFO_V0); + m_CPND_CKPTINFO_V0_UPDATE((char *)cb->shm_addr.ckpt_addr + sizeof(CKPT_HDR), new_ckpt_info, i_offset); + + } else { + i_offset = offset * sizeof(CKPT_INFO_V0); + m_CPND_CKPTINFO_V0_READ(prev_ckpt_info, (char *)cb->shm_addr.ckpt_addr + sizeof(CKPT_HDR), i_offset); + prev_ckpt_info.client_bitmap = prev_ckpt_info.client_bitmap | bitmap_value; + m_CPND_CKPTINFO_V0_UPDATE((char *)cb->shm_addr.ckpt_addr + sizeof(CKPT_HDR), prev_ckpt_info, i_offset); + } + TRACE_LEAVE(); + return rc; +}/************************************************************************************************************ * Name : cpnd_write_ckpt_info * - * Description : To write checkpoint info + * Description : To write checkpoint info * * Arguments : CPND_CKPT_NODE - ckpt node , offset - to write to corresponding ckpt , client_hdl * * Return Values : Success / Error * - * Notes : Check if the offset is less than 31 , if so then update the information in the corresponding offset + * Notes : Check if the offset is less than 31 , if so then update the information in the corresponding offset else find the next free location and there update the checkpoint information ************************************************************************************************************/ +uint32_t cpnd_write_ckpt_info(CPND_CB *cb, CPND_CKPT_NODE *cp_node, int32_t offset, SaCkptHandleT client_hdl) +{ + uint32_t rc = NCSCC_RC_SUCCESS; + if (cpnd_shm_version.shm_version == CPSV_CPND_SHM_VERSION_LONG_DN) { + rc = cpnd_write_ckpt_info_v1(cb, cp_node, offset, client_hdl); + } else { + rc = cpnd_write_ckpt_info_v0(cb, cp_node, offset, client_hdl); + } + return rc; +} -uint32_t cpnd_write_ckpt_info(CPND_CB *cb, CPND_CKPT_NODE *cp_node, int32_t offset, SaCkptHandleT client_hdl) +/************************************************************************************************************ + * Name : cpnd_write_ckpt_info_v1 + * + * Description : To write checkpoint info + * + * Arguments : CPND_CKPT_NODE - ckpt node , offset - to write to corresponding ckpt , client_hdl + * + * Return Values : Success / Error + * + * Notes : Check if the offset is less than 31 , if so then update the information in the corresponding offset + else find the next free location and there update the checkpoint information + ************************************************************************************************************/ +uint32_t cpnd_write_ckpt_info_v1(CPND_CB *cb, CPND_CKPT_NODE *cp_node, int32_t offset, SaCkptHandleT client_hdl) { CKPT_INFO ckpt_info; uint32_t rc = NCSCC_RC_SUCCESS; @@ -885,6 +1137,54 @@ uint32_t cpnd_write_ckpt_info(CPND_CB *c } +/************************************************************************************************************ + * Name : cpnd_write_ckpt_info_v0 + * + * Description : To write checkpoint info v0 + * + * Arguments : CPND_CKPT_NODE - ckpt node , offset - to write to corresponding ckpt , client_hdl + * + * Return Values : Success / Error + * + * Notes : Check if the offset is less than 31 , if so then update the information in the corresponding offset + else find the next free location and there update the checkpoint information + ************************************************************************************************************/ + +uint32_t cpnd_write_ckpt_info_v0(CPND_CB *cb, CPND_CKPT_NODE *cp_node, int32_t offset, SaCkptHandleT client_hdl) +{ + CKPT_INFO_V0 ckpt_info; + uint32_t rc = NCSCC_RC_SUCCESS; + uint64_t i_offset; + + TRACE_ENTER(); + memset(&ckpt_info, 0, sizeof(CKPT_INFO_V0)); + osaf_extended_name_lend(cp_node->ckpt_name, &ckpt_info.ckpt_name); + ckpt_info.ckpt_id = cp_node->ckpt_id; + ckpt_info.maxSections = cp_node->create_attrib.maxSections; + ckpt_info.maxSecSize = cp_node->create_attrib.maxSectionSize; + ckpt_info.cpnd_rep_create = cp_node->cpnd_rep_create; + ckpt_info.offset = offset; + ckpt_info.node_id = cb->nodeid; + ckpt_info.is_first = true; + + if (client_hdl) { + ckpt_info.bm_offset = client_hdl / 32; + ckpt_info.client_bitmap = cpnd_client_bitmap_set(client_hdl % 32); + } + ckpt_info.is_valid = 1; + ckpt_info.next = SHM_NEXT; + + if ((offset * sizeof(CKPT_INFO_V0)) > UINTMAX_MAX) { + LOG_ER("cpnd write ckpt info failed,exceeded the write limits(UINT64_MAX) "); + } + i_offset = offset * sizeof(CKPT_INFO_V0); + m_CPND_CKPTINFO_UPDATE((char *)cb->shm_addr.ckpt_addr + sizeof(CKPT_HDR), ckpt_info, i_offset); + + TRACE_LEAVE2("cpnd ckpt info write success ckpt_id:%llx",cp_node->ckpt_id); + return rc; + +} + /******************************************************************** * Name : cpnd_restart_shm_client_update * @@ -1062,11 +1362,18 @@ uint32_t cpnd_restart_shm_ckpt_free(CPND if (((cp_node->offset) * sizeof(CKPT_INFO)) > UINTMAX_MAX) { LOG_ER("cpnd ckpt free failed,exceeded the write limits(UINT64_MAX) "); } - i_offset = (cp_node->offset) * sizeof(CKPT_INFO); + if (cpnd_shm_version.shm_version == CPSV_CPND_SHM_VERSION_LONG_DN) { + i_offset = (cp_node->offset) * sizeof(CKPT_INFO); + + /*Update the prev & curr shared memory segments with the new data */ + m_CPND_CKPTINFO_UPDATE((char *)cb->shm_addr.ckpt_addr + sizeof(CKPT_HDR), ckpt_info, i_offset); + } else { + i_offset = (cp_node->offset) * sizeof(CKPT_INFO_V0); + + /*Update the prev & curr shared memory segments with the new data */ + m_CPND_CKPTINFO_V0_UPDATE((char *)cb->shm_addr.ckpt_addr + sizeof(CKPT_HDR), ckpt_info, i_offset); + } cp_node->offset = SHM_INIT; - - /*Update the prev & curr shared memory segments with the new data */ - m_CPND_CKPTINFO_UPDATE((char *)cb->shm_addr.ckpt_addr + sizeof(CKPT_HDR), ckpt_info, i_offset); TRACE_LEAVE(); @@ -1088,12 +1395,21 @@ void cpnd_restart_ckpt_name_length_reset CKPT_INFO ckpt_info; memset(&ckpt_info, '\0', sizeof(CKPT_INFO)); - if (cp_node->offset >= 0) { + if (cp_node->offset < 0) { + return; + } + if (cpnd_shm_version.shm_version == CPSV_CPND_SHM_VERSION_LONG_DN) { m_CPND_CKPTINFO_READ(ckpt_info, (char *)cb->shm_addr.ckpt_addr + sizeof(CKPT_HDR), cp_node->offset * sizeof(CKPT_INFO)); ckpt_info.is_unlink = true; m_CPND_CKPTINFO_UPDATE((char *)cb->shm_addr.ckpt_addr + sizeof(CKPT_HDR), ckpt_info, cp_node->offset * sizeof(CKPT_INFO)); + } else { + m_CPND_CKPTINFO_V0_READ(ckpt_info, (char *)cb->shm_addr.ckpt_addr + sizeof(CKPT_HDR), + cp_node->offset * sizeof(CKPT_INFO_V0)); + ((CKPT_INFO_V0 *)(&ckpt_info))->is_unlink = true; + m_CPND_CKPTINFO_V0_UPDATE((char *)cb->shm_addr.ckpt_addr + sizeof(CKPT_HDR), ckpt_info, + cp_node->offset * sizeof(CKPT_INFO_V0)); } return; } @@ -1112,12 +1428,21 @@ void cpnd_restart_set_close_flag(CPND_CB CKPT_INFO ckpt_info; memset(&ckpt_info, '\0', sizeof(CKPT_INFO)); - if (cp_node->offset >= 0) { + if (cp_node->offset < 0) { + return; + } + if (cpnd_shm_version.shm_version == CPSV_CPND_SHM_VERSION_LONG_DN) { m_CPND_CKPTINFO_READ(ckpt_info, (char *)cb->shm_addr.ckpt_addr + sizeof(CKPT_HDR), cp_node->offset * sizeof(CKPT_INFO)); ckpt_info.is_close = true; m_CPND_CKPTINFO_UPDATE((char *)cb->shm_addr.ckpt_addr + sizeof(CKPT_HDR), ckpt_info, cp_node->offset * sizeof(CKPT_INFO)); + } else { + m_CPND_CKPTINFO_V0_READ(ckpt_info, (char *)cb->shm_addr.ckpt_addr + sizeof(CKPT_HDR), + cp_node->offset * sizeof(CKPT_INFO_V0)); + ((CKPT_INFO_V0 *)(&ckpt_info))->is_close = true; + m_CPND_CKPTINFO_V0_UPDATE((char *)cb->shm_addr.ckpt_addr + sizeof(CKPT_HDR), ckpt_info, + cp_node->offset * sizeof(CKPT_INFO_V0)); } return; } @@ -1136,12 +1461,21 @@ void cpnd_restart_reset_close_flag(CPND_ CKPT_INFO ckpt_info; memset(&ckpt_info, '\0', sizeof(CKPT_INFO)); - if (cp_node->offset >= 0) { + if (cp_node->offset < 0) { + return; + } + if (cpnd_shm_version.shm_version == CPSV_CPND_SHM_VERSION_LONG_DN) { m_CPND_CKPTINFO_READ(ckpt_info, (char *)cb->shm_addr.ckpt_addr + sizeof(CKPT_HDR), cp_node->offset * sizeof(CKPT_INFO)); ckpt_info.is_close = false; m_CPND_CKPTINFO_UPDATE((char *)cb->shm_addr.ckpt_addr + sizeof(CKPT_HDR), ckpt_info, cp_node->offset * sizeof(CKPT_INFO)); + } else { + m_CPND_CKPTINFO_V0_READ(ckpt_info, (char *)cb->shm_addr.ckpt_addr + sizeof(CKPT_HDR), + cp_node->offset * sizeof(CKPT_INFO_V0)); + ((CKPT_INFO_V0 *)(&ckpt_info))->is_close = false; + m_CPND_CKPTINFO_V0_UPDATE((char *)cb->shm_addr.ckpt_addr + sizeof(CKPT_HDR), + ckpt_info, cp_node->offset * sizeof(CKPT_INFO_V0)); } return; } @@ -1235,6 +1569,94 @@ void cpnd_clear_ckpt_info(CPND_CB *cb, C } /************************************************************************************************************ + * Name : cpnd_clear_ckpt_info_v0 + * + * Description : To start the timer and to reset the client information + * + * Arguments : + * + * Return Values: +************************************************************************************************************/ +void cpnd_clear_ckpt_info_v0(CPND_CB *cb, CPND_CKPT_NODE *cp_node, uint32_t curr_offset, uint32_t prev_offset) +{ + CKPT_INFO_V0 prev_ckpt_info, curr_ckpt_info, next_ckpt_info; + uint64_t i_offset, no_ckpts; + CKPT_HDR ckpt_hdr; + + TRACE_ENTER(); + memset(&prev_ckpt_info, '\0', sizeof(CKPT_INFO_V0)); + memset(&curr_ckpt_info, '\0', sizeof(CKPT_INFO_V0)); + memset(&next_ckpt_info, '\0', sizeof(CKPT_INFO_V0)); + + if (((prev_offset * sizeof(CKPT_INFO_V0)) > UINTMAX_MAX) || ((curr_offset * sizeof(CKPT_INFO_V0)) > UINTMAX_MAX)){ + LOG_ER("cpnd clear ckpt info failed,exceeded the write limits(UINT64_MAX) "); + } + i_offset = prev_offset * sizeof(CKPT_INFO_V0); + m_CPND_CKPTINFO_V0_READ(prev_ckpt_info, (char *)cb->shm_addr.ckpt_addr + sizeof(CKPT_HDR), i_offset); + + i_offset = curr_offset * sizeof(CKPT_INFO_V0); + m_CPND_CKPTINFO_V0_READ(curr_ckpt_info, (char *)cb->shm_addr.ckpt_addr + sizeof(CKPT_HDR), i_offset); + + /* Update the Next Location in the previous prev_ckpt_info.next as we have to clear the curr ckpt_info */ + if (cp_node->offset != curr_offset) { + memset(&ckpt_hdr, '\0', sizeof(CKPT_HDR)); + m_CPND_CKPTHDR_READ(ckpt_hdr, (char *)cb->shm_addr.ckpt_addr, 0); + no_ckpts = --(ckpt_hdr.num_ckpts); + /* write the checkpoint info (number of ckpts)in the header */ + cpnd_ckpt_write_header(cb, no_ckpts); + + prev_ckpt_info.next = curr_ckpt_info.next; + /*Update the prev & curr shared memory segments with the new data */ + i_offset = prev_offset * sizeof(CKPT_INFO_V0); + m_CPND_CKPTINFO_V0_UPDATE((char *)cb->shm_addr.ckpt_addr + sizeof(CKPT_HDR), prev_ckpt_info, i_offset); + + memset(&curr_ckpt_info, '\0', sizeof(CKPT_INFO_V0)); + i_offset = curr_offset * sizeof(CKPT_INFO_V0); + m_CPND_CKPTINFO_V0_UPDATE((char *)cb->shm_addr.ckpt_addr + sizeof(CKPT_HDR), curr_ckpt_info, i_offset); + } else { /* This is the starting entry for this cp_node so update accordingly */ + + if (curr_ckpt_info.next >= 0) { + memset(&ckpt_hdr, '\0', sizeof(CKPT_HDR)); + m_CPND_CKPTHDR_READ(ckpt_hdr, (char *)cb->shm_addr.ckpt_addr, 0); + no_ckpts = --(ckpt_hdr.num_ckpts); + /* write the checkpoint info (number of ckpts)in the header */ + cpnd_ckpt_write_header(cb, no_ckpts); + + cp_node->offset = curr_ckpt_info.next; + + i_offset = (curr_ckpt_info.next) * sizeof(CKPT_INFO_V0); + if (((curr_ckpt_info.next) * sizeof(CKPT_INFO_V0)) > UINTMAX_MAX) { + LOG_ER("cpnd clear ckpt info failed,exceeded the write limits(UINT64_MAX) "); + } + i_offset = (curr_ckpt_info.next) * sizeof(CKPT_INFO_V0); + m_CPND_CKPTINFO_V0_READ(next_ckpt_info, (char *)cb->shm_addr.ckpt_addr + sizeof(CKPT_HDR), + i_offset); + + next_ckpt_info.is_close = curr_ckpt_info.is_close; + next_ckpt_info.is_unlink = curr_ckpt_info.is_unlink; + next_ckpt_info.close_time = curr_ckpt_info.close_time; + next_ckpt_info.is_first = true; + m_CPND_CKPTINFO_V0_UPDATE((char *)cb->shm_addr.ckpt_addr + sizeof(CKPT_HDR), next_ckpt_info, + i_offset); + + if (((curr_ckpt_info.offset) * sizeof(CKPT_INFO_V0)) > UINTMAX_MAX) { + LOG_ER("cpnd clear ckpt info failed,exceeded the write limits(UINT64_MAX) "); + } + i_offset = (curr_ckpt_info.offset) * sizeof(CKPT_INFO_V0); + memset(&curr_ckpt_info, '\0', sizeof(CKPT_INFO_V0)); + + m_CPND_CKPTINFO_V0_UPDATE((char *)cb->shm_addr.ckpt_addr + sizeof(CKPT_HDR), curr_ckpt_info, + i_offset); + + } else { + /* There is only one ckpt_info is there for this cp_node so no need to delete this node as part of close + This ckpt_info gets deleted as part of unlink & lcl_ref_cnt of cp_node == 0 / lcl_ref_cnt == 0 & ret_tmr expires */ + } + } + TRACE_LEAVE(); +} + +/************************************************************************************************************ * Name : cpnd_restart_client_reset * * Description : To start the timer and to reset the client information @@ -1245,6 +1667,23 @@ void cpnd_clear_ckpt_info(CPND_CB *cb, C ************************************************************************************************************/ void cpnd_restart_client_reset(CPND_CB *cb, CPND_CKPT_NODE *cp_node, CPND_CKPT_CLIENT_NODE *cl_node) { + if (cpnd_shm_version.shm_version == CPSV_CPND_SHM_VERSION_LONG_DN) { + cpnd_restart_client_reset_v1(cb, cp_node, cl_node); + } else { + cpnd_restart_client_reset_v0(cb, cp_node, cl_node); + } +} +/************************************************************************************************************ + * Name : cpnd_restart_client_reset_v1 + * + * Description : To start the timer and to reset the client information + * + * Arguments : + * + * Return Values: +************************************************************************************************************/ +void cpnd_restart_client_reset_v1(CPND_CB *cb, CPND_CKPT_NODE *cp_node, CPND_CKPT_CLIENT_NODE *cl_node) +{ CKPT_INFO ckpt_info; uint32_t bitmap_offset = 0, num_bitset = 0; bool found = false; @@ -1281,6 +1720,53 @@ void cpnd_restart_client_reset(CPND_CB * return; } +/************************************************************************************************************ + * Name : cpnd_restart_client_reset_v0 + * + * Description : To start the timer and to reset the client information + * + * Arguments : + * + * Return Values: +************************************************************************************************************/ +void cpnd_restart_client_reset_v0(CPND_CB *cb, CPND_CKPT_NODE *cp_node, CPND_CKPT_CLIENT_NODE *cl_node) +{ + CKPT_INFO_V0 ckpt_info; + uint32_t bitmap_offset = 0, num_bitset = 0; + bool found = false; + uint32_t offset, prev_offset; + SaCkptHandleT client_hdl = cl_node->ckpt_app_hdl; + + + TRACE_ENTER(); + bitmap_offset = client_hdl / 32; + + memset(&ckpt_info, '\0', sizeof(CKPT_INFO_V0)); + + if (cp_node->offset >= 0) { + m_CPND_CKPTINFO_V0_READ(ckpt_info, (char *)cb->shm_addr.ckpt_addr + sizeof(CKPT_HDR), + cp_node->offset * sizeof(CKPT_INFO_V0)); + /* findour the exact ckpt_info matching the client_hdl */ + found = cpnd_find_exact_ckptinfo_v0(cb, &ckpt_info, bitmap_offset, &offset, &prev_offset); + if (found) { + memset(&ckpt_info, '\0', sizeof(CKPT_INFO_V0)); + m_CPND_CKPTINFO_V0_READ(ckpt_info, (char *)cb->shm_addr.ckpt_addr + sizeof(CKPT_HDR), + offset * sizeof(CKPT_INFO_V0)); + client_bitmap_reset(&ckpt_info.client_bitmap, (client_hdl % 32)); + m_CPND_CKPTINFO_V0_UPDATE((char *)cb->shm_addr.ckpt_addr + sizeof(CKPT_HDR), + ckpt_info, offset * sizeof(CKPT_INFO_V0)); + + /* Delete the ckpt_info from shared memory if this ckpt_info's all 31 refs are closed */ + num_bitset = client_bitmap_isset(ckpt_info.client_bitmap); + if (!num_bitset) + cpnd_clear_ckpt_info_v0(cb, cp_node, offset, prev_offset); + + } + } + TRACE_LEAVE(); + return; +} + /********************************************************************************************* * Name : cpnd_restart_shm_ckpt_update * @@ -1304,6 +1790,14 @@ uint32_t cpnd_restart_shm_ckpt_update(CP CKPT_HDR ckpt_hdr; TRACE_ENTER(); + /* Check ckpt name input versus shm version and restart shm if need */ + if (strlen(cp_node->ckpt_name) > SA_MAX_UNEXTENDED_NAME_LENGTH && cpnd_shm_version.shm_version != CPSV_CPND_SHM_VERSION_LONG_DN) { + cpnd_shm_version.shm_version = CPSV_CPND_SHM_VERSION_LONG_DN; + NCS_OS_POSIX_SHM_REQ_INFO cpnd_open_req; + memset(&cpnd_open_req, 0, sizeof(cpnd_open_req)); + cpnd_restart_shm(&cpnd_open_req, cb, cb->nodeid); + } + /* check if the ckpt already exists */ if (cp_node->offset == SHM_INIT) { /* if it is not there then find the free place to fit into */ /* now find the free shm for placing the checkpoint info */ @@ -1372,6 +1866,9 @@ static uint32_t cpnd_restore_client_info n_clients = cli_hdr.num_clients; TRACE_1("cpnd num clients read - n_clients = %d", n_clients); + /* Clean up before loading data*/ + cpnd_client_node_tree_cleanup(cb); + /* ( DO - WHILE )- READ THE CLIENT INFO AND FILL THE DATABASE OF CLIENT INFO */ if (n_clients != 0) { while (counter < MAX_CLIENTS) { @@ -1839,12 +2336,8 @@ static void cpnd_destroy_shm_cpnd_cp_inf static void *cpnd_create_shm_cpnd_cp_info(NCS_OS_POSIX_SHM_REQ_INFO *req_info) { uint32_t rc = NCSCC_RC_SUCCESS; - CPND_SHM_VERSION cpnd_shm_version; TRACE_ENTER(); - /* Initializing shared memory version */ - memset(&cpnd_shm_version, '\0', sizeof(cpnd_shm_version)); - cpnd_shm_version.shm_version = CPSV_CPND_SHM_VERSION; /* Create the shared memory */ req_info->info.open.i_flags = O_CREAT | O_RDWR; @@ -1855,9 +2348,7 @@ static void *cpnd_create_shm_cpnd_cp_inf } /* Initialize memory and set version */ - memset(req_info->info.open.o_addr, 0, - sizeof(CLIENT_HDR) + (MAX_CLIENTS * sizeof(CLIENT_INFO)) + sizeof(CKPT_HDR) + - (MAX_CKPTS * sizeof(CKPT_INFO))); + memset(req_info->info.open.o_addr, 0, cpsv_cpnd_shm_size(cpnd_shm_version.shm_version)); memcpy(req_info->info.open.o_addr, &cpnd_shm_version, sizeof(cpnd_shm_version)); TRACE_LEAVE(); ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot _______________________________________________ Opensaf-devel mailing list Opensaf-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/opensaf-devel