Hi Hoang,

On 10/18/2016 11:24 AM, Vo Minh Hoang wrote:
> Dear Mahesh,
>
>>> [AVM] A non-collated Ckpt will have two replicas on both Active and
> standby.
> Each node will receive one CPND_EVT_D2ND_CKPT_CREATE message so it handles
> swapping itself and does not affect each other nor another.
[AVM]   I was taking about existing, swapping of existing `small format shm`
  not  not new create request , where the ckpt is already opened 
multiple nodes with ALL option.
>
>>> [AVM] piratically  we can have large size data & transit time, if ckt pat
> has  large data  sham is file I/O operation
>>>              not middle-ware controlled activity , swap time will vary
> depending on system.
> I am agree that this modification affects performance of create/open
> function so it need performance acceptance verification.
> Fortunately, shared mem is on memory so it is not heavily depend on OS or
> file system (unless on swap memory area).
> Maybe I am not understand your ideal here but I have not found a clear
> reason of handling try-again.
[AVM] say for example an application is writing in a loop to old `small 
format shm`,
at that moment you started conversation of old `small format shm` to 
new  `big format`

-AVM

>
> Thank you and best regards,
> Hoang
>
> -----Original Message-----
> From: A V Mahesh [mailto:mahesh.va...@oracle.com]
> Sent: Tuesday, October 18, 2016 12:14 PM
> To: Vo Minh Hoang <hoang.m...@dektech.com.au>
> Cc: anders.wid...@ericsson.com; opensaf-devel@lists.sourceforge.net
> Subject: Re: [PATCH 1 of 1] cpnd: use shared memory based on ckpt name
> length [#2108]
>
> Hi Hoan,
>
>
> On 10/18/2016 9:59 AM, Vo Minh Hoang wrote:
>> Dear Mahesh,
>>
>> Thank you very much for your comments.
>>
>> I would like to explain my understanding and reason for this solution.
>> Please correct me if I am wrong.
>>
>> - This memory swapping works on single node alone, it will occur
>> maximum once per node in open/create checkpoint process.
>> - This swapping action just takes place in nodes that meet condition
>> and does not affect other node.
> [AVM] A non-collated Ckpt will have two replicas on both Active and standby
> .
>> - CPND handles open/create processes atomically in sequence in one
>> thread only.
>>
>> Because of that I think it is unnecessary to implement thread
>> synchronizing or `try-again` handling.
> [AVM] piratically  we can have large size data & transit time, if ckt pat
> has  large data  sham is file I/O operation
>               not middle-ware controlled activity , swap time will vary
> depending on system.
>> Sincerely,
>> Hoang
>>
>> -----Original Message-----
>> From: A V Mahesh [mailto:mahesh.va...@oracle.com]
>> Sent: Tuesday, October 18, 2016 10:48 AM
>> To: Vo Minh Hoang <hoang.m...@dektech.com.au>
>> Cc: anders.wid...@ericsson.com; opensaf-devel@lists.sourceforge.net
>> Subject: Re: [PATCH 1 of 1] cpnd: use shared memory based on ckpt name
>> length [#2108]
>>
>> Hi Hoang,
>>
>> On 10/13/2016 12:44 PM, Vo Minh Hoang wrote:
>>> No, old checkpoint data is converted to `big format`.
>>> So all of them will be stored in `big format`.
>> [AVM] This approach is introducing NEW transit ,  so far application
>> are aware of  switch-over & fail-over transit and TRY-AGAIN is
>> expected only in those case , now this solution is introducing  a new
>> transit  for the application which are accessioning the old  (by the
>> way this patch didn't implemented TRY-AGAIN when shared memory
>> swapping action occurring)
>>
>> `small format shm`, up on some application creating  `big format` (
>> application impacting the HA behavior )
>>     not sure about the solution approach need to discussed !
>>
>> -AVM
>>
>> On 10/13/2016 12:44 PM, Vo Minh Hoang wrote:
>>> Dear Mahesh,
>>>
>>> Because of keeping the consistent working behavior of existing
>>> function, only 1 shared memory at a time. If shared memory swapping
>>> action occurs, a new shared memory will replace old one.
>>>
>>> Here is the detailed answers to your questions:
>>>>> -The  existing  `small format shm`  will continue to be small , is
>>>>> that
>>> right ?
>>>>> -Only newly created longDN checkpoint will be in `big format shm`,
>>>>> is
>>> that right ?
>>> No, old checkpoint data is converted to `big format`.
>>> So all of them will be stored in `big format`.
>>>
>>>>> - what will be the format of newly joined the PL-5 opens  an
>>>>> existing
>>> `small format shm`
>>> PL-5 still use `small format`.
>>> Only when a long DN replica is added in this node, the shared memory
>>> is converted to `big format`.
>>>>>     the what will be the new replica  on new node `small format shm`
>>>>> or `big
>>> format shm` ?
>>> This implementation only affect the `header` shared memory
>>> (opensaf_CPND_CHECKPOINT_INFO_nodeid). It do not change replica
>>> shared memory (opensaf_ckptname_nodeid_n).
>>>
>>> About testing, because of above specification, I tested:
>>> - start new node
>>> - restart ckptnd with existing small shm
>>> - restart ckptnd with existing big shm
>>> - create first long dn (check all node)
>>>
>>> Thank you and best regards,
>>> Hoang
>>>
>>> -----Original Message-----
>>> From: A V Mahesh [mailto:mahesh.va...@oracle.com]
>>> Sent: Thursday, October 13, 2016 1:33 PM
>>> To: Hoang Vo <hoang.m...@dektech.com.au>; anders.wid...@ericsson.com
>>> Cc: opensaf-devel@lists.sourceforge.net
>>> Subject: Re: [PATCH 1 of 1] cpnd: use shared memory based on ckpt
>>> name length [#2108]
>>>
>>> Hi Hoang,
>>>
>>>     >> - Run time cpnd keep using small format shm until first longDN
>>> checkpoint is created.
>>>     >> After that cpnd use big format shm.
>>>
>>> While reviewing I am assuming following please confirm  :
>>>
>>> -The  existing  `small format shm`  will continue to be small , is
>>> that right ?
>>> -Only newly created longDN checkpoint will be in `big format shm`, is
>>> that right ?
>>> - what will be the format of newly joined the PL-5 opens  an existing
>>> `small format shm`
>>>       the what will be the new replica  on new node `small format shm`
>>> or `big format shm` ?
>>>
>>>
>>> I hope you  tested following :
>>> ==========================
>>> - combination of some `small format shm`  and some  `big format shm`
>>> ckpts
>>> - Joined a New node ( say PL-5)  and then opened the existing `small
>>> format shm` ckpt from the new Node
>>> - Restating controller which has combination of  `small format shm`
>>> and `big format shm` and how the restored non-collocated ckpt`s
>>>
>>> -AVM
>>>
>>> On 10/11/2016 1:15 PM, Hoang Vo wrote:
>>>>      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

Reply via email to