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(¬ificationFilterHandles, 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