Implementation of Section 6.2.2 of the CKPT-B.02.02 spec.
---
 src/ais/include/saCkpt.h          | 415 ++++++++++++++++++++++++--------------
 src/ckpt/Makefile.am              |   2 +
 src/ckpt/apitest/test_cpa.c       | 122 +++++++++++
 src/ckpt/apitest/test_cpa_util.c  | 190 +++++++++++++++++
 src/ckpt/apitest/test_cpsv.h      |  13 ++
 src/ckpt/apitest/test_cpsv_conf.h |   8 +
 src/ckpt/ckptnd/cpnd_cb.h         |   3 +
 src/ckpt/ckptnd/cpnd_evt.c        | 113 +++++++++++
 src/ckpt/ckptnd/cpnd_init.c       |  57 ++++++
 9 files changed, 768 insertions(+), 155 deletions(-)

diff --git a/src/ais/include/saCkpt.h b/src/ais/include/saCkpt.h
index 3feae1c..210b78b 100644
--- a/src/ais/include/saCkpt.h
+++ b/src/ais/include/saCkpt.h
@@ -1,186 +1,291 @@
-/*
-
-  Header file of SA Forum AIS CKPT APIs (SAI-AIS-B.01.00.09)
-  compiled on 28SEP2004 by sayandeb.s...@motorola.com.
-*/
+/*******************************************************************************
+**
+** FILE:
+**   saCkpt.h
+**
+** DESCRIPTION: 
+**   This file provides the C language binding for the Service 
+**   Availability(TM) Forum AIS Checkpoint Service (CKPT). It contains all of 
+**   the prototypes and type definitions required for CKPT. 
+**   
+** SPECIFICATION VERSION:
+**   SAI-AIS-CKPT-B.02.02
+**
+** DATE: 
+**   Thu Jul 16 2009
+**
+** LEGAL:
+**   OWNERSHIP OF SPECIFICATION AND COPYRIGHTS. 
+**
+** Copyright(c) 2009, Service Availability(TM) Forum. All rights reserved.
+**
+** Permission to use, copy, modify, and distribute this software for any
+** purpose without fee is hereby granted, provided that this entire notice
+** is included in all copies of any software which is or includes a copy
+** or modification of this software and in all copies of the supporting
+** documentation for such software.
+**
+** THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
+** WARRANTY.  IN PARTICULAR, THE SERVICE AVAILABILITY FORUM DOES NOT MAKE ANY
+** REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
+** OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
+**
+*******************************************************************************/
 
 #ifndef _SA_CKPT_H
 #define _SA_CKPT_H
 
+/**************************************************/
+/********** Defs for CKPT API functions ***********/
+/**************************************************/
+
 #include "saAis.h"
 
 #ifdef  __cplusplus
 extern "C" {
 #endif
 
-       typedef SaUint64T SaCkptHandleT;
-       typedef SaUint64T SaCkptCheckpointHandleT;
-       typedef SaUint64T SaCkptSectionIterationHandleT;
+typedef SaUint64T SaCkptHandleT;
+typedef SaUint64T SaCkptCheckpointHandleT;
+typedef SaUint64T SaCkptSectionIterationHandleT;
 
 #define SA_CKPT_WR_ALL_REPLICAS 0X1
 #define SA_CKPT_WR_ACTIVE_REPLICA 0X2
 #define SA_CKPT_WR_ACTIVE_REPLICA_WEAK 0X4
 #define SA_CKPT_CHECKPOINT_COLLOCATED 0X8
 
-       typedef SaUint32T SaCkptCheckpointCreationFlagsT;
+typedef SaUint32T SaCkptCheckpointCreationFlagsT;
 
-       typedef struct {
-               SaCkptCheckpointCreationFlagsT creationFlags;
-               SaSizeT checkpointSize;
-               SaTimeT retentionDuration;
-               SaUint32T maxSections;
-               SaSizeT maxSectionSize;
-               SaSizeT maxSectionIdSize;
-       } SaCkptCheckpointCreationAttributesT;
+typedef struct {
+    SaCkptCheckpointCreationFlagsT creationFlags;
+    SaSizeT                        checkpointSize;
+    SaTimeT                        retentionDuration;
+    SaUint32T                      maxSections;
+    SaSizeT                        maxSectionSize;
+    SaSizeT                        maxSectionIdSize;
+} SaCkptCheckpointCreationAttributesT;
 
 #define SA_CKPT_CHECKPOINT_READ 0X1
 #define SA_CKPT_CHECKPOINT_WRITE 0X2
 #define SA_CKPT_CHECKPOINT_CREATE 0X4
 
-       typedef SaUint32T SaCkptCheckpointOpenFlagsT;
+typedef SaUint32T SaCkptCheckpointOpenFlagsT;
 
 #define SA_CKPT_DEFAULT_SECTION_ID   {0, NULL}
 #define SA_CKPT_GENERATED_SECTION_ID {0, NULL}
 
-       typedef struct {
-               SaUint16T idLen;
-               SaUint8T *id;
-       } SaCkptSectionIdT;
-
-       typedef struct {
-               SaCkptSectionIdT *sectionId;
-               SaTimeT expirationTime;
-       } SaCkptSectionCreationAttributesT;
-
-       typedef enum {
-               SA_CKPT_SECTION_VALID = 1,
-               SA_CKPT_SECTION_CORRUPTED = 2
-       } SaCkptSectionStateT;
-
-       typedef struct {
-               SaCkptSectionIdT sectionId;
-               SaTimeT expirationTime;
-               SaSizeT sectionSize;
-               SaCkptSectionStateT sectionState;
-               SaTimeT lastUpdate;
-       } SaCkptSectionDescriptorT;
-
-       typedef enum {
-               SA_CKPT_SECTIONS_FOREVER = 1,
-               SA_CKPT_SECTIONS_LEQ_EXPIRATION_TIME = 2,
-               SA_CKPT_SECTIONS_GEQ_EXPIRATION_TIME = 3,
-               SA_CKPT_SECTIONS_CORRUPTED = 4,
-               SA_CKPT_SECTIONS_ANY = 5
-       } SaCkptSectionsChosenT;
-
-       typedef struct {
-               SaCkptSectionIdT sectionId;
-               void *dataBuffer;
-               SaSizeT dataSize;
-               SaOffsetT dataOffset;
-               SaSizeT readSize;
-       } SaCkptIOVectorElementT;
-
-       typedef struct {
-               SaCkptCheckpointCreationAttributesT 
checkpointCreationAttributes;
-               SaUint32T numberOfSections;
-               SaSizeT memoryUsed;
-       } SaCkptCheckpointDescriptorT;
-
-       typedef enum {
-               SA_CKPT_SECTION_FULL = 1,
-               SA_CKPT_SECTION_AVAILABLE = 2
-       } SaCkptCheckpointStatusT;
-
-       typedef enum {
-               SA_CKPT_CHECKPOINT_STATUS = 1
-       } SaCkptStateT;
-
-       typedef void
-        (*SaCkptCheckpointOpenCallbackT) (SaInvocationT invocation,
-                                          SaCkptCheckpointHandleT 
checkpointHandle, SaAisErrorT error);
-       typedef void
-        (*SaCkptCheckpointSynchronizeCallbackT) (SaInvocationT invocation, 
SaAisErrorT error);
-
-       typedef struct {
-               SaCkptCheckpointOpenCallbackT saCkptCheckpointOpenCallback;
-               SaCkptCheckpointSynchronizeCallbackT 
saCkptCheckpointSynchronizeCallback;
-       } SaCkptCallbacksT;
-
-       extern SaAisErrorT
-        saCkptInitialize(SaCkptHandleT *ckptHandle, const SaCkptCallbacksT 
*callbacks, SaVersionT *version);
-       extern SaAisErrorT
-        saCkptSelectionObjectGet(SaCkptHandleT ckptHandle, SaSelectionObjectT 
*selectionObject);
-       extern SaAisErrorT
-        saCkptDispatch(SaCkptHandleT ckptHandle, SaDispatchFlagsT 
dispatchFlags);
-       extern SaAisErrorT
-        saCkptFinalize(SaCkptHandleT ckptHandle);
-       extern SaAisErrorT
-        saCkptCheckpointOpen(SaCkptHandleT ckptHandle,
-                             const SaNameT *checkpointName,
-                             const SaCkptCheckpointCreationAttributesT 
*checkpointCreationAttributes,
-                             SaCkptCheckpointOpenFlagsT checkpointOpenFlags,
-                             SaTimeT timeout, SaCkptCheckpointHandleT 
*checkpointHandle);
-       extern SaAisErrorT
-        saCkptCheckpointOpenAsync(SaCkptHandleT ckptHandle,
-                                  SaInvocationT invocation,
-                                  const SaNameT *checkpointName,
-                                  const SaCkptCheckpointCreationAttributesT 
*checkpointCreationAttributes,
-                                  SaCkptCheckpointOpenFlagsT 
checkpointOpenFlags);
-       extern SaAisErrorT
-        saCkptCheckpointClose(SaCkptCheckpointHandleT checkpointHandle);
-       extern SaAisErrorT
-        saCkptCheckpointUnlink(SaCkptHandleT ckptHandle, const SaNameT 
*checkpointName);
-       extern SaAisErrorT
-        saCkptCheckpointRetentionDurationSet(SaCkptCheckpointHandleT 
checkpointHandle, SaTimeT retentionDuration);
-       extern SaAisErrorT
-        saCkptActiveReplicaSet(SaCkptCheckpointHandleT checkpointHandle);
-       extern SaAisErrorT
-        saCkptCheckpointStatusGet(SaCkptCheckpointHandleT checkpointHandle,
-                                  SaCkptCheckpointDescriptorT 
*checkpointStatus);
-       extern SaAisErrorT
-        saCkptSectionCreate(SaCkptCheckpointHandleT checkpointHandle,
-                            SaCkptSectionCreationAttributesT 
*sectionCreationAttributes,
-                            const void *initialData, SaSizeT initialDataSize);
-       extern SaAisErrorT
-        saCkptSectionDelete(SaCkptCheckpointHandleT checkpointHandle, const 
SaCkptSectionIdT *sectionId);
-       extern SaAisErrorT
-        saCkptSectionExpirationTimeSet(SaCkptCheckpointHandleT 
checkpointHandle,
-                                       const SaCkptSectionIdT *sectionId, 
SaTimeT expirationTime);
-       extern SaAisErrorT
-        saCkptSectionIterationInitialize(SaCkptCheckpointHandleT 
checkpointHandle,
-                                         SaCkptSectionsChosenT sectionsChosen,
-                                         SaTimeT expirationTime,
-                                         SaCkptSectionIterationHandleT 
*sectionIterationHandle);
-       extern SaAisErrorT
-        saCkptSectionIterationNext(SaCkptSectionIterationHandleT 
sectionIterationHandle,
-                                   SaCkptSectionDescriptorT 
*sectionDescriptor);
-       extern SaAisErrorT
-        saCkptSectionIterationFinalize(SaCkptSectionIterationHandleT 
sectionIterationHandle);
-       extern SaAisErrorT
-        saCkptCheckpointWrite(SaCkptCheckpointHandleT checkpointHandle,
-                              const SaCkptIOVectorElementT *ioVector,
-                              SaUint32T numberOfElements, SaUint32T 
*erroneousVectorIndex);
-       extern SaAisErrorT
-        saCkptSectionOverwrite(SaCkptCheckpointHandleT checkpointHandle,
-                               const SaCkptSectionIdT *sectionId, const void 
*dataBuffer, SaSizeT dataSize);
-       extern SaAisErrorT
-        saCkptCheckpointRead(SaCkptCheckpointHandleT checkpointHandle,
-                             SaCkptIOVectorElementT *ioVector,
-                             SaUint32T numberOfElements, SaUint32T 
*erroneousVectorIndex);
-       extern SaAisErrorT
-        saCkptCheckpointSynchronize(SaCkptCheckpointHandleT checkpointHandle, 
SaTimeT timeout);
-       extern SaAisErrorT
-        saCkptCheckpointSynchronizeAsync(SaCkptCheckpointHandleT 
checkpointHandle, SaInvocationT invocation);
-
-       extern SaAisErrorT
-        saCkptSectionIdFree(SaCkptCheckpointHandleT checkpointHandle, SaUint8T 
*id);
-
-       extern SaAisErrorT
-        saCkptIOVectorElementDataFree(SaCkptCheckpointHandleT 
checkpointHandle, void *data);
+typedef struct {
+    SaUint16T idLen;
+    SaUint8T *id;
+} SaCkptSectionIdT;
+
+typedef struct {
+    SaCkptSectionIdT *sectionId;
+    SaTimeT expirationTime;
+} SaCkptSectionCreationAttributesT;
+
+typedef enum {
+    SA_CKPT_SECTION_VALID = 1,
+    SA_CKPT_SECTION_CORRUPTED = 2
+} SaCkptSectionStateT;
+
+typedef struct {
+    SaCkptSectionIdT    sectionId;
+    SaTimeT             expirationTime;
+    SaSizeT             sectionSize;
+    SaCkptSectionStateT sectionState;
+    SaTimeT             lastUpdate;
+} SaCkptSectionDescriptorT;
+
+typedef enum {
+    SA_CKPT_SECTIONS_FOREVER = 1,
+    SA_CKPT_SECTIONS_LEQ_EXPIRATION_TIME = 2,
+    SA_CKPT_SECTIONS_GEQ_EXPIRATION_TIME = 3,
+    SA_CKPT_SECTIONS_CORRUPTED = 4,
+    SA_CKPT_SECTIONS_ANY = 5
+} SaCkptSectionsChosenT;
+
+typedef struct {
+    SaCkptSectionIdT sectionId;
+    void            *dataBuffer;
+    SaSizeT          dataSize;
+    SaOffsetT        dataOffset;
+    SaSizeT          readSize;
+} SaCkptIOVectorElementT;
+
+typedef struct {
+    SaCkptCheckpointCreationAttributesT checkpointCreationAttributes;
+    SaUint32T                           numberOfSections;
+    SaSizeT                             memoryUsed;
+} SaCkptCheckpointDescriptorT;
+
+typedef void 
+(*SaCkptCheckpointOpenCallbackT)(
+    SaInvocationT invocation,
+    SaCkptCheckpointHandleT checkpointHandle,
+    SaAisErrorT error);
+
+typedef void 
+(*SaCkptCheckpointSynchronizeCallbackT)(
+    SaInvocationT invocation,
+    SaAisErrorT error);
+
+typedef struct {
+    SaCkptCheckpointOpenCallbackT        saCkptCheckpointOpenCallback;
+    SaCkptCheckpointSynchronizeCallbackT saCkptCheckpointSynchronizeCallback;
+} SaCkptCallbacksT;
+
+typedef enum {      
+    SA_CKPT_SECTION_RESOURCES_EXHAUSTED = 1,
+    SA_CKPT_SECTION_RESOURCES_AVAILABLE = 2
+} SaCkptCheckpointStatusT;
+
+typedef enum {      
+    SA_CKPT_CHECKPOINT_STATUS = 1
+} SaCkptStateT;
+
+
+/*************************************************/
+/******** CKPT API function declarations *********/
+/*************************************************/
+extern SaAisErrorT 
+saCkptInitialize(
+    SaCkptHandleT *ckptHandle, 
+    const SaCkptCallbacksT *callbacks,
+    SaVersionT *version);
+
+extern SaAisErrorT 
+saCkptSelectionObjectGet(
+    SaCkptHandleT ckptHandle,
+    SaSelectionObjectT *selectionObject);
+
+extern SaAisErrorT 
+saCkptDispatch(
+    SaCkptHandleT ckptHandle, 
+    SaDispatchFlagsT dispatchFlags);
+
+extern SaAisErrorT 
+saCkptFinalize(
+    SaCkptHandleT ckptHandle);
+
+extern SaAisErrorT
+saCkptCheckpointOpen(
+    SaCkptHandleT ckptHandle,
+    const SaNameT *checkpointName,
+    const SaCkptCheckpointCreationAttributesT *checkpointCreationAttributes,
+    SaCkptCheckpointOpenFlagsT checkpointOpenFlags,
+    SaTimeT timeout,
+    SaCkptCheckpointHandleT *checkpointHandle);
+
+extern SaAisErrorT 
+saCkptCheckpointOpenAsync(
+    SaCkptHandleT ckptHandle,
+    SaInvocationT invocation,
+    const SaNameT *checkpointName,
+    const SaCkptCheckpointCreationAttributesT *checkpointCreationAttributes,
+    SaCkptCheckpointOpenFlagsT checkpointOpenFlags);
+
+extern SaAisErrorT
+saCkptCheckpointClose(
+    SaCkptCheckpointHandleT checkpointHandle);
+
+extern SaAisErrorT 
+saCkptCheckpointUnlink(
+    SaCkptHandleT ckptHandle, 
+    const SaNameT *checkpointName);
+
+extern SaAisErrorT 
+saCkptCheckpointRetentionDurationSet(
+    SaCkptCheckpointHandleT checkpointHandle,
+    SaTimeT retentionDuration);
+
+extern SaAisErrorT 
+saCkptActiveReplicaSet(
+    SaCkptCheckpointHandleT checkpointHandle);
+
+extern SaAisErrorT 
+saCkptCheckpointStatusGet(
+    SaCkptCheckpointHandleT checkpointHandle,
+    SaCkptCheckpointDescriptorT *checkpointStatus);
+
+extern SaAisErrorT 
+saCkptSectionCreate(
+    SaCkptCheckpointHandleT checkpointHandle,
+    SaCkptSectionCreationAttributesT *sectionCreationAttributes,
+    const void *initialData,
+    SaSizeT initialDataSize);
+
+extern SaAisErrorT 
+saCkptSectionDelete(
+    SaCkptCheckpointHandleT checkpointHandle,
+    const SaCkptSectionIdT *sectionId);
+
+extern SaAisErrorT
+saCkptSectionIdFree(
+    SaCkptCheckpointHandleT checkpointHandle,
+    SaUint8T *id);
+
+extern SaAisErrorT 
+saCkptSectionExpirationTimeSet(
+    SaCkptCheckpointHandleT checkpointHandle,
+    const SaCkptSectionIdT* sectionId,
+    SaTimeT expirationTime);
+
+extern SaAisErrorT 
+saCkptSectionIterationInitialize(
+    SaCkptCheckpointHandleT checkpointHandle,
+    SaCkptSectionsChosenT sectionsChosen,
+    SaTimeT expirationTime,
+    SaCkptSectionIterationHandleT *sectionIterationHandle);
+
+extern SaAisErrorT 
+saCkptSectionIterationNext(
+    SaCkptSectionIterationHandleT sectionIterationHandle,
+    SaCkptSectionDescriptorT *sectionDescriptor);
+
+extern SaAisErrorT 
+saCkptSectionIterationFinalize(
+    SaCkptSectionIterationHandleT sectionIterationHandle);
+
+extern SaAisErrorT 
+saCkptCheckpointWrite(
+    SaCkptCheckpointHandleT checkpointHandle,
+    const SaCkptIOVectorElementT *ioVector,
+    SaUint32T numberOfElements,
+    SaUint32T *erroneousVectorIndex);
+
+extern SaAisErrorT 
+saCkptSectionOverwrite(
+    SaCkptCheckpointHandleT checkpointHandle,
+    const SaCkptSectionIdT *sectionId,
+    const void *dataBuffer,
+    SaSizeT dataSize);
+
+extern SaAisErrorT 
+saCkptCheckpointRead(
+    SaCkptCheckpointHandleT checkpointHandle,
+    SaCkptIOVectorElementT *ioVector,
+    SaUint32T numberOfElements,
+    SaUint32T *erroneousVectorIndex);
+
+extern SaAisErrorT      
+saCkptIOVectorElementDataFree(
+    SaCkptCheckpointHandleT checkpointHandle,
+    void *data);
+
+extern SaAisErrorT 
+saCkptCheckpointSynchronize(
+    SaCkptCheckpointHandleT checkpointHandle,
+    SaTimeT timeout);
+
+extern SaAisErrorT 
+saCkptCheckpointSynchronizeAsync(
+    SaCkptCheckpointHandleT checkpointHandle,
+    SaInvocationT invocation);
 
 #ifdef  __cplusplus
 }
 #endif
 
-#endif   /* _SA_CKPT_H */
+#endif  /* _SA_CKPT_H */
+
diff --git a/src/ckpt/Makefile.am b/src/ckpt/Makefile.am
index 48c7d30..1a4f476 100644
--- a/src/ckpt/Makefile.am
+++ b/src/ckpt/Makefile.am
@@ -155,6 +155,7 @@ bin_osafckptnd_LDADD = \
        lib/libckpt_common.la \
        lib/libSaAmf.la \
        lib/libSaClm.la \
+       lib/libSaNtf.la \
        lib/libosaf_common.la \
        lib/libSaImmOi.la \
        lib/libSaImmOm.la \
@@ -212,6 +213,7 @@ bin_ckpttest_SOURCES = \
 bin_ckpttest_LDADD = \
        lib/libapitest.la \
        lib/libSaCkpt.la \
+       lib/libSaNtf.la \
        lib/libopensaf_core.la
 
 endif
diff --git a/src/ckpt/apitest/test_cpa.c b/src/ckpt/apitest/test_cpa.c
index a04f09c..792eb27 100644
--- a/src/ckpt/apitest/test_cpa.c
+++ b/src/ckpt/apitest/test_cpa.c
@@ -7711,6 +7711,118 @@ final1:
        test_validate(result, TEST_PASS);
 }
 
+static void cpsv_it_ntf_01(void)
+{
+       int result;
+       printHead("To verify notification received when max number of sections 
is reached");
+       result = test_ckptInitialize(CKPT_INIT_SUCCESS_T, TEST_CONFIG_MODE);
+       if (result != TEST_PASS)
+               goto final1;
+
+       result =
+           test_ckptOpen(CKPT_OPEN_ALL_CREATE_SUCCESS_T, TEST_CONFIG_MODE);
+       if (result != TEST_PASS)
+               goto final2;
+
+       result = test_ckptOpen(CKPT_OPEN_ALL_WRITE_SUCCESS_T, TEST_CONFIG_MODE);
+       if (result != TEST_PASS)
+               goto final3;
+
+       result = test_ckptSectionCreate(CKPT_SECTION_CREATE_SUCCESS_T,
+                                       TEST_CONFIG_MODE);
+       if (result != TEST_PASS)
+               goto final3;
+
+       result = test_ckptSectionCreate(CKPT_SECTION_CREATE_SUCCESS3_T,
+                                       TEST_CONFIG_MODE);
+       if (result != TEST_PASS)
+               goto final3;
+
+       result = test_ckptNtfInit(CKPT_NTF_RESOURCES_EXHAUSTED,
+                                       TEST_NONCONFIG_MODE);
+       if (result != TEST_PASS)
+               goto final3;
+
+       result = test_ckptSectionCreate(CKPT_SECTION_CREATE_NO_SPACE_T,
+                                       TEST_NONCONFIG_MODE);
+       if (result != TEST_PASS)
+               goto final4;
+
+       result = test_ckptNtfStateChange(CKPT_NTF_RESOURCES_EXHAUSTED,
+                                   TEST_NONCONFIG_MODE);
+
+final4:
+       test_ckptNtfCleanup(CKPT_NTF_RESOURCES_EXHAUSTED, TEST_NONCONFIG_MODE);
+final3:
+       test_ckpt_cleanup(CPSV_CLEAN_ALL_REPLICAS_CKPT);
+final2:
+       test_cpsv_cleanup(CPSV_CLEAN_INIT_SUCCESS_T);
+final1:
+       printResult(result);
+       test_validate(result, TEST_PASS);
+}
+
+static void cpsv_it_ntf_02(void)
+{
+       int result;
+       printHead("To verify notification received when sections are available"
+                      " again");
+       result = test_ckptInitialize(CKPT_INIT_SUCCESS_T, TEST_CONFIG_MODE);
+       if (result != TEST_PASS)
+               goto final1;
+
+       result =
+           test_ckptOpen(CKPT_OPEN_ALL_CREATE_SUCCESS_T, TEST_CONFIG_MODE);
+       if (result != TEST_PASS)
+               goto final2;
+
+       result = test_ckptOpen(CKPT_OPEN_ALL_WRITE_SUCCESS_T, TEST_CONFIG_MODE);
+       if (result != TEST_PASS)
+               goto final3;
+
+       result = test_ckptSectionCreate(CKPT_SECTION_CREATE_SUCCESS_T,
+                                       TEST_CONFIG_MODE);
+       if (result != TEST_PASS)
+               goto final3;
+
+       result = test_ckptSectionCreate(CKPT_SECTION_CREATE_SUCCESS3_T,
+                                       TEST_CONFIG_MODE);
+       if (result != TEST_PASS)
+               goto final3;
+
+       result = test_ckptNtfInit(CKPT_NTF_RESOURCES_AVAILABLE,
+                                       TEST_NONCONFIG_MODE);
+       if (result != TEST_PASS)
+               goto final3;
+
+       result = test_ckptSectionCreate(CKPT_SECTION_CREATE_NO_SPACE_T,
+                                       TEST_NONCONFIG_MODE);
+       if (result != TEST_PASS)
+               goto final4;
+
+       result = test_ckptNtfStateChange(CKPT_NTF_RESOURCES_EXHAUSTED,
+                                   TEST_NONCONFIG_MODE);
+       if (result != TEST_PASS)
+               goto final4;
+
+       result = test_ckptSectionDelete(CKPT_DEL_SUCCESS_T, TEST_CONFIG_MODE);
+       if (result != TEST_PASS)
+               goto final4;
+
+       result = test_ckptNtfStateChange(CKPT_NTF_RESOURCES_AVAILABLE,
+                                   TEST_NONCONFIG_MODE);
+
+final4:
+       test_ckptNtfCleanup(CKPT_NTF_RESOURCES_AVAILABLE, TEST_NONCONFIG_MODE);
+final3:
+       test_ckpt_cleanup(CPSV_CLEAN_ALL_REPLICAS_CKPT);
+final2:
+       test_cpsv_cleanup(CPSV_CLEAN_INIT_SUCCESS_T);
+final1:
+       printResult(result);
+       test_validate(result, TEST_PASS);
+}
+
 /********** END OF TEST CASES ************/
 
 __attribute__((constructor)) static void ckpt_cpa_test_constructor(void)
@@ -8308,4 +8420,14 @@ __attribute__((constructor)) static void 
ckpt_cpa_test_constructor(void)
        test_case_add(
            24, cpsv_it_arrclbk_02,
            "To verify the arrival callback when NULL clbk is passed");
+
+       test_suite_add(25, "CKPT Notifications");
+       test_case_add(25,
+                       cpsv_it_ntf_01,
+                       "To verify that Resource Exhausted Notification is "
+                       "received");
+       test_case_add(25,
+                       cpsv_it_ntf_02,
+                       "To verify that Resource Available Notification is "
+                       "received");
 }
diff --git a/src/ckpt/apitest/test_cpa_util.c b/src/ckpt/apitest/test_cpa_util.c
index 6634790..99f2140 100644
--- a/src/ckpt/apitest/test_cpa_util.c
+++ b/src/ckpt/apitest/test_cpa_util.c
@@ -2910,3 +2910,193 @@ int test_red_ckptDispatch(int i, CONFIG_FLAG cfg_flg)
 
        return result;
 }
+
+static struct SafCheckpointNtf NTF_API_Initialize[] = {
+       [CKPT_NTF_RESOURCES_EXHAUSTED] = {
+               &tcd.ntfHandle,
+               &tcd.ntfSelObj,
+               SA_CKPT_SECTION_RESOURCES_EXHAUSTED
+       },
+
+       [CKPT_NTF_RESOURCES_AVAILABLE] = {
+               &tcd.ntfHandle,
+               &tcd.ntfSelObj,
+               SA_CKPT_SECTION_RESOURCES_AVAILABLE
+       }
+};
+
+static void ntfCallback(SaNtfSubscriptionIdT subscriptionId,
+                        const SaNtfNotificationsT *notification)
+{
+       do {
+               if (notification->notificationType != SA_NTF_TYPE_STATE_CHANGE) 
{
+                       NTF_API_Initialize[subscriptionId].result = TEST_FAIL;
+                       break;
+               }
+
+               if 
(notification->notification.stateChangeNotification.notificationHeader.notificationClassId->vendorId
 != SA_NTF_VENDOR_ID_SAF) {
+                       NTF_API_Initialize[subscriptionId].result = TEST_FAIL;
+                       break;
+               }
+
+               if 
(notification->notification.stateChangeNotification.notificationHeader.notificationClassId->majorId
 != SA_SVC_CKPT) {
+                       NTF_API_Initialize[subscriptionId].result = TEST_FAIL;
+                       break;
+               }
+    
+               if 
(notification->notification.stateChangeNotification.numStateChanges != 1) {
+                       NTF_API_Initialize[subscriptionId].result = TEST_FAIL;
+                       break;
+               }
+
+               if 
(*notification->notification.stateChangeNotification.sourceIndicator != 
SA_NTF_OBJECT_OPERATION) {
+                       NTF_API_Initialize[subscriptionId].result = TEST_FAIL;
+                       break;
+               }
+
+               if 
(notification->notification.stateChangeNotification.changedStates[0].stateId != 
SA_CKPT_CHECKPOINT_STATUS) {
+                       NTF_API_Initialize[subscriptionId].result = TEST_FAIL;
+                       break;
+               }
+
+               if 
(strcmp(saAisNameBorrow(notification->notification.stateChangeNotification.notificationHeader.notifyingObject),
 "safApp=safCkptService")) {
+                       NTF_API_Initialize[subscriptionId].result = TEST_FAIL;
+                       break;
+               }
+
+               if (tcd.ntfTest == CKPT_NTF_RESOURCES_EXHAUSTED) {
+                       if 
(notification->notification.stateChangeNotification.notificationHeader.notificationClassId->minorId
 != 0x65) {
+                               NTF_API_Initialize[subscriptionId].result = 
TEST_FAIL;
+                               break;
+                       }
+
+                       if 
(notification->notification.stateChangeNotification.changedStates[0].newState 
!= SA_CKPT_SECTION_RESOURCES_EXHAUSTED) {
+                               NTF_API_Initialize[subscriptionId].result = 
TEST_FAIL;
+                               break;
+                       }
+
+                       if 
(notification->notification.stateChangeNotification.changedStates[0].oldStatePresent
 != SA_FALSE) {
+                               NTF_API_Initialize[subscriptionId].result = 
TEST_FAIL;
+                               break;
+                       }
+               } else if (tcd.ntfTest == CKPT_NTF_RESOURCES_AVAILABLE) {
+                       if 
(notification->notification.stateChangeNotification.notificationHeader.notificationClassId->minorId
 != 0x66) {
+                               NTF_API_Initialize[subscriptionId].result = 
TEST_FAIL;
+                               break;
+                       }
+
+                       if 
(notification->notification.stateChangeNotification.changedStates[0].newState 
!= SA_CKPT_SECTION_RESOURCES_AVAILABLE) {
+                               NTF_API_Initialize[subscriptionId].result = 
TEST_FAIL;
+                               break;
+                       }
+
+                       if 
(notification->notification.stateChangeNotification.changedStates[0].oldStatePresent
 != SA_TRUE) {
+                               NTF_API_Initialize[subscriptionId].result = 
TEST_FAIL;
+                               break;
+                       }
+
+                       if 
(notification->notification.stateChangeNotification.changedStates[0].oldState 
!= SA_CKPT_SECTION_RESOURCES_EXHAUSTED) {
+                               NTF_API_Initialize[subscriptionId].result = 
TEST_FAIL;
+                               break;
+                       }
+               } else {
+                       assert(false);
+                       break;
+               }
+       } while (false);
+}
+
+int test_ckptNtfStateChange(int i, CONFIG_FLAG cfg_flg)
+{
+       SaAisErrorT rc;
+       int result = TEST_PASS;
+       fd_set read_fd;
+
+       FD_ZERO(&read_fd);
+       FD_SET(tcd.ntfSelObj, &read_fd);
+       rc = select(tcd.ntfSelObj + 1, &read_fd, NULL, NULL, NULL);
+       if (rc == -1) {
+               m_TEST_CPSV_PRINTF("Select FAILED\n");
+               return TEST_FAIL;
+       }
+
+       tcd.ntfTest = i;
+
+       rc = saNtfDispatch(tcd.ntfHandle, SA_DISPATCH_ALL);
+
+       if (rc != SA_AIS_OK)
+               result = TEST_FAIL;
+       else
+               result = NTF_API_Initialize[i].result;
+
+       return result;
+}
+
+int test_ckptNtfInit(int i, CONFIG_FLAG cfg_flg)
+{
+       int result = TEST_PASS;
+
+       do {
+               SaNtfHandleT ntfHandle;
+               SaNtfCallbacksT callbacks = {
+                       ntfCallback,
+                       0
+               };
+               SaVersionT version = { 'A', 1, 0 };
+               SaNtfStateChangeNotificationFilterT stateChangeFilter;
+               SaSelectionObjectT ntfSelObj;
+
+               SaAisErrorT rc = saNtfInitialize(&ntfHandle, &callbacks, 
&version);
+               if (rc != SA_AIS_OK) {
+                       result = TEST_FAIL;
+                       break;
+               }
+
+               rc = saNtfStateChangeNotificationFilterAllocate(
+                       ntfHandle, &stateChangeFilter, 0, 0, 0, 0, 0, 0);
+
+               if (rc != SA_AIS_OK) {
+                       result = TEST_FAIL;
+                       break;
+               }
+
+               SaNtfNotificationTypeFilterHandlesT notificationFilterHandles =
+               {
+                       0, 0, stateChangeFilter.notificationFilterHandle, 0, 0
+               };
+
+               rc = saNtfNotificationSubscribe(&notificationFilterHandles, i);
+
+               if (rc != SA_AIS_OK) {
+                       result = TEST_FAIL;
+                       break;
+               }
+
+               rc = 
saNtfNotificationFilterFree(stateChangeFilter.notificationFilterHandle);
+               if (rc != SA_AIS_OK) {
+                       result = TEST_FAIL;
+                       break;
+               }
+
+               rc = saNtfSelectionObjectGet(ntfHandle, &ntfSelObj);
+               if (rc != SA_AIS_OK) {
+                       result = TEST_FAIL;
+                       break;
+               }
+
+               *NTF_API_Initialize[i].ntfHandle = ntfHandle;
+               *NTF_API_Initialize[i].ntfSelObj = ntfSelObj;
+       } while (false);
+
+       return result;
+}
+
+int test_ckptNtfCleanup(int i, CONFIG_FLAG cfg_flg)
+{
+       int result = TEST_PASS;
+       int rc = saNtfFinalize(*NTF_API_Initialize[i].ntfHandle);
+       if (rc != SA_AIS_OK)
+               result = TEST_FAIL;
+
+       return result;
+}
diff --git a/src/ckpt/apitest/test_cpsv.h b/src/ckpt/apitest/test_cpsv.h
index ec1d2bf..27d7c80 100644
--- a/src/ckpt/apitest/test_cpsv.h
+++ b/src/ckpt/apitest/test_cpsv.h
@@ -18,6 +18,7 @@
 
 #include "saAmf.h"
 #include "saCkpt.h"
+#include "saNtf.h"
 #include "string.h"
 #include "stdio.h"
 #include "math.h"
@@ -248,6 +249,13 @@ struct SafCheckpointReadLarge {
   char *result_string;
 };
 
+struct SafCheckpointNtf {
+  SaNtfHandleT *ntfHandle;
+  SaSelectionObjectT *ntfSelObj;
+  SaCkptCheckpointStatusT expectedStatus;
+  int result;
+};
+
 typedef enum {
   CKPT_INIT_SUCCESS_T = 1,
   CKPT_INIT_NULL_CBKS_T,
@@ -382,6 +390,11 @@ typedef enum {
 } CKPT_SECTION_CREATE_TC_TYPE;
 
 typedef enum {
+  CKPT_NTF_RESOURCES_EXHAUSTED,
+  CKPT_NTF_RESOURCES_AVAILABLE
+} CKPT_NTF_TC_TYPE;
+
+typedef enum {
   CKPT_EXP_BAD_HANDLE_T = 1,
   CKPT_EXP_INVALID_PARAM_T,
   CKPT_EXP_ERR_ACCESS_T,
diff --git a/src/ckpt/apitest/test_cpsv_conf.h 
b/src/ckpt/apitest/test_cpsv_conf.h
index 51406f9..68522de 100644
--- a/src/ckpt/apitest/test_cpsv_conf.h
+++ b/src/ckpt/apitest/test_cpsv_conf.h
@@ -143,6 +143,11 @@ struct cpsv_testcase_data {
   SaAisErrorT sync_clbk_err;
   int arr_clbk_flag;
   int arr_clbk_err;
+
+  // NTF data
+  SaNtfHandleT ntfHandle;
+  SaSelectionObjectT ntfSelObj;
+  int ntfTest;
 };
 
 struct cpsv_testcase_data tcd;
@@ -170,6 +175,9 @@ extern int test_ckptSynchronizeAsync(int i, CONFIG_FLAG 
cfg_flg);
 extern int test_ckptIterationInit(int i, CONFIG_FLAG cfg_flg);
 extern int test_ckptIterationNext(int i, CONFIG_FLAG cfg_flg);
 extern int test_ckptIterationFin(int i, CONFIG_FLAG cfg_flg);
+extern int test_ckptNtfInit(int i, CONFIG_FLAG cfg_flg);
+extern int test_ckptNtfCleanup(int i, CONFIG_FLAG cfg_flg);
+extern int test_ckptNtfStateChange(int i, CONFIG_FLAG cfg_flg);
 extern int test_red_ckptInitialize(int i, CONFIG_FLAG cfg_flg);
 extern int test_red_ckptSelectionObject(int i, CONFIG_FLAG cfg_flg);
 extern int test_red_ckptDispatch(int i, CONFIG_FLAG cfg_flg);
diff --git a/src/ckpt/ckptnd/cpnd_cb.h b/src/ckpt/ckptnd/cpnd_cb.h
index 78853c2..91cc6c7 100644
--- a/src/ckpt/ckptnd/cpnd_cb.h
+++ b/src/ckpt/ckptnd/cpnd_cb.h
@@ -201,6 +201,8 @@ typedef struct cpnd_ckpt_node {
   CPND_TMR ret_tmr;
   bool is_restart;
   bool is_ckpt_onscxb;
+  bool resourceExhaustedSent;
+  bool resourceAvailableSent;
   uint32_t cur_state;
   uint32_t oth_state;
   /*   uint32_t                               read_lck_cnt; */
@@ -312,6 +314,7 @@ typedef struct cpnd_cb_tag {
   SaSelectionObjectT clm_sel_obj;
   SaClmNodeIdT nodeid;
   SaAmfHandleT amf_hdl; /* AMF handle, obtained thru AMF init        */
+  SaNtfHandleT ntf_hdl;
   uint8_t *cpnd_res_shm_name;
   bool cpnd_first_time;
   bool read_lck_flag;
diff --git a/src/ckpt/ckptnd/cpnd_evt.c b/src/ckpt/ckptnd/cpnd_evt.c
index 2070163..0c93fe8 100644
--- a/src/ckpt/ckptnd/cpnd_evt.c
+++ b/src/ckpt/ckptnd/cpnd_evt.c
@@ -477,6 +477,109 @@ void cpnd_process_evt(CPSV_EVT *evt)
 }
 
 /****************************************************************************
+ * Name          : sendStateChangeNotification
+ *
+ * Description   : send an NTF state change notification
+ *
+ * Arguments     : CPND_CB *cb - CPND CB pointer
+ *                 CPND_CKPT_NODE *node - Checkpoint Node
+ *                 SaCkptCheckpointStatusT status - notification status
+ *
+ * Return Values : None.
+ *
+ * Notes         : None.
+ *****************************************************************************/
+static void sendStateChangeNotification(CPND_CB *cb,
+                                       CPND_CKPT_NODE *node,
+                                       SaCkptCheckpointStatusT status)
+{
+       if ((status == SA_CKPT_SECTION_RESOURCES_EXHAUSTED &&
+               !node->resourceExhaustedSent) ||
+               (status == SA_CKPT_SECTION_RESOURCES_AVAILABLE &&
+               !node->resourceAvailableSent)) {
+               do {
+                       char *name = 0;
+
+                       SaNtfStateChangeNotificationT ntfStateChange = { 0 };
+
+                       SaAisErrorT rc = saNtfStateChangeNotificationAllocate(
+                               cb->ntf_hdl,
+                               &ntfStateChange,
+                               1, /* numCorrelated Notifications */
+                               0, /* length addition text */
+                               0, /* num additional info */
+                               1, /* num of state changes */
+                               0); /* variable data size */
+
+                       if (rc != SA_AIS_OK) {
+                               LOG_ER("saNtfStateChangeNotificationAllocate 
failed: %i", rc);
+                               break;
+                       }
+
+                       *ntfStateChange.notificationHeader.eventType =
+                               SA_NTF_OBJECT_STATE_CHANGE;
+
+                       name = malloc(strlen(node->ckpt_name) + 1);
+                       strcpy(name, node->ckpt_name);
+                       name[strlen(node->ckpt_name)] = '\0';
+                       osaf_extended_name_steal(
+                               name,
+                               
ntfStateChange.notificationHeader.notificationObject);
+
+                       name = malloc(sizeof("safApp=safCkptService"));
+                       strcpy(name, "safApp=safCkptService");
+                       name[sizeof("safApp=safCkptService") - 1] = '\0';
+                       osaf_extended_name_steal(
+                               name,
+                               
ntfStateChange.notificationHeader.notifyingObject);
+
+                       
ntfStateChange.notificationHeader.notificationClassId->vendorId =
+                               SA_NTF_VENDOR_ID_SAF;
+                       
ntfStateChange.notificationHeader.notificationClassId->majorId =
+                               SA_SVC_CKPT;
+                       
ntfStateChange.notificationHeader.notificationClassId->minorId =
+                               (status == SA_CKPT_SECTION_RESOURCES_EXHAUSTED) 
?
+                                       0x65 : 0x66;
+
+                       *ntfStateChange.sourceIndicator = 
SA_NTF_OBJECT_OPERATION;
+
+                       ntfStateChange.changedStates[0].stateId =
+                               SA_CKPT_CHECKPOINT_STATUS;
+
+                       ntfStateChange.changedStates[0].oldStatePresent =
+                               (status == SA_CKPT_SECTION_RESOURCES_EXHAUSTED) 
?
+                                       SA_FALSE : SA_TRUE;
+
+                       if (status == SA_CKPT_SECTION_RESOURCES_AVAILABLE) {
+                               ntfStateChange.changedStates[0].oldState =
+                                       SA_CKPT_SECTION_RESOURCES_EXHAUSTED;
+                       }
+
+                       ntfStateChange.changedStates[0].newState = status;
+
+                       rc = 
saNtfNotificationSend(ntfStateChange.notificationHandle);
+
+                       if (rc != SA_AIS_OK)
+                               LOG_ER("saNtfNotificationSend failed: %i", rc);
+                       else {
+                               if (status == 
SA_CKPT_SECTION_RESOURCES_EXHAUSTED) {
+                                       node->resourceExhaustedSent = true;
+                                       node->resourceAvailableSent = false;
+                               } else {
+                                       node->resourceAvailableSent = true;
+                                       node->resourceExhaustedSent = false;
+                               }
+                       }
+
+                       rc = 
saNtfNotificationFree(ntfStateChange.notificationHandle);
+
+                       if (rc != SA_AIS_OK)
+                               LOG_ER("saNtfNotificationFree failed: %i", rc);
+               } while (false);
+       }
+}
+
+/****************************************************************************
  * Name          : cpnd_evt_proc_ckpt_init
  *
  * Description   : Function to process the SaCkptInitialize from clients
@@ -2664,6 +2767,9 @@ static uint32_t cpnd_evt_proc_ckpt_sect_create(CPND_CB 
*cb, CPND_EVT *evt,
                        send_evt.info.cpa.type = CPA_EVT_ND2A_SEC_CREATE_RSP;
                        send_evt.info.cpa.info.sec_creat_rsp.error =
                            SA_AIS_ERR_NO_SPACE;
+                       sendStateChangeNotification(cb,
+                                                       cp_node,
+                                                       
SA_CKPT_SECTION_RESOURCES_EXHAUSTED);
                        goto agent_rsp;
                }
 
@@ -2698,6 +2804,9 @@ static uint32_t cpnd_evt_proc_ckpt_sect_create(CPND_CB 
*cb, CPND_EVT *evt,
                                            CPA_EVT_ND2A_SEC_CREATE_RSP;
                                        send_evt.info.cpa.info.sec_creat_rsp
                                            .error = SA_AIS_ERR_NO_SPACE;
+                                       sendStateChangeNotification(cb,
+                                               cp_node,
+                                               
SA_CKPT_SECTION_RESOURCES_EXHAUSTED);
                                        goto agent_rsp;
                                }
 
@@ -3148,6 +3257,10 @@ static uint32_t cpnd_evt_proc_ckpt_sect_delete(CPND_CB 
*cb, CPND_EVT *evt,
                if (sec_info->ckpt_sec_exptmr.is_active)
                        cpnd_tmr_stop(&sec_info->ckpt_sec_exptmr);
                m_CPND_FREE_CKPT_SECTION(sec_info);
+
+               sendStateChangeNotification(cb,
+                       cp_node,
+                       SA_CKPT_SECTION_RESOURCES_AVAILABLE);
        } else {
                TRACE_4("cpnd ckpt sect del failed for sec_id:%s,ckpt_id:%llx",
                        evt->info.sec_delReq.sec_id.id, cp_node->ckpt_id);
diff --git a/src/ckpt/ckptnd/cpnd_init.c b/src/ckpt/ckptnd/cpnd_init.c
index 398faac..2251773 100644
--- a/src/ckpt/ckptnd/cpnd_init.c
+++ b/src/ckpt/ckptnd/cpnd_init.c
@@ -55,6 +55,7 @@ static uint32_t cpnd_cb_db_destroy(CPND_CB *cb);
 
 static bool cpnd_clear_mbx(NCSCONTEXT arg, NCSCONTEXT msg);
 
+static SaAisErrorT cpnd_ntf_init(void);
 static SaAisErrorT cpnd_clm_init(void);
 
 static SaAisErrorT cpnd_start_clm_init_bg();
@@ -239,6 +240,13 @@ static uint32_t cpnd_lib_init(CPND_CREATE_INFO *info)
                goto cpnd_ipc_att_fail;
        }
 
+       /* Initialize the NTF service */
+       rc = cpnd_ntf_init();
+       if (rc != SA_AIS_OK) {
+               LOG_ER("cpnd ntf init failed with return value:%d", rc);
+               goto cpnd_ntf_init_fail;
+       }
+
        /* Initalize the CLM service */
        rc = cpnd_clm_init();
        if (rc != SA_AIS_OK) {
@@ -325,6 +333,7 @@ cpnd_mds_fail:
 cpnd_clm_init_fail:
        m_NCS_IPC_DETACH(&cb->cpnd_mbx, cpnd_clear_mbx, cb);
 
+cpnd_ntf_init_fail:
 cpnd_ipc_att_fail:
        m_NCS_IPC_RELEASE(&cb->cpnd_mbx, NULL);
 
@@ -605,6 +614,54 @@ void cpnd_main_process(CPND_CB *cb)
 }
 
 /****************************************************************************
+ * Name          : cpnd_ntf_init
+ *
+ * Description   : This function initializes NTF
+ *
+ * Arguments     : -
+ *
+ * Return Values : -
+ *
+ * Notes         : None.
+ *****************************************************************************/
+static SaAisErrorT cpnd_ntf_init(void)
+{
+       SaAisErrorT rc = SA_AIS_OK;
+
+       TRACE_ENTER();
+
+       do {
+               CPND_CB *cb = m_CPND_TAKE_CPND_CB;
+               SaVersionT ntf_version = { 'A', 1, 1 };
+               SaNtfHandleT ntfHandle;
+               int retries = 5;
+
+               while (retries--) {
+                       rc = saNtfInitialize(&ntfHandle, 0, &ntf_version);
+                       if (rc == SA_AIS_OK) {
+                               break;
+                       } else if (rc == SA_AIS_ERR_TRY_AGAIN) {
+                               osaf_nanosleep(&kOneSecond);
+                       } else {
+                               LOG_WA("saNtfInitialize returned %u", rc);
+                               break;
+                       }
+               }
+
+               if (rc != SA_AIS_OK) {
+                       LOG_ER("cpnd clm init failed with return value:%d", rc);
+                       break;
+               }
+
+               cb->ntf_hdl = ntfHandle;
+       } while (false);
+
+       TRACE_LEAVE();
+
+       return rc;
+}
+
+/****************************************************************************
  * Name          : cpnd_clm_init
  *
  * Description   : This function initialize CLM, get Node Id, and enalbe
-- 
2.9.5


------------------------------------------------------------------------------
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