See comment inline. regards, Anders Widell
On 02/19/2016 11:05 AM, praveen malviya wrote: > > > On 19-Feb-16 2:17 PM, Anders Widell wrote: >> Hi! >> >> See my comment inline, marked [AndersW]. >> >> regards, >> Anders Widell >> >> On 02/19/2016 07:01 AM, praveen malviya wrote: >>> Please see responses with [Praveen]. >>> >>> Thanks, >>> Praveen >>> >>> On 18-Feb-16 9:41 PM, Lennart Lund wrote: >>>> Please see responses with [Lennart] >>>> >>>> Thanks >>>> Lennart >>>> >>>>> -----Original Message----- >>>>> From: praveen malviya [mailto:praveen.malv...@oracle.com] >>>>> Sent: den 18 februari 2016 14:02 >>>>> To: Minh Chau H; Lennart Lund; Vu Minh Nguyen >>>>> Cc: opensaf-devel@lists.sourceforge.net >>>>> Subject: Re: [PATCH 1 of 5] NTF: Add support cloud resilience for >>>>> NTF Agent >>>>> [#1180] >>>>> >>>>> Please see the responses with [Praveen] >>>>> >>>>> Thanks, >>>>> Praveen >>>>> >>>>> On 12-Feb-16 8:52 PM, minh chau wrote: >>>>>> Hi Praveen, >>>>>> >>>>>> Please find my comments inline [Minh] >>>>>> >>>>>> Thanks, >>>>>> Minh >>>>>> >>>>>> On 12/02/16 22:10, praveen malviya wrote: >>>>>>> Hi Minh, >>>>>>> >>>>>>> Please find some initial comments and questions marked with >>>>>>> [Praveen]. >>>>>>> >>>>>>> One question regarding the approach. >>>>>>> In most of the changed APIs from saNtfInitialize() to >>>>>>> saNtfNotificationReadFinalize(), clients are being recovered. >>>>>>> Why the >>>>>>> idea of recovering them is not considered in mds callback itself in >>>>>>> the function call ntfa_update_ntfsv_state() when server state >>>>>>> changes >>>>>>> from DOWN to UP. It will save changes in APIs for recovering the >>>>>>> clients. Clients are being marked invalid in the mds_callback >>>>>>> itself. >>>>>>> >>>>>> [Minh] From memory I did try to recover clients in mds callback >>>>>> (svc_evt) where indicates server UP. Though recovery needs to send >>>>>> messages (reintroducing client id, read id, ...) to server, that >>>>>> will >>>>>> end up another mds enc callback inside of first callback. That >>>>>> results >>>>>> into fail to send *recovery* messages, there are two mds callback >>>>>> but >>>>>> only one return. To solve this, I need to start a thread the recover >>>>>> clients in background. That would cause another problem where up >>>>>> calls >>>>>> from client could be blocked, since the recovery thread needs to >>>>>> block >>>>>> mutual resource handles. >>>>>> Another realistic reason, client can give up to send/read/receive >>>>>> notification after receiving couple times of TRY_AGAIN due to server >>>>>> down, and doing nothing until finalize handle. And after client >>>>>> stops >>>>>> TRY_AGAIN loop, server can be restarted. In such cases, no needs to >>>>>> recover client handles. >>>>>>> Thanks, >>>>>>> Praveen >>>>>>> >>>>>>> On 23-Dec-15 9:32 AM, Minh Hon Chau wrote: >>>>>>>> osaf/libs/agents/saf/ntfa/ntfa.h | 31 +- >>>>>>>> osaf/libs/agents/saf/ntfa/ntfa_api.c | 672 >>>>>>>> +++++++++++++++++++++++++++------ >>>>>>>> osaf/libs/agents/saf/ntfa/ntfa_mds.c | 6 +- >>>>>>>> osaf/libs/agents/saf/ntfa/ntfa_util.c | 465 >>>>> ++++++++++++++++++++++- >>>>>>>> 4 files changed, 1022 insertions(+), 152 deletions(-) >>>>>>>> >>>>>>>> >>>>>>>> The patch contains support for cloud resilience feature >>>>>>>> in NTF Agent code. Please refer README.HYDRA for content >>>>>>>> of the changes >>>>>>>> >>>>>>>> diff --git a/osaf/libs/agents/saf/ntfa/ntfa.h >>>>>>>> b/osaf/libs/agents/saf/ntfa/ntfa.h >>>>>>>> --- a/osaf/libs/agents/saf/ntfa/ntfa.h >>>>>>>> +++ b/osaf/libs/agents/saf/ntfa/ntfa.h >>>>>>>> @@ -91,6 +91,7 @@ typedef struct ntfa_filter_hdl_rec { >>>>>>>> typedef struct subscriberList { >>>>>>>> SaNtfHandleT subscriberListNtfHandle; >>>>>>>> SaNtfSubscriptionIdT subscriberListSubscriptionId; >>>>>>>> + ntfsv_filter_ptrs_t filters; /* remember the filters used by >>>>>>>> this subscriber */ >>>>>>>> struct subscriberList *prev; >>>>>>>> struct subscriberList *next; >>>>>>>> } ntfa_subscriber_list_t; >>>>>>>> @@ -100,6 +101,10 @@ typedef struct ntfa_reader_hdl_rec { >>>>>>>> unsigned int reader_id; /* handle value returned by >>>>>>>> NTFS for >>>>>>>> this client */ >>>>>>>> SaNtfHandleT ntfHandle; >>>>>>>> unsigned int reader_hdl; /* READER handle from handle >>>>>>>> mgr */ >>>>>>>> + >>>>>>>> + ntfsv_filter_ptrs_t filters; /* remember the filters used by >>>>>>>> this reader */ >>>>>>>> + SaNtfSearchCriteriaT searchCriteria; /* remember the >>>>>>>> searchCriteria for recovery */ >>>>>>>> + >>>>>>>> struct ntfa_reader_hdl_rec *next; /* next pointer >>>>>>>> for the >>>>>>>> list in ntfa_cb_t */ >>>>>>>> struct ntfa_client_hdl_rec *parent_hdl; /* Back >>>>>>>> Pointer to >>>>>>>> the client instantiation */ >>>>>>>> } ntfa_reader_hdl_rec_t; >>>>>>>> @@ -114,24 +119,35 @@ typedef struct ntfa_client_hdl_rec { >>>>>>>> ntfa_reader_hdl_rec_t *reader_list; >>>>>>>> SYSF_MBX mbx; /* priority q mbx b/w MDS & >>>>>>>> Library */ >>>>>>>> struct ntfa_client_hdl_rec *next; /* next pointer >>>>>>>> for the >>>>>>>> list in ntfa_cb_t */ >>>>>>>> + bool valid; /* handle is valid if it's known by NTF >>>>>>>> server, used for headless hydra */ >>>>>>>> + SaVersionT version; /* the API version is being used by >>>>>>>> client, >>>>>>>> used for recover after headless */ >>>>>>>> } ntfa_client_hdl_rec_t; >>>>>>>> >>>>>>>> /* >>>>>>>> * The NTFA control block is the master anchor structure for >>>>>>>> all NTFA >>>>>>>> * instantiations within a process. >>>>>>>> */ >>>>>>>> +typedef enum { >>>>>>>> + NTFA_NTFSV_NONE = 0, >>>>>>>> + NTFA_NTFSV_DOWN, >>>>>>>> + NTFA_NTFSV_NO_ACTIVE, >>>>>>>> + NTFA_NTFSV_NEW_ACTIVE, >>>>>>>> + NTFA_NTFSV_UP >>>>>>>> +}ntfa_ntfsv_state_t; >>>>>>>> + >>>>>>>> typedef struct { >>>>>>>> pthread_mutex_t cb_lock; /* CB lock */ >>>>>>>> ntfa_client_hdl_rec_t *client_list; /* NTFA client >>>>>>>> handle >>>>>>>> database */ >>>>>>>> ntfa_reader_hdl_rec_t *reader_list; >>>>>>>> MDS_HDL mds_hdl; /* MDS handle */ >>>>>>>> MDS_DEST ntfs_mds_dest; /* NTFS absolute/virtual >>>>>>>> address */ >>>>>>>> - int ntfs_up; /* Indicate that MDS subscription >>>>>>>> - * is complete */ >>>>>>>> + >>>>>>>> /* NTFS NTFA sync params */ >>>>>>>> int ntfs_sync_awaited; >>>>>>>> NCS_SEL_OBJ ntfs_sync_sel; >>>>>>>> SaUint32T ntf_var_data_limit; /* max allowed >>>>>>>> variableDataSize */ >>>>>>>> + /* NTF Server state */ >>>>>>>> + ntfa_ntfsv_state_t ntfa_ntfsv_state; >>>>>>>> } ntfa_cb_t; >>>>>>>> >>>>>>>> /* ntfa_saf_api.c */ >>>>>>>> @@ -149,7 +165,7 @@ extern void ntfsv_ntfa_evt_free(struct n >>>>>>>> >>>>>>>> /* ntfa_init.c */ >>>>>>>> extern unsigned int ntfa_startup(void); >>>>>>>> -extern unsigned int ntfa_shutdown(void); >>>>>>>> +extern unsigned int ntfa_shutdown(bool forced); >>>>>>>> >>>>>>>> /* ntfa_hdl.c */ >>>>>>>> extern SaAisErrorT ntfa_hdl_cbk_dispatch(ntfa_cb_t *, >>>>>>>> ntfa_client_hdl_rec_t *, SaDispatchFlagsT); >>>>>>>> @@ -159,6 +175,7 @@ extern ntfa_notification_hdl_rec_t *ntfa >>>>>>>> extern ntfa_filter_hdl_rec_t >>>>>>>> *ntfa_filter_hdl_rec_add(ntfa_client_hdl_rec_t **hdl_rec); >>>>>>>> extern void ntfa_hdl_list_del(ntfa_client_hdl_rec_t **); >>>>>>>> extern uint32_t ntfa_hdl_rec_del(ntfa_client_hdl_rec_t **, >>>>>>>> ntfa_client_hdl_rec_t *); >>>>>>>> +extern void ntfa_hdl_rec_force_del(ntfa_client_hdl_rec_t **, >>>>>>>> ntfa_client_hdl_rec_t *); >>>>>>>> extern uint32_t >>>>>>>> ntfa_notification_hdl_rec_del(ntfa_notification_hdl_rec_t **, >>>>>>>> ntfa_notification_hdl_rec_t *); >>>>>>>> extern uint32_t ntfa_filter_hdl_rec_del(ntfa_filter_hdl_rec_t >>>>>>>> **, >>>>>>>> ntfa_filter_hdl_rec_t *); >>>>>>>> extern bool ntfa_validate_ntfa_client_hdl(ntfa_cb_t *ntfa_cb, >>>>>>>> ntfa_client_hdl_rec_t *find_hdl_rec); >>>>>>>> @@ -166,11 +183,15 @@ extern bool ntfa_validate_ntfa_client_hd >>>>>>>> /* ntfa_util.c */ >>>>>>>> extern ntfa_client_hdl_rec_t >>>>>>>> *ntfa_find_hdl_rec_by_client_id(ntfa_cb_t *ntfa_cb, uint32_t >>>>> client_id); >>>>>>>> extern void ntfa_msg_destroy(ntfsv_msg_t *msg); >>>>>>>> -extern void ntfa_hdl_rec_destructor(ntfa_notification_hdl_rec_t >>>>>>>> *instance); >>>>>>>> -extern void ntfa_filter_hdl_rec_destructor(ntfa_filter_hdl_rec_t >>>>>>>> +extern void >>>>>>>> ntfa_notification_destructor(ntfa_notification_hdl_rec_t >>>>>>>> *instance); >>>>>>>> +extern void ntfa_filter_destructor(ntfa_filter_hdl_rec_t >>>>>>>> *notificationFilterInstance); >>>>>>>> extern ntfa_reader_hdl_rec_t >>>>>>>> *ntfa_reader_hdl_rec_add(ntfa_client_hdl_rec_t **hdl_rec); >>>>>>>> extern uint32_t ntfa_reader_hdl_rec_del(ntfa_reader_hdl_rec_t >>>>>>>> **, >>>>>>>> ntfa_reader_hdl_rec_t *); >>>>>>>> extern void ntfa_add_to_async_cbk_msg_list(ntfsv_msg_t ** >>>>>>>> head, >>>>>>>> ntfsv_msg_t * new_node); >>>>>>>> extern uint32_t ntfa_ntfs_msg_proc(ntfa_cb_t *cb, ntfsv_msg_t >>>>>>>> *ntfsv_msg, MDS_SEND_PRIORITY_TYPE prio); >>>>>>>> +extern void ntfa_update_ntfsv_state(ntfa_ntfsv_state_t >>>>> changedState); >>>>>>>> +extern SaAisErrorT ntfa_copy_ntf_filter_ptrs(ntfsv_filter_ptrs_t* >>>>> pDes, >>>>>>>> + const ntfsv_filter_ptrs_t* pSrc); >>>>>>>> +extern SaAisErrorT ntfa_del_ntf_filter_ptrs(ntfsv_filter_ptrs_t* >>>>>>>> filter_ptrs); >>>>>>>> #endif /* !NTFA_H */ >>>>>>>> diff --git a/osaf/libs/agents/saf/ntfa/ntfa_api.c >>>>>>>> b/osaf/libs/agents/saf/ntfa/ntfa_api.c >>>>>>>> --- a/osaf/libs/agents/saf/ntfa/ntfa_api.c >>>>>>>> +++ b/osaf/libs/agents/saf/ntfa/ntfa_api.c >>>>>>>> @@ -34,11 +34,42 @@ >>>>>>>> /* The main controle block */ >>>>>>>> ntfa_cb_t ntfa_cb = { >>>>>>>> .cb_lock = PTHREAD_MUTEX_INITIALIZER, >>>>>>>> + .ntfa_ntfsv_state = NTFA_NTFSV_NONE, >>>>>>>> }; >>>>>>>> >>>>>>>> /* list of subscriptions for this process */ >>>>>>>> ntfa_subscriber_list_t *subscriberNoList = NULL; >>>>>>>> >>>>>>>> +/* >>>>>>>> + * @Brief: Determine the common "availability" of API, which >>>>>>>> depends >>>>>>>> on the >>>>>>>> + * NTF Server state >>>>>>>> + * @Param: None >>>>>>>> + * @Return: OK - If Server state is UP >>>>>>>> + * TRY_AGAIN - If Server state is No Active >>>>>>>> (temporary no >>>>>>>> active) >>>>>>>> + * BAD_HANDLE - If Server state is completely Down (no >>>>>>>> active at all). >>>>>>>> + * This error code will be returned to >>>>>>>> client >>>>>>>> calling API >>>>>>>> + */ >>>>>>>> +static SaAisErrorT checkNtfServerState() >>>>>>>> +{ >>>>>>>> + SaAisErrorT rc = SA_AIS_ERR_NOT_SUPPORTED; >>>>>>>> + /* Check NTF server availability */ >>>>>>>> + if (ntfa_cb.ntfa_ntfsv_state == NTFA_NTFSV_UP) { >>>>>>>> + rc = SA_AIS_OK; >>>>>>>> + } else if (ntfa_cb.ntfa_ntfsv_state == NTFA_NTFSV_DOWN) { >>>>>>>> + TRACE("NTFS server is down"); >>>>>>>> + rc = SA_AIS_ERR_TRY_AGAIN; >>>>>>> [Praveen] 1. Function header says BAD_HANDLE for "down" but here >>>>>>> TRY_AGAIN is returned. >>>>>> [Minh]: I got similar comments from Lennart, I will correct the >>>>>> function >>>>>> description >>>>>>> 2. If server state is down, it means both ntfs are not up which >>>>>>> means >>>>>>> headless cluster. But in case of normal cluster also application >>>>>>> will >>>>>>> get TRY_AGAIN. Are you relying on the fact that in >>>>>>> normal >>>>>>> cluster case payloads will be rebooted? if answer is yes then >>>>>>> what if >>>>>>> reboot is delayed by changing the opensaf_reboot script which is >>>>>>> customizable? >>>>>> [Minh]: I don't get your question. No impact if payloads reboot >>>>> [Praveen] Actually I want draw attention to two problems here: >>>>> 1) Normal cluster case: Both controllers are up in normal cluster >>>>> (attribute commented in immd.conf) and some ntf application is >>>>> running >>>>> on the payload. Now if opensaf is stopped on the payload, application >>>>> will still get TRY_AGIAN. Now if a fresh controller is started and >>>>> payload is not started, the application API will be successful. But >>>>> this >>>>> application should not be able to get a success for any API since its >>>>> payload is down. >>>>> 2) Headless cluster case: Same case when with headless cluster >>>>> configured (attribute un-commented in immd.conf). >>>>> >>>>> I think this may be the generic problem with all the service with two >>>>> tier architecture and a fix is needed. There should be a mechanism >>>>> though which agent should detect opensaf shutdown on local node and >>>>> clear all clients data. >>>>> >>>>> >>>> [Lennart] I cannot see that there is a problem if an OpenSAF service >>>> that has no node director (ntf and log) can recover and continue to >>>> work >>>> after a headless situation. For this service there is no OpenSAF >>>> running on a payload node. >>>> For the "normal" case (attribute commented in immd.conf) the current >>>> behavior shall apply which is to invalidate all clients if no server >>>> is available (SC-nodes down). There should be no impact at all in any >>>> mode on the ntf and log service if OpenSAF is stopped on the payload >>>> node. >>> As I mentioned this is not the case when controller(s) are down, only >>> bring down the payload when application is running on it. In this case >>> NTFS will not get agent down and it will not clear this client. Also >>> agent only MDS subscribes for NTFS so it will also not detect opensaf >>> down of local node. So the application will continue, in my case Send() >>> API was able to send notification successfully. >>> Anyways I have verified, this is the problem without any headless >>> patches also. >> [AndersW] I think this problem is caused by missing / incomplete >> integration with CLM. If you stop OpenSAF on a payload node, the node >> will no longer be a member of the cluster. NTF ought to return >> SA_AIS_ERR_UNAVAILABLE to client requests from non-member nodes >> according to the A.03.01 spec (see Section 3.12.1 in the A.03.01 spec). >> The OpenSAF implementation is still on the A.01.01 version, though. >> There is a separate enhancement ticket to implement full CLM integration >> in NTF: ticket [#1639]. > > I think even after CLM integration there would be a problem when: > 1) Application obtains valid handles (saNtfInitialize and allocation > of notifications). > 2) Controller goes down and then payload also goes down. > 3) Controller comes up and then payload comes up. Here controller does > not know about any agent up so it cannot send clm node join status to > agent application. > 4)Now application calls Send() API. NTf agent will recover clients and > Send() API will be successful. > Since as of now NTf is not CLM integrated it can be postponed. [AndersW] When recovering clients after headless, the NTF server must check if the node the client is running on is a cluster member node. Recovering a client should work in a similar way as initializing a new client. But yes as you say, this is something that should be solved in the context of ticket [#1639]. > > > Thanks > Praveen >>> >>> Thanks >>> Praveen >>>>>>>> + } else if (ntfa_cb.ntfa_ntfsv_state == >>>>>>>> NTFA_NTFSV_NO_ACTIVE) { >>>>>>>> + TRACE("NTFS server is unavailable"); >>>>>>>> + rc = SA_AIS_ERR_TRY_AGAIN; >>>>>>>> + } else if (ntfa_cb.ntfa_ntfsv_state == NTFA_NTFSV_NONE) { >>>>>>>> + TRACE("No NTF server is detected, or API is called during >>>>>>>> headless"); >>>>>>>> + rc = SA_AIS_ERR_TRY_AGAIN; >>>>>>>> + } else >>>>>>>> + TRACE("Not supported API call under NTF Server state >>>>>>>> (%u)", >>>>>>>> + ntfa_cb.ntfa_ntfsv_state); >>>>>>>> + return rc; >>>>>>>> +} >>>>>>>> + >>>>>>>> static SaAisErrorT checkNtfValueTypeRange(SaNtfValueTypeT >>>>>>>> type) >>>>>>>> { >>>>>>>> return (type < SA_NTF_VALUE_UINT8 || type > >>>>>>>> SA_NTF_VALUE_ARRAY)? SA_AIS_ERR_INVALID_PARAM >>>>>>>> @@ -871,7 +902,266 @@ SaAisErrorT getFilters(const SaNtfNotifi >>>>>>>> } >>>>>>>> >>>>>>>> /* end help functions */ >>>>>>>> - >>>>>>>> >>>>> +/********************************************************* >>>>> ******************* >>>>>>>> + Name : reinitializeClient >>>>>>>> + >>>>>>>> + Description : This routine sends initialize messages to NTF >>>>>>>> Server in >>>>>>>> + order to obtain new client id >>>>>>>> + >>>>>>>> + Arguments : client_hdl* [IN]: client handle >>>>>>>> + >>>>>>>> + Return Values : SA_AIS_OK if success, others are failure >>>>>>>> + >>>>>>>> + Notes : None >>>>>>>> >>>>> +********************************************************* >>>>> *********************/ >>>>>>>> +SaAisErrorT reinitializeClient(ntfa_client_hdl_rec_t* >>>>>>>> client_hdl) { >>>>>>>> + uint32_t mds_rc; >>>>>>>> + SaAisErrorT rc = SA_AIS_OK; >>>>>>>> + ntfsv_msg_t i_msg, *o_msg = NULL; >>>>>>>> + >>>>>>>> + TRACE_ENTER(); >>>>>>>> + >>>>>>>> + memset(&i_msg, 0, sizeof(ntfsv_msg_t)); >>>>>>>> + i_msg.type = NTFSV_NTFA_API_MSG; >>>>>>>> + i_msg.info.api_info.type = NTFSV_INITIALIZE_REQ; >>>>>>>> + i_msg.info.api_info.param.init.version = client_hdl->version; >>>>>>>> + >>>>>>>> + mds_rc = ntfa_mds_msg_sync_send(&ntfa_cb, &i_msg, &o_msg, >>>>>>>> NTFS_WAIT_TIME); >>>>>>>> + switch (mds_rc) { >>>>>>>> + case NCSCC_RC_SUCCESS: >>>>>>>> + break; >>>>>>>> + case NCSCC_RC_REQ_TIMOUT: >>>>>>>> + rc = SA_AIS_ERR_TRY_AGAIN; >>>>>>>> + goto done; >>>>>>>> + default: >>>>>>>> + rc = SA_AIS_ERR_BAD_HANDLE; >>>>>>>> + goto done; >>>>>>>> + } >>>>>>>> + >>>>>>>> + osafassert(o_msg != NULL); >>>>>>>> + /* Check response msg: type, rc */ >>>>>>>> + if (o_msg->info.api_resp_info.type != NTFSV_INITIALIZE_RSP) { >>>>>>>> + TRACE("info.api_resp_info.type:%u", >>>>>>>> o_msg->info.api_resp_info.type); >>>>>>>> + rc = SA_AIS_ERR_LIBRARY; >>>>>>>> + goto done; >>>>>>>> + } >>>>>>>> + if ((rc = o_msg->info.api_resp_info.rc) != SA_AIS_OK) { >>>>>>>> + TRACE("info.api_resp_info.rc:%u", >>>>>>>> o_msg->info.api_resp_info.rc); >>>>>>>> + rc = SA_AIS_ERR_BAD_HANDLE; >>>>>>>> + goto done; >>>>>>>> + } >>>>>>>> + >>>>>>>> + client_hdl->ntfs_client_id = >>>>>>>> o_msg->info.api_resp_info.param.init_rsp.client_id; >>>>>>>> + TRACE("Successfully recover client_id, new client_id:%u", >>>>>>>> + client_hdl->ntfs_client_id); >>>>>>>> + >>>>>>>> +done: >>>>>>>> + if (o_msg) >>>>>>>> + ntfa_msg_destroy(o_msg); >>>>>>>> + TRACE_LEAVE(); >>>>>>>> + return rc; >>>>>>>> +} >>>>>>>> >>>>> +/********************************************************* >>>>> ******************* >>>>>>>> + Name : recoverReader >>>>>>>> + >>>>>>>> + Description : This routine sends read_initialize messages to >>>>>>>> NTF >>>>>>>> Server in >>>>>>>> + order to reintroduce this reader to NTF Server >>>>>>>> + >>>>>>>> + Arguments : client_hdl* [IN]: client handle >>>>>>>> + reader_hdl* [IN]: reader handle >>>>>>>> + >>>>>>>> + Return Values : SA_AIS_OK if success, others are failure >>>>>>>> + >>>>>>>> + Notes : None >>>>>>>> >>>>> +********************************************************* >>>>> *********************/ >>>>>>>> +SaAisErrorT recoverReader(ntfa_client_hdl_rec_t* client_hdl, >>>>>>>> ntfa_reader_hdl_rec_t* reader_hdl) { >>>>>>>> + uint32_t mds_rc; >>>>>>>> + SaAisErrorT rc = SA_AIS_OK; >>>>>>>> + ntfsv_msg_t i_msg, *o_msg = NULL; >>>>>>>> + ntfsv_reader_init_req_2_t *send_param; >>>>>>>> + >>>>>>>> + TRACE_ENTER(); >>>>>>>> + >>>>>>>> + /* Make sure the filters have not been deleted */ >>>>>>>> + if (reader_hdl->filters.alarm_filter == NULL && >>>>>>>> + reader_hdl->filters.att_ch_filter == NULL && >>>>>>>> + reader_hdl->filters.obj_cr_del_filter == NULL && >>>>>>>> + reader_hdl->filters.sec_al_filter == NULL && >>>>>>>> + reader_hdl->filters.sta_ch_filter == NULL) >>>>>>>> + return SA_AIS_ERR_BAD_HANDLE; >>>>>>>> + >>>>>>>> + memset(&i_msg, 0, sizeof(ntfsv_msg_t)); >>>>>>>> + i_msg.type = NTFSV_NTFA_API_MSG; >>>>>>>> + i_msg.info.api_info.type = NTFSV_READER_INITIALIZE_REQ_2; >>>>>>>> + send_param = &i_msg.info.api_info.param.reader_init_2; >>>>>>>> + send_param->head.client_id = client_hdl->ntfs_client_id; >>>>>>>> + send_param->head.searchCriteria = reader_hdl->searchCriteria; >>>>>>>> + send_param->f_rec = reader_hdl->filters; >>>>>>>> + >>>>>>>> + mds_rc = ntfa_mds_msg_sync_send(&ntfa_cb, &i_msg, &o_msg, >>>>>>>> NTFS_WAIT_TIME); >>>>>>>> + >>>>>>>> + switch (mds_rc) { >>>>>>>> + case NCSCC_RC_SUCCESS: >>>>>>>> + break; >>>>>>>> + case NCSCC_RC_REQ_TIMOUT: >>>>>>>> + rc = SA_AIS_ERR_TRY_AGAIN; >>>>>>>> + goto done; >>>>>>>> + default: >>>>>>>> + rc = SA_AIS_ERR_BAD_HANDLE; >>>>>>>> + goto done; >>>>>>>> + } >>>>>>>> + >>>>>>>> + osafassert(o_msg != NULL); >>>>>>>> + if ((rc = o_msg->info.api_resp_info.rc) != SA_AIS_OK) { >>>>>>>> + TRACE("o_msg->info.api_resp_info.rc:%u", >>>>>>>> o_msg->info.api_resp_info.rc); >>>>>>>> + rc = SA_AIS_ERR_BAD_HANDLE; >>>>>>>> + goto done; >>>>>>>> + } >>>>>>>> + >>>>>>>> + if (o_msg->info.api_resp_info.type != >>>>>>>> NTFSV_READER_INITIALIZE_RSP) { >>>>>>>> + TRACE("msg type (%d) failed", >>>>>>>> (int)o_msg->info.api_resp_info.type); >>>>>>>> + rc = SA_AIS_ERR_LIBRARY; >>>>>>>> + goto done; >>>>>>>> + } >>>>>>>> + /* Update reader_id since it may be changed */ >>>>>>>> + reader_hdl->reader_id = >>>>>>>> o_msg->info.api_resp_info.param.reader_init_rsp.readerId; >>>>>>>> + >>>>>>>> + TRACE("Recover reader successfully"); >>>>>>>> +done: >>>>>>>> + if (o_msg) >>>>>>>> + ntfa_msg_destroy(o_msg); >>>>>>>> + TRACE_LEAVE(); >>>>>>>> + return rc; >>>>>>>> +} >>>>>>>> >>>>> +/********************************************************* >>>>> ******************* >>>>>>>> + Name : recoverSubscriber >>>>>>>> + >>>>>>>> + Description : This routine sends subscribe messages to NTF >>>>>>>> Server in >>>>>>>> + order to reintroduce this subscriber to NTF Server >>>>>>>> + >>>>>>>> + Arguments : client_hdl* [IN]: client handle >>>>>>>> + subscriber_hdl* [IN]: subscriber handle >>>>>>>> + >>>>>>>> + Return Values : SA_AIS_OK if success, others are failure >>>>>>>> + >>>>>>>> + Notes : None >>>>>>>> >>>>> +********************************************************* >>>>> *********************/ >>>>>>>> +SaAisErrorT recoverSubscriber(ntfa_client_hdl_rec_t* client_hdl, >>>>>>>> + ntfa_subscriber_list_t* >>>>>>>> subscriber_hdl) { >>>>>>>> + uint32_t mds_rc; >>>>>>>> + SaAisErrorT rc = SA_AIS_OK; >>>>>>>> + ntfsv_msg_t i_msg, *o_msg = NULL; >>>>>>>> + ntfsv_subscribe_req_t *send_param; >>>>>>>> + >>>>>>>> + TRACE_ENTER(); >>>>>>>> + >>>>>>>> + /* Make sure the filters have not been deleted */ >>>>>>>> + if (subscriber_hdl->filters.alarm_filter == NULL && >>>>>>>> + subscriber_hdl->filters.att_ch_filter == NULL && >>>>>>>> + subscriber_hdl->filters.obj_cr_del_filter == NULL && >>>>>>>> + subscriber_hdl->filters.sec_al_filter == NULL && >>>>>>>> + subscriber_hdl->filters.sta_ch_filter == NULL) >>>>>>>> + return SA_AIS_ERR_BAD_HANDLE; >>>>>>>> + >>>>>>>> + memset(&i_msg, 0, sizeof(ntfsv_msg_t)); >>>>>>>> + i_msg.type = NTFSV_NTFA_API_MSG; >>>>>>>> + i_msg.info.api_info.type = NTFSV_SUBSCRIBE_REQ; >>>>>>>> + send_param = &i_msg.info.api_info.param.subscribe; >>>>>>>> + >>>>>>>> + send_param->client_id = client_hdl->ntfs_client_id; >>>>>>>> + send_param->subscriptionId = >>>>>>>> subscriber_hdl->subscriberListSubscriptionId; >>>>>>>> + send_param->f_rec = subscriber_hdl->filters; >>>>>>>> + >>>>>>>> + mds_rc = ntfa_mds_msg_sync_send(&ntfa_cb, &i_msg, &o_msg, >>>>>>>> NTFS_WAIT_TIME); >>>>>>>> + >>>>>>>> + switch (mds_rc) { >>>>>>>> + case NCSCC_RC_SUCCESS: >>>>>>>> + break; >>>>>>>> + case NCSCC_RC_REQ_TIMOUT: >>>>>>>> + rc = SA_AIS_ERR_TRY_AGAIN; >>>>>>>> + goto done; >>>>>>>> + default: >>>>>>>> + rc = SA_AIS_ERR_BAD_HANDLE; >>>>>>>> + goto done; >>>>>>>> + } >>>>>>>> + >>>>>>>> + osafassert(o_msg != NULL); >>>>>>>> + >>>>>>>> + if ((rc = o_msg->info.api_resp_info.rc) != SA_AIS_OK) { >>>>>>>> + TRACE("o_msg->info.api_resp_info.rc:%u", >>>>>>>> o_msg->info.api_resp_info.rc); >>>>>>>> + rc = SA_AIS_ERR_BAD_HANDLE; >>>>>>>> + goto done; >>>>>>>> + } >>>>>>>> + >>>>>>>> + if (o_msg->info.api_resp_info.type != NTFSV_SUBSCRIBE_RSP) { >>>>>>>> + TRACE("msg type (%d) failed", >>>>>>>> (int)o_msg->info.api_resp_info.type); >>>>>>>> + rc = SA_AIS_ERR_LIBRARY; >>>>>>>> + goto done; >>>>>>>> + } >>>>>>>> + TRACE("Recover subscriber successfully"); >>>>>>>> +done: >>>>>>>> + if (o_msg) >>>>>>>> + ntfa_msg_destroy(o_msg); >>>>>>>> + >>>>>>>> + TRACE_LEAVE(); >>>>>>>> + return rc; >>>>>>>> +} >>>>>>>> >>>>> +/********************************************************* >>>>> ******************* >>>>>>>> + Name : recoverClient >>>>>>>> + >>>>>>>> + Description : In NTF-A.03.01, section 2.1.2. A client can be >>>>>>>> producer, >>>>>>>> + subscriber, and reader at the same time. >>>>>>>> + This routine will recovery: >>>>>>>> + (1) client_id >>>>>>>> + (2) Then it will continue the recovery if this client >>>>>>>> also >>>>>>>> + has instance of subscriber or reader. >>>>>>>> + Arguments : client_hdl* [IN]: client handle >>>>>>>> + >>>>>>>> + Return Values : SA_AIS_OK if success, others are failure >>>>>>>> + >>>>>>>> + Notes : None >>>>>>>> >>>>> +********************************************************* >>>>> *********************/ >>>>>>>> +SaAisErrorT recoverClient(ntfa_client_hdl_rec_t *client_hdl) { >>>>>>>> + >>>>>>>> + TRACE_ENTER(); >>>>>>>> + SaAisErrorT rc = SA_AIS_OK; >>>>>>>> + >>>>>>>> + osafassert(client_hdl); >>>>>>>> + >>>>>>>> + if ((rc = reinitializeClient(client_hdl)) == SA_AIS_OK) { >>>>>>>> + /* Restore reader */ >>>>>>>> + ntfa_reader_hdl_rec_t* reader_hdl = >>>>>>>> client_hdl->reader_list; >>>>>>>> + while (reader_hdl != NULL && rc == SA_AIS_OK) { >>>>>>>> + rc = recoverReader(client_hdl, reader_hdl); >>>>>>>> + reader_hdl = reader_hdl->next; >>>>>>>> + } >>>>>>>> + if (rc != SA_AIS_OK) { >>>>>>>> + TRACE("Failed to restore reader (readerId:%d)", >>>>>>>> + reader_hdl->reader_id); >>>>>>>> + goto done; >>>>>>>> + } >>>>>>>> + /* Restore subscriber */ >>>>>>>> + ntfa_subscriber_list_t* subscriber_hdl = >>>>>>>> subscriberNoList; >>>>>>>> + while (subscriber_hdl != NULL && rc == SA_AIS_OK) { >>>>>>>> + if (client_hdl->local_hdl == >>>>>>>> subscriber_hdl->subscriberListNtfHandle) >>>>>>>> + rc = recoverSubscriber(client_hdl, >>>>>>>> subscriber_hdl); >>>>>>>> + subscriber_hdl = subscriber_hdl->next; >>>>>>>> + } >>>>>>>> + if (rc != SA_AIS_OK) { >>>>>>>> + TRACE("Failed to restore subscriber >>>>>>>> (subscriptionId:%d)", >>>>>>>> + subscriber_hdl->subscriberListSubscriptionId); >>>>>>>> + goto done; >>>>>>>> + } >>>>>>>> + client_hdl->valid = true; >>>>>>>> + } else { >>>>>>>> + TRACE("Failed to restore client (id:%d)", >>>>>>>> client_hdl->ntfs_client_id); >>>>>>>> + goto done; >>>>>>>> + } >>>>>>>> + >>>>>>>> +done: >>>>>>>> + TRACE_LEAVE(); >>>>>>>> + return rc; >>>>>>>> +} >>>>>>>> >>>>> /********************************************************** >>>>> ***************** >>>>>>>> * 8.4.1 >>>>>>>> * >>>>>>>> @@ -923,15 +1213,14 @@ SaAisErrorT saNtfInitialize(SaNtfHandleT >>>>>>>> version->releaseCode = NTF_RELEASE_CODE; >>>>>>>> version->majorVersion = NTF_MAJOR_VERSION; >>>>>>>> version->minorVersion = NTF_MINOR_VERSION; >>>>>>>> - ntfa_shutdown(); >>>>>>>> + ntfa_shutdown(false); >>>>>>>> rc = SA_AIS_ERR_VERSION; >>>>>>>> goto done; >>>>>>>> } >>>>>>>> >>>>>>>> - if (!ntfa_cb.ntfs_up) { >>>>>>>> - ntfa_shutdown(); >>>>>>>> - TRACE("NTFS server is down"); >>>>>>>> - rc = SA_AIS_ERR_TRY_AGAIN; >>>>>>>> + /* Check NTF server availability */ >>>>>>>> + if ((rc = checkNtfServerState()) != SA_AIS_OK) { >>>>>>>> + ntfa_shutdown(false); >>>>>>>> goto done; >>>>>>>> } >>>>>>>> >>>>>>>> @@ -977,7 +1266,7 @@ SaAisErrorT saNtfInitialize(SaNtfHandleT >>>>>>>> rc = SA_AIS_ERR_NO_MEMORY; >>>>>>>> goto err; >>>>>>>> } >>>>>>>> - >>>>>>>> + ntfa_hdl_rec->version = *version; >>>>>>>> /* pass the handle value to the appl */ >>>>>>>> if (SA_AIS_OK == rc) >>>>>>>> *ntfHandle = ntfa_hdl_rec->local_hdl; >>>>>>>> @@ -990,7 +1279,7 @@ SaAisErrorT saNtfInitialize(SaNtfHandleT >>>>>>>> >>>>>>>> if (rc != SA_AIS_OK) { >>>>>>>> TRACE_2("NTFA INIT FAILED\n"); >>>>>>>> - ntfa_shutdown(); >>>>>>>> + ntfa_shutdown(false); >>>>>>>> } >>>>>>>> >>>>>>>> done: >>>>>>>> @@ -1101,6 +1390,28 @@ SaAisErrorT saNtfDispatch(SaNtfHandleT n >>>>>>>> goto done; >>>>>>>> } >>>>>>>> >>>>>>>> + /* Need to check NTF server availability here >>>>>>>> + * Because if the notificationCallback just comes after >>>>>>>> MDS_DOWN >>>>>>>> + * it will go to recovery then result in failure due to no >>>>>>>> director >>>>>>>> + */ >>>>>>>> + if ((rc = checkNtfServerState()) != SA_AIS_OK) { >>>>>>>> + ncshm_give_hdl(ntfHandle); >>>>>>>> + goto done; >>>>>>>> + } >>>>>>>> + >>>>>>>> + if (!hdl_rec->valid) { >>>>>>>> + /* recovery */ >>>>>>>> + if ((rc = recoverClient(hdl_rec)) != SA_AIS_OK) { >>>>>>>> + if (rc == SA_AIS_ERR_BAD_HANDLE) { >>>>>>>> + ncshm_give_hdl(ntfHandle); >>>>>>>> + osafassert(pthread_mutex_lock(&ntfa_cb.cb_lock) == 0); >>>>>>>> + ntfa_hdl_rec_force_del(&ntfa_cb.client_list, hdl_rec); >>>>>>>> + osafassert(pthread_mutex_unlock(&ntfa_cb.cb_lock) == 0); >>>>>>>> + ntfa_shutdown(false); >>>>>>>> + goto done; >>>>>>>> + } >>>>>>>> + } >>>>>>>> + } >>>>>>>> if ((rc = ntfa_hdl_cbk_dispatch(&ntfa_cb, hdl_rec, >>>>>>>> dispatchFlags)) != SA_AIS_OK) >>>>>>>> TRACE("NTFA_DISPATCH_FAILURE"); >>>>>>>> >>>>>>>> @@ -1145,6 +1456,13 @@ SaAisErrorT saNtfFinalize(SaNtfHandleT n >>>>>>>> >>>>>>>> TRACE_ENTER(); >>>>>>>> >>>>>>>> + /* Check NTF server availability */ >>>>>>>> + if (ntfa_cb.ntfa_ntfsv_state == NTFA_NTFSV_NO_ACTIVE) { >>>>>>>> + TRACE("NTFS server is temporarily unavailable"); >>>>>>>> + rc = SA_AIS_ERR_TRY_AGAIN; >>>>>>>> + goto done; >>>>>>>> + } >>>>>>>> + >>>>>>>> /* retrieve hdl rec */ >>>>>>>> hdl_rec = ncshm_take_hdl(NCS_SERVICE_ID_NTFA, ntfHandle); >>>>>>>> if (hdl_rec == NULL) { >>>>>>>> @@ -1152,43 +1470,37 @@ SaAisErrorT saNtfFinalize(SaNtfHandleT n >>>>>>>> rc = SA_AIS_ERR_BAD_HANDLE; >>>>>>>> goto done; >>>>>>>> } >>>>>>>> - >>>>>>>> - /* Check Whether NTFS is up or not */ >>>>>>>> - if (!ntfa_cb.ntfs_up) { >>>>>>>> - TRACE("NTFS down"); >>>>>>>> - rc = SA_AIS_ERR_TRY_AGAIN; >>>>>>>> - goto done_give_hdl; >>>>>>>> + if (hdl_rec->valid) { >>>>>>>> + /** populate & send the finalize message >>>>>>>> + ** and make sure the finalize from the server >>>>>>>> + ** end returned before deleting the local records. >>>>>>>> + **/ >>>>>>>> + memset(&msg, 0, sizeof(ntfsv_msg_t)); >>>>>>>> + msg.type = NTFSV_NTFA_API_MSG; >>>>>>>> + msg.info.api_info.type = NTFSV_FINALIZE_REQ; >>>>>>>> + msg.info.api_info.param.finalize.client_id = >>>>>>>> hdl_rec->ntfs_client_id; >>>>>>>> + >>>>>>>> + mds_rc = ntfa_mds_msg_sync_send(&ntfa_cb, &msg, &o_msg, >>>>>>>> NTFS_WAIT_TIME); >>>>>>>> + switch (mds_rc) { >>>>>>>> + case NCSCC_RC_SUCCESS: >>>>>>>> + break; >>>>>>>> + case NCSCC_RC_REQ_TIMOUT: >>>>>>>> + rc = SA_AIS_ERR_TIMEOUT; >>>>>>>> + TRACE("ntfa_mds_msg_sync_send FAILED: %u", rc); >>>>>>>> + goto done_give_hdl; >>>>>>>> + default: >>>>>>>> + TRACE("ntfa_mds_msg_sync_send FAILED: %u", rc); >>>>>>>> + rc = SA_AIS_ERR_NO_RESOURCES; >>>>>>>> + goto done_give_hdl; >>>>>>>> + } >>>>>>>> + >>>>>>>> + if (o_msg != NULL) { >>>>>>>> + rc = o_msg->info.api_resp_info.rc; >>>>>>>> + ntfa_msg_destroy(o_msg); >>>>>>>> + } else >>>>>>>> + rc = SA_AIS_ERR_NO_RESOURCES; >>>>>>>> } >>>>>>>> >>>>>>>> - /** populate & send the finalize message >>>>>>>> - ** and make sure the finalize from the server >>>>>>>> - ** end returned before deleting the local records. >>>>>>>> - **/ >>>>>>>> - memset(&msg, 0, sizeof(ntfsv_msg_t)); >>>>>>>> - msg.type = NTFSV_NTFA_API_MSG; >>>>>>>> - msg.info.api_info.type = NTFSV_FINALIZE_REQ; >>>>>>>> - msg.info.api_info.param.finalize.client_id = >>>>>>>> hdl_rec->ntfs_client_id; >>>>>>>> - >>>>>>>> - mds_rc = ntfa_mds_msg_sync_send(&ntfa_cb, &msg, &o_msg, >>>>>>>> NTFS_WAIT_TIME); >>>>>>>> - switch (mds_rc) { >>>>>>>> - case NCSCC_RC_SUCCESS: >>>>>>>> - break; >>>>>>>> - case NCSCC_RC_REQ_TIMOUT: >>>>>>>> - rc = SA_AIS_ERR_TIMEOUT; >>>>>>>> - TRACE("ntfa_mds_msg_sync_send FAILED: %u", rc); >>>>>>>> - goto done_give_hdl; >>>>>>>> - default: >>>>>>>> - TRACE("ntfa_mds_msg_sync_send FAILED: %u", rc); >>>>>>>> - rc = SA_AIS_ERR_NO_RESOURCES; >>>>>>>> - goto done_give_hdl; >>>>>>>> - } >>>>>>>> - >>>>>>>> - if (o_msg != NULL) { >>>>>>>> - rc = o_msg->info.api_resp_info.rc; >>>>>>>> - ntfa_msg_destroy(o_msg); >>>>>>>> - } else >>>>>>>> - rc = SA_AIS_ERR_NO_RESOURCES; >>>>>>>> - >>>>>>>> if (rc == SA_AIS_OK) { >>>>>>>> /** delete the hdl rec >>>>>>>> ** including all resources allocated by client if >>>>>>>> MDS send is >>>>>>>> @@ -1205,7 +1517,7 @@ SaAisErrorT saNtfFinalize(SaNtfHandleT n >>>>>>>> ncshm_give_hdl(ntfHandle); >>>>>>>> >>>>>>>> if (rc == SA_AIS_OK) { >>>>>>>> - rc = ntfa_shutdown(); >>>>>>>> + rc = ntfa_shutdown(false); >>>>>>>> if (rc != NCSCC_RC_SUCCESS) >>>>>>>> TRACE_1("ntfa_shutdown failed"); >>>>>>>> } >>>>>>>> @@ -1349,7 +1661,7 @@ SaAisErrorT saNtfNotificationFree(SaNtfN >>>>>>>> } >>>>>>>> >>>>>>>> /* free the resources allocated by >>>>>>>> saNtf<ntfType>NotificationAllocate */ >>>>>>>> - ntfa_hdl_rec_destructor(notification_hdl_rec); >>>>>>>> + ntfa_notification_destructor(notification_hdl_rec); >>>>>>>> >>>>>>>> /** Delete the resources related to the >>>>>>>> notificationHandle & >>>>>>>> * remove reference in the client. >>>>>>>> @@ -1419,6 +1731,24 @@ SaAisErrorT saNtfNotificationSend(SaNtfN >>>>>>>> } >>>>>>>> osafassert(pthread_mutex_unlock(&ntfa_cb.cb_lock) == 0); >>>>>>>> >>>>>>>> + /* Check NTF server availability */ >>>>>>>> + if ((rc = checkNtfServerState()) != SA_AIS_OK) >>>>>>>> + goto done_give_hdls; >>>>>>>> + >>>>>>>> + /* Recover if this is invalid handle */ >>>>>>>> + if (!client_rec->valid) { >>>>>>>> + if ((rc = recoverClient(client_rec)) != SA_AIS_OK) { >>>>>>>> + ncshm_give_hdl(client_handle); >>>>>>>> + ncshm_give_hdl(notificationHandle); >>>>>>>> + if (rc == SA_AIS_ERR_BAD_HANDLE) { >>>>>>>> + osafassert(pthread_mutex_lock(&ntfa_cb.cb_lock) == 0); >>>>>>>> + ntfa_hdl_rec_force_del(&ntfa_cb.client_list, client_rec); >>>>>>>> + osafassert(pthread_mutex_unlock(&ntfa_cb.cb_lock) == 0); >>>>>>>> + ntfa_shutdown(false); >>>>>>>> + } >>>>>>>> + goto err_free; >>>>>>>> + } >>>>>>>> + } >>>>>>>> /** >>>>>>>> ** Populate a sync MDS message >>>>>>>> **/ >>>>>>>> @@ -1481,13 +1811,6 @@ SaAisErrorT saNtfNotificationSend(SaNtfN >>>>>>>> goto done_give_hdls; >>>>>>>> } >>>>>>>> >>>>>>>> - /* Check whether NTFS is up or not */ >>>>>>>> - if (!ntfa_cb.ntfs_up) { >>>>>>>> - TRACE("NTFS down"); >>>>>>>> - rc = SA_AIS_ERR_TRY_AGAIN; >>>>>>>> - goto done_give_hdls; >>>>>>>> - } >>>>>>>> - >>>>>>>> /* Send a sync MDS message to obtain a notification id */ >>>>>>>> mds_rc = ntfa_mds_msg_sync_send(&ntfa_cb, &msg, &o_msg, >>>>> timeout); >>>>>>>> switch (mds_rc) { >>>>>>>> @@ -1596,7 +1919,8 @@ static SaNtfHandleT ntfHandleGet(SaNtfS >>>>>>>> return ntfHandle; >>>>>>>> } >>>>>>>> >>>>>>>> -static SaAisErrorT subscriptionListAdd(SaNtfHandleT ntfHandle, >>>>>>>> SaNtfSubscriptionIdT subscriptionId) >>>>>>>> +static SaAisErrorT subscriptionListAdd(SaNtfHandleT ntfHandle, >>>>>>>> SaNtfSubscriptionIdT subscriptionId, >>>>>>>> + ntfsv_filter_ptrs_t >>>>>>>> filters) >>>>>>>> { >>>>>>>> SaAisErrorT rc = SA_AIS_OK; >>>>>>>> ntfa_subscriber_list_t* ntfSubscriberList; >>>>>>>> @@ -1610,7 +1934,9 @@ static SaAisErrorT subscriptionListAdd(S >>>>>>>> /* Add ntfHandle and subscriptionId into list */ >>>>>>>> ntfSubscriberList->subscriberListNtfHandle = ntfHandle; >>>>>>>> ntfSubscriberList->subscriberListSubscriptionId = >>>>>>>> subscriptionId; >>>>>>>> - >>>>>>>> + memset(&ntfSubscriberList->filters, 0, >>>>>>>> sizeof(ntfsv_filter_ptrs_t)); >>>>>>>> + ntfa_copy_ntf_filter_ptrs(&ntfSubscriberList->filters, >>>>>>>> &filters); >>>>>>>> + >>>>>>>> osafassert(pthread_mutex_lock(&ntfa_cb.cb_lock) == 0); >>>>>>>> if (NULL == subscriberNoList) { >>>>>>>> subscriberNoList = ntfSubscriberList; >>>>>>>> @@ -1648,6 +1974,7 @@ static void subscriberListItemRemove(SaN >>>>>>>> subscriberNoList = NULL; >>>>>>>> } >>>>>>>> TRACE_1("REMOVE: listPtr->SubscriptionId %d", >>>>>>>> listPtr->subscriberListSubscriptionId); >>>>>>>> + ntfa_del_ntf_filter_ptrs(&listPtr->filters); >>>>>>>> free(listPtr); >>>>>>>> osafassert(pthread_mutex_unlock(&ntfa_cb.cb_lock) == 0); >>>>>>>> } >>>>>>>> @@ -1666,20 +1993,33 @@ SaAisErrorT saNtfNotificationSubscribe(c >>>>>>>> ntfsv_msg_t msg, *o_msg = NULL; >>>>>>>> ntfsv_subscribe_req_t *send_param; >>>>>>>> uint32_t timeout = NTFS_WAIT_TIME; >>>>>>>> - >>>>>>>> + bool recovery_failed = false; >>>>>>>> TRACE_ENTER(); >>>>>>>> + >>>>>>>> rc = getFilters(notificationFilterHandles, &filters, >>>>>>>> &ntfHandle, &client_hdl_rec); >>>>>>>> if (rc != SA_AIS_OK) { >>>>>>>> TRACE("getFilters failed"); >>>>>>>> goto done; >>>>>>>> } >>>>>>>> >>>>>>>> + /* Check NTF server availability */ >>>>>>>> + if ((rc = checkNtfServerState()) != SA_AIS_OK) >>>>>>>> + goto done; >>>>>>>> + >>>>>>>> + /* recovery */ >>>>>>>> + if (client_hdl_rec != NULL && !client_hdl_rec->valid) { >>>>>>>> + if ((rc = recoverClient(client_hdl_rec)) != SA_AIS_OK) { >>>>>>>> + recovery_failed = true; >>>>>>>> + goto done; >>>>>>>> + } >>>>>>>> + } >>>>>>>> + >>>>>>>> tmpHandle = ntfHandleGet(subscriptionId); >>>>>>>> if (tmpHandle != 0) { >>>>>>>> rc = SA_AIS_ERR_EXIST; >>>>>>>> goto done; >>>>>>>> } >>>>>>>> - rc = subscriptionListAdd(ntfHandle, subscriptionId); >>>>>>>> + rc = subscriptionListAdd(ntfHandle, subscriptionId, filters); >>>>>>>> if (rc != SA_AIS_OK) { >>>>>>>> goto done; >>>>>>>> } >>>>>>>> @@ -1693,29 +2033,24 @@ SaAisErrorT saNtfNotificationSubscribe(c >>>>>>>> send_param->client_id = client_hdl_rec->ntfs_client_id; >>>>>>>> send_param->subscriptionId = subscriptionId; >>>>>>>> send_param->f_rec = filters; >>>>>>>> - /* Check whether NTFS is up or not */ >>>>>>>> - if (ntfa_cb.ntfs_up) { >>>>>>>> - uint32_t rv; >>>>>>>> - /* Send a sync MDS message to obtain a log stream id */ >>>>>>>> - rv = ntfa_mds_msg_sync_send(&ntfa_cb, &msg, &o_msg, >>>>> timeout); >>>>>>>> - if (rv == NCSCC_RC_SUCCESS) { >>>>>>>> - osafassert(o_msg != NULL); >>>>>>>> - if (SA_AIS_OK == o_msg->info.api_resp_info.rc) { >>>>>>>> - TRACE_1("subscriptionId from server %u", >>>>>>>> - o_msg->info.api_resp_info.param.subscribe_rsp.subscriptionId); >>>>>>>> - } else { >>>>>>>> - rc = o_msg->info.api_resp_info.rc; >>>>>>>> - TRACE("Bad return status!!! rc = %d", rc); >>>>>>>> - } >>>>>>>> + >>>>>>>> + uint32_t rv; >>>>>>>> + /* Send a sync MDS message to obtain a log stream id */ >>>>>>>> + rv = ntfa_mds_msg_sync_send(&ntfa_cb, &msg, &o_msg, timeout); >>>>>>>> + if (rv == NCSCC_RC_SUCCESS) { >>>>>>>> + osafassert(o_msg != NULL); >>>>>>>> + if (SA_AIS_OK == o_msg->info.api_resp_info.rc) { >>>>>>>> + TRACE_1("subscriptionId from server %u", >>>>>>>> + o_msg->info.api_resp_info.param.subscribe_rsp.subscriptionId); >>>>>>>> } else { >>>>>>>> - if(rv == NCSCC_RC_INVALID_INPUT) >>>>>>>> - rc = SA_AIS_ERR_INVALID_PARAM; >>>>>>>> - else >>>>>>>> - rc = SA_AIS_ERR_TRY_AGAIN; >>>>>>>> + rc = o_msg->info.api_resp_info.rc; >>>>>>>> + TRACE("Bad return status!!! rc = %d", rc); >>>>>>>> } >>>>>>>> } else { >>>>>>>> - TRACE_1("NTFS down"); >>>>>>>> - rc = SA_AIS_ERR_TRY_AGAIN; >>>>>>>> + if(rv == NCSCC_RC_INVALID_INPUT) >>>>>>>> + rc = SA_AIS_ERR_INVALID_PARAM; >>>>>>>> + else >>>>>>>> + rc = SA_AIS_ERR_TRY_AGAIN; >>>>>>>> } >>>>>>>> >>>>>>>> if (rc != SA_AIS_OK) { >>>>>>>> @@ -1724,6 +2059,7 @@ SaAisErrorT saNtfNotificationSubscribe(c >>>>>>>> if (o_msg) >>>>>>>> ntfa_msg_destroy(o_msg); >>>>>>>> done: >>>>>>>> + >>>>>>>> ncshm_give_hdl(ntfHandle); >>>>>>>> if (notificationFilterHandles) { >>>>>>>> if >>>>>>>> (notificationFilterHandles->attributeChangeFilterHandle) >>>>>>>> @@ -1737,6 +2073,13 @@ SaAisErrorT saNtfNotificationSubscribe(c >>>>>>>> if (notificationFilterHandles->alarmFilterHandle) >>>>>>>> ncshm_give_hdl(notificationFilterHandles->alarmFilterHandle); >>>>>>>> } >>>>>>>> + if (recovery_failed && rc == SA_AIS_ERR_BAD_HANDLE) { >>>>>>>> + osafassert(pthread_mutex_lock(&ntfa_cb.cb_lock) == 0); >>>>>>>> + ntfa_hdl_rec_force_del(&ntfa_cb.client_list, >>>>>>>> client_hdl_rec); >>>>>>>> + osafassert(pthread_mutex_unlock(&ntfa_cb.cb_lock) == 0); >>>>>>>> + ntfa_shutdown(false); >>>>>>>> + } >>>>>>>> + >>>>>>>> TRACE_LEAVE(); >>>>>>>> return rc; >>>>>>>> } >>>>>>>> @@ -1995,6 +2338,7 @@ SaAisErrorT saNtfSecurityAlarmNotificati >>>>>>>> rc = SA_AIS_ERR_INVALID_PARAM; >>>>>>>> goto done; >>>>>>>> } >>>>>>>> + >>>>>>>> /* retrieve hdl rec */ >>>>>>>> hdl_rec = ncshm_take_hdl(NCS_SERVICE_ID_NTFA, ntfHandle); >>>>>>>> if (hdl_rec == NULL) { >>>>>>>> @@ -2058,6 +2402,7 @@ SaAisErrorT saNtfPtrValAllocate(SaNtfNot >>>>>>>> rc = SA_AIS_ERR_INVALID_PARAM; >>>>>>>> goto done; >>>>>>>> } >>>>>>>> + >>>>>>>> notification_hdl_rec = ncshm_take_hdl(NCS_SERVICE_ID_NTFA, >>>>>>>> notificationHandle); >>>>>>>> if (notification_hdl_rec == NULL) { >>>>>>>> TRACE("ncshm_take_hdl notificationHandle failed"); >>>>>>>> @@ -2098,6 +2443,7 @@ SaAisErrorT saNtfArrayValAllocate(SaNtfN >>>>>>>> rc = SA_AIS_ERR_INVALID_PARAM; >>>>>>>> goto done; >>>>>>>> } >>>>>>>> + >>>>>>>> notification_hdl_rec = ncshm_take_hdl(NCS_SERVICE_ID_NTFA, >>>>>>>> notificationHandle); >>>>>>>> if (notification_hdl_rec == NULL) { >>>>>>>> TRACE("ncshm_take_hdl notificationHandle failed"); >>>>>>>> @@ -2228,6 +2574,7 @@ SaAisErrorT saNtfArrayValGet(SaNtfNotifi >>>>>>>> rc = SA_AIS_ERR_INVALID_PARAM; >>>>>>>> goto done; >>>>>>>> } >>>>>>>> + >>>>>>>> notification_hdl_rec = ncshm_take_hdl(NCS_SERVICE_ID_NTFA, >>>>>>>> notificationHandle); >>>>>>>> if (notification_hdl_rec == NULL) { >>>>>>>> TRACE("ncshm_take_hdl notificationHandle failed"); >>>>>>>> @@ -2695,7 +3042,7 @@ SaAisErrorT saNtfNotificationFilterFree( >>>>>>>> } >>>>>>>> >>>>>>>> /* free the resources allocated by >>>>>>>> saNtf<ntfType>FilterAllocate */ >>>>>>>> - ntfa_filter_hdl_rec_destructor(filter_hdl_rec); >>>>>>>> + ntfa_filter_destructor(filter_hdl_rec); >>>>>>>> >>>>>>>> /** Delete the resources related to the >>>>>>>> notificationFilterHandle & >>>>>>>> * remove reference in the client. >>>>>>>> @@ -2729,7 +3076,6 @@ SaAisErrorT saNtfNotificationUnsubscribe >>>>>>>> TRACE_ENTER(); >>>>>>>> SaAisErrorT rc = SA_AIS_ERR_NOT_EXIST; >>>>>>>> SaNtfHandleT ntfHandle; >>>>>>>> - >>>>>>>> ntfa_client_hdl_rec_t *client_hdl_rec; >>>>>>>> >>>>>>>> ntfsv_msg_t msg, *o_msg = NULL; >>>>>>>> @@ -2737,7 +3083,6 @@ SaAisErrorT saNtfNotificationUnsubscribe >>>>>>>> ntfsv_unsubscribe_req_t *send_param; >>>>>>>> uint32_t timeout = NTFS_WAIT_TIME; >>>>>>>> >>>>>>>> - >>>>>>>> ntfHandle = ntfHandleGet(subscriptionId); >>>>>>>> if (ntfHandle == 0) { >>>>>>>> TRACE_1("ntfHandleGet failed, subscription not >>>>>>>> exist"); >>>>>>>> @@ -2753,9 +3098,16 @@ SaAisErrorT saNtfNotificationUnsubscribe >>>>>>>> goto done; >>>>>>>> } >>>>>>>> >>>>>>>> - /** >>>>>>>> - ** Populate a sync MDS message >>>>>>>> - **/ >>>>>>>> + /* Check NTF server availability */ >>>>>>>> + if ((rc = checkNtfServerState()) != SA_AIS_OK) { >>>>>>> [Praveen] Here in both unavailability and down case, API will >>>>>>> return >>>>>>> without clean up of subscriber information. But README in patch 3 >>>>>>> tals >>>>>>> differently for the two cases. >>>>>>> I think handling like saNtfFinalize() way needs to be done here. >>>>>> [Minh]: I will have to check the history commit, to see if any >>>>>> reason >>>>>> that agent doesn't silently release subscriber's resource here as >>>>>> described in README. But it looks to me a bug, can I get back to >>>>>> you later? >>>>> [Praveen] This needs to be corrected otherwise the same application >>>>> will >>>>> not be able to reuse old subscription_id. It will get ERR_EXIST. >>>>>>>> + ncshm_give_hdl(ntfHandle); >>>>>>>> + goto done; >>>>>>>> + } >>>>>>>> + >>>>>>>> + if (client_hdl_rec->valid) { >>>>>>>> + /** >>>>>>>> + ** Populate a sync MDS message >>>>>>>> + **/ >>>>>>>> memset(&msg, 0, sizeof(ntfsv_msg_t)); >>>>>>>> msg.type = NTFSV_NTFA_API_MSG; >>>>>>>> msg.info.api_info.type = NTFSV_UNSUBSCRIBE_REQ; >>>>>>>> @@ -2764,13 +3116,6 @@ SaAisErrorT saNtfNotificationUnsubscribe >>>>>>>> send_param->client_id = >>>>>>>> client_hdl_rec->ntfs_client_id; >>>>>>>> send_param->subscriptionId = subscriptionId; >>>>>>>> >>>>>>>> - /* Check whether NTFS is up or not */ >>>>>>>> - if (!ntfa_cb.ntfs_up) { >>>>>>>> - TRACE_1("NTFS down"); >>>>>>>> - rc = SA_AIS_ERR_TRY_AGAIN; >>>>>>>> - goto done_give_hdl; >>>>>>>> - } >>>>>>>> - >>>>>>>> /* Send a sync MDS message to obtain a log stream >>>>>>>> id */ >>>>>>>> rc = ntfa_mds_msg_sync_send(&ntfa_cb, &msg, &o_msg, >>>>> timeout); >>>>>>>> if (rc != NCSCC_RC_SUCCESS) { >>>>>>>> @@ -2785,6 +3130,7 @@ SaAisErrorT saNtfNotificationUnsubscribe >>>>>>>> TRACE_1("Bad return status! rc = %d", rc); >>>>>>>> goto done_give_hdl; >>>>>>>> } >>>>>>>> + } >>>>>>>> subscriberListItemRemove(subscriptionId); >>>>>>>> >>>>>>>> /*Remove msg for subscriptionId from mailbox*/ >>>>>>>> @@ -2815,6 +3161,19 @@ SaAisErrorT saNtfNotificationUnsubscribe >>>>>>>> done_give_hdl: >>>>>>>> if (o_msg) >>>>>>>> ntfa_msg_destroy(o_msg); >>>>>>>> + >>>>>>>> + if (!client_hdl_rec->valid) { >>>>>>>> + if ((rc = recoverClient(client_hdl_rec)) != SA_AIS_OK) { >>>>>>>> + if (rc == SA_AIS_ERR_BAD_HANDLE) { >>>>>>>> + ncshm_give_hdl(ntfHandle); >>>>>>>> + osafassert(pthread_mutex_lock(&ntfa_cb.cb_lock) == 0); >>>>>>>> + ntfa_hdl_rec_force_del(&ntfa_cb.client_list, client_hdl_rec); >>>>>>>> + osafassert(pthread_mutex_unlock(&ntfa_cb.cb_lock) == 0); >>>>>>>> + ntfa_shutdown(false); >>>>>>>> + goto done; >>>>>>>> + } >>>>>>>> + } >>>>>>>> + } >>>>>>>> ncshm_give_hdl(ntfHandle); >>>>>>>> done: >>>>>>>> TRACE_LEAVE(); >>>>>>>> @@ -2838,6 +3197,7 @@ SaAisErrorT saNtfNotificationReadInitial >>>>>>>> ntfsv_reader_init_req_2_t *send_param; >>>>>>>> uint32_t timeout = NTFS_WAIT_TIME; >>>>>>>> >>>>>>>> + bool recovery_failed = false; >>>>>>>> TRACE_ENTER(); >>>>>>>> if (notificationFilterHandles == NULL || readHandle == >>>>>>>> NULL) { >>>>>>>> rc = SA_AIS_ERR_INVALID_PARAM; >>>>>>>> @@ -2872,6 +3232,18 @@ SaAisErrorT saNtfNotificationReadInitial >>>>>>>> goto done_give_client_hdl; >>>>>>>> } >>>>>>>> >>>>>>>> + /* Check NTF server availability */ >>>>>>>> + if ((rc = checkNtfServerState()) != SA_AIS_OK) >>>>>>>> + goto done_give_client_hdl; >>>>>>>> + >>>>>>>> + /* recovery */ >>>>>>>> + if (client_hdl_rec != NULL && !client_hdl_rec->valid) { >>>>>>>> + if ((rc = recoverClient(client_hdl_rec)) != SA_AIS_OK) { >>>>>>>> + recovery_failed = true; >>>>>>>> + goto done_give_client_hdl; >>>>>>>> + } >>>>>>>> + } >>>>>>>> + >>>>>>>> /** >>>>>>>> ** Populate a sync MDS message >>>>>>>> **/ >>>>>>>> @@ -2884,13 +3256,6 @@ SaAisErrorT saNtfNotificationReadInitial >>>>>>>> send_param->head.searchCriteria = searchCriteria; >>>>>>>> send_param->f_rec = filters; >>>>>>>> >>>>>>>> - /* Check whether NTFS is up or not */ >>>>>>>> - if (!ntfa_cb.ntfs_up) { >>>>>>>> - TRACE("NTFS down"); >>>>>>>> - rc = SA_AIS_ERR_TRY_AGAIN; >>>>>>>> - goto done_give_client_hdl; >>>>>>>> - } >>>>>>>> - >>>>>>>> /* Send a sync MDS message to obtain a log stream id */ >>>>>>>> rc = ntfa_mds_msg_sync_send(&ntfa_cb, &msg, &o_msg, >>>>>>>> timeout); >>>>>>>> if (rc != NCSCC_RC_SUCCESS) { >>>>>>>> @@ -2925,12 +3290,16 @@ SaAisErrorT saNtfNotificationReadInitial >>>>>>>> reader_hdl_rec->ntfHandle = ntfHandle; >>>>>>>> /* Store the readerId returned from server */ >>>>>>>> reader_hdl_rec->reader_id = >>>>>>>> o_msg->info.api_resp_info.param.reader_init_rsp.readerId; >>>>>>>> + memset(&reader_hdl_rec->filters, 0, >>>>>>>> sizeof(ntfsv_filter_ptrs_t)); >>>>>>>> + ntfa_copy_ntf_filter_ptrs(&reader_hdl_rec->filters, &filters); >>>>>>>> + reader_hdl_rec->searchCriteria = searchCriteria; >>>>>>>> /** UnLock ntfa_CB **/ >>>>>>>> osafassert(pthread_mutex_unlock(&ntfa_cb.cb_lock) == 0); >>>>>>>> >>>>>>>> done_give_client_hdl: >>>>>>>> if (o_msg) >>>>>>>> ntfa_msg_destroy(o_msg); >>>>>>>> + >>>>>>>> if (client_hdl_rec) >>>>>>>> ncshm_give_hdl(client_hdl_rec->local_hdl); >>>>>>>> if (notificationFilterHandles) { >>>>>>>> @@ -2947,6 +3316,12 @@ done_give_client_hdl: >>>>>>>> } >>>>>>>> >>>>>>>> ncshm_give_hdl(notificationFilterHandles->alarmFilterHandle); >>>>>>>> + if (recovery_failed && rc == SA_AIS_ERR_BAD_HANDLE) { >>>>>>>> + osafassert(pthread_mutex_lock(&ntfa_cb.cb_lock) == 0); >>>>>>>> + ntfa_hdl_rec_force_del(&ntfa_cb.client_list, >>>>>>>> client_hdl_rec); >>>>>>>> + osafassert(pthread_mutex_unlock(&ntfa_cb.cb_lock) == 0); >>>>>>>> + ntfa_shutdown(false); >>>>>>>> + } >>>>>>>> done: >>>>>>>> TRACE_LEAVE(); >>>>>>>> return rc; >>>>>>>> @@ -2983,42 +3358,46 @@ SaAisErrorT saNtfNotificationReadFinaliz >>>>>>>> } >>>>>>>> TRACE_1("reader_hdl_rec = %u", >>>>>>>> reader_hdl_rec->reader_hdl); >>>>>>>> >>>>>>>> - /** >>>>>>>> - ** Populate a sync MDS message >>>>>>>> - **/ >>>>>>>> - memset(&msg, 0, sizeof(ntfsv_msg_t)); >>>>>>>> - msg.type = NTFSV_NTFA_API_MSG; >>>>>>>> - msg.info.api_info.type = NTFSV_READER_FINALIZE_REQ; >>>>>>>> - send_param = &msg.info.api_info.param.reader_finalize; >>>>>>>> - send_param->client_id = client_hdl_rec->ntfs_client_id; >>>>>>>> - send_param->readerId = reader_hdl_rec->reader_id; >>>>>>>> - >>>>>>>> - /* Check whether NTFS is up or not */ >>>>>>>> - if (!ntfa_cb.ntfs_up) { >>>>>>>> - TRACE("NTFS down"); >>>>>>>> - rc = SA_AIS_ERR_TRY_AGAIN; >>>>>>>> - goto done_give_hdls; >>>>>>>> + /* Check NTF server availability */ >>>>>>>> + if ((rc = checkNtfServerState()) != SA_AIS_OK) { >>>>>>> [Praveen] Same comment here as in Unsubscribe(). >>>>>>> [Minh] As above in Unsubscribed() >>>>>>>> + ncshm_give_hdl(client_hdl_rec->local_hdl); >>>>>>>> + ncshm_give_hdl(readhandle); >>>>>>>> + goto done; >>>>>>>> } >>>>>>>> >>>>>>>> - /* Send a sync MDS message */ >>>>>>>> - rc = ntfa_mds_msg_sync_send(&ntfa_cb, &msg, &o_msg, timeout); >>>>>>>> - if (rc != NCSCC_RC_SUCCESS) { >>>>>>>> - rc = SA_AIS_ERR_TRY_AGAIN; >>>>>>>> - goto done_give_hdls; >>>>>>>> + if (client_hdl_rec->valid) { >>>>>>>> + /** >>>>>>>> + ** Populate a sync MDS message >>>>>>>> + **/ >>>>>>>> + memset(&msg, 0, sizeof(ntfsv_msg_t)); >>>>>>>> + msg.type = NTFSV_NTFA_API_MSG; >>>>>>>> + msg.info.api_info.type = NTFSV_READER_FINALIZE_REQ; >>>>>>>> + send_param = &msg.info.api_info.param.reader_finalize; >>>>>>>> + send_param->client_id = client_hdl_rec->ntfs_client_id; >>>>>>>> + send_param->readerId = reader_hdl_rec->reader_id; >>>>>>>> + >>>>>>>> + >>>>>>>> + /* Send a sync MDS message */ >>>>>>>> + rc = ntfa_mds_msg_sync_send(&ntfa_cb, &msg, &o_msg, >>>>> timeout); >>>>>>>> + if (rc != NCSCC_RC_SUCCESS) { >>>>>>>> + rc = SA_AIS_ERR_TRY_AGAIN; >>>>>>>> + goto done_give_hdls; >>>>>>>> + } >>>>>>>> + >>>>>>>> + osafassert(o_msg != NULL); >>>>>>>> + if (SA_AIS_OK != o_msg->info.api_resp_info.rc) { >>>>>>>> + rc = o_msg->info.api_resp_info.rc; >>>>>>>> + TRACE("Bad return status!!! rc = %d", rc); >>>>>>>> + goto done_give_hdls; >>>>>>>> + } >>>>>>>> + >>>>>>>> + if (o_msg->info.api_resp_info.type != >>>>>>>> NTFSV_READER_FINALIZE_RSP) { >>>>>>>> + TRACE("msg type (%d) failed", >>>>>>>> (int)o_msg->info.api_resp_info.type); >>>>>>>> + rc = SA_AIS_ERR_LIBRARY; >>>>>>>> + goto done_give_hdls; >>>>>>>> + } >>>>>>>> } >>>>>>>> >>>>>>>> - osafassert(o_msg != NULL); >>>>>>>> - if (SA_AIS_OK != o_msg->info.api_resp_info.rc) { >>>>>>>> - rc = o_msg->info.api_resp_info.rc; >>>>>>>> - TRACE("Bad return status!!! rc = %d", rc); >>>>>>>> - goto done_give_hdls; >>>>>>>> - } >>>>>>>> - >>>>>>>> - if (o_msg->info.api_resp_info.type != >>>>> NTFSV_READER_FINALIZE_RSP) { >>>>>>>> - TRACE("msg type (%d) failed", >>>>>>>> (int)o_msg->info.api_resp_info.type); >>>>>>>> - rc = SA_AIS_ERR_LIBRARY; >>>>>>>> - goto done_give_hdls; >>>>>>>> - } >>>>>>>> osafassert(pthread_mutex_lock(&ntfa_cb.cb_lock) == 0); >>>>>>>> oas_rc = >>>>>>>> ntfa_reader_hdl_rec_del(&client_hdl_rec->reader_list, >>>>>>>> reader_hdl_rec); >>>>>>>> if (oas_rc != NCSCC_RC_SUCCESS) { >>>>>>>> @@ -3029,6 +3408,20 @@ SaAisErrorT saNtfNotificationReadFinaliz >>>>>>>> done_give_hdls: >>>>>>>> if (o_msg) >>>>>>>> ntfa_msg_destroy(o_msg); >>>>>>>> + >>>>>>>> + if (!client_hdl_rec->valid) { >>>>>>>> + if ((rc = recoverClient(client_hdl_rec)) != SA_AIS_OK) { >>>>>>>> + if (rc == SA_AIS_ERR_BAD_HANDLE) { >>>>>>>> + ncshm_give_hdl(client_hdl_rec->local_hdl); >>>>>>>> + ncshm_give_hdl(readhandle); >>>>>>>> + osafassert(pthread_mutex_lock(&ntfa_cb.cb_lock) == 0); >>>>>>>> + ntfa_hdl_rec_force_del(&ntfa_cb.client_list, client_hdl_rec); >>>>>>>> + osafassert(pthread_mutex_unlock(&ntfa_cb.cb_lock) == 0); >>>>>>>> + ntfa_shutdown(false); >>>>>>>> + goto done; >>>>>>>> + } >>>>>>>> + } >>>>>>>> + } >>>>>>>> ncshm_give_hdl(client_hdl_rec->local_hdl); >>>>>>>> done_give_read_hdl: >>>>>>>> ncshm_give_hdl(readhandle); >>>>>>>> @@ -3082,6 +3475,23 @@ SaAisErrorT saNtfNotificationReadNext(Sa >>>>>>>> } >>>>>>>> TRACE_1("reader_hdl_rec = %u", >>>>>>>> reader_hdl_rec->reader_hdl); >>>>>>>> >>>>>>>> + /* Check NTF server availability */ >>>>>>>> + if ((rc = checkNtfServerState()) != SA_AIS_OK) >>>>>>>> + goto done_give_hdls; >>>>>>>> + >>>>>>>> + if (!client_hdl_rec->valid) { >>>>>>>> + if ((rc = recoverClient(client_hdl_rec)) != SA_AIS_OK) { >>>>>>>> + ncshm_give_hdl(client_hdl_rec->local_hdl); >>>>>>>> + ncshm_give_hdl(readHandle); >>>>>>>> + if (rc == SA_AIS_ERR_BAD_HANDLE) { >>>>>>>> + osafassert(pthread_mutex_lock(&ntfa_cb.cb_lock) == 0); >>>>>>>> + ntfa_hdl_rec_force_del(&ntfa_cb.client_list, client_hdl_rec); >>>>>>>> + osafassert(pthread_mutex_unlock(&ntfa_cb.cb_lock) == 0); >>>>>>>> + ntfa_shutdown(false); >>>>>>>> + } >>>>>>>> + goto done; >>>>>>>> + } >>>>>>>> + } >>>>>>>> /** >>>>>>>> ** Populate a sync MDS message >>>>>>>> **/ >>>>>>>> @@ -3092,12 +3502,6 @@ SaAisErrorT saNtfNotificationReadNext(Sa >>>>>>>> send_param->client_id = client_hdl_rec->ntfs_client_id; >>>>>>>> send_param->readerId = reader_hdl_rec->reader_id; >>>>>>>> send_param->searchDirection = searchDirection; >>>>>>>> - /* Check whether NTFS is up or not */ >>>>>>>> - if (!ntfa_cb.ntfs_up) { >>>>>>>> - TRACE("NTFS down"); >>>>>>>> - rc = SA_AIS_ERR_TRY_AGAIN; >>>>>>>> - goto done_give_hdls; >>>>>>>> - } >>>>>>>> >>>>>>>> do { >>>>>>>> /* Send a sync MDS message */ >>>>>>>> diff --git a/osaf/libs/agents/saf/ntfa/ntfa_mds.c >>>>>>>> b/osaf/libs/agents/saf/ntfa/ntfa_mds.c >>>>>>>> --- a/osaf/libs/agents/saf/ntfa/ntfa_mds.c >>>>>>>> +++ b/osaf/libs/agents/saf/ntfa/ntfa_mds.c >>>>>>>> @@ -369,7 +369,8 @@ static uint32_t ntfa_mds_svc_evt(struct >>>>>>>> TRACE("NTFS down"); >>>>>>>> pthread_mutex_lock(&ntfa_cb.cb_lock); >>>>>>>> memset(&ntfa_cb.ntfs_mds_dest, 0, >>>>>>>> sizeof(MDS_DEST)); >>>>>>>> - ntfa_cb.ntfs_up = 0; >>>>>>>> + ntfa_update_ntfsv_state(mds_cb_info->info.svc_evt.i_change == >>>>>>>> NCSMDS_NO_ACTIVE ? >>>>>>>> + NTFA_NTFSV_NO_ACTIVE : NTFA_NTFSV_DOWN); >>>>>>>> pthread_mutex_unlock(&ntfa_cb.cb_lock); >>>>>>>> } >>>>>>>> break; >>>>>>>> @@ -382,7 +383,8 @@ static uint32_t ntfa_mds_svc_evt(struct >>>>>>>> TRACE_2("MSG from NTFS NCSMDS_NEW_ACTIVE/UP"); >>>>>>>> pthread_mutex_lock(&ntfa_cb.cb_lock); >>>>>>>> ntfa_cb.ntfs_mds_dest = >>>>>>>> mds_cb_info->info.svc_evt.i_dest; >>>>>>>> - ntfa_cb.ntfs_up = 1; >>>>>>>> + ntfa_update_ntfsv_state(mds_cb_info->info.svc_evt.i_change == >>>>>>>> NCSMDS_NEW_ACTIVE ? >>>>>>>> + NTFA_NTFSV_NEW_ACTIVE : NTFA_NTFSV_UP); >>>>>>>> if (ntfa_cb.ntfs_sync_awaited) { >>>>>>>> /* signal waiting thread */ >>>>>>>> m_NCS_SEL_OBJ_IND(&ntfa_cb.ntfs_sync_sel); >>>>>>>> diff --git a/osaf/libs/agents/saf/ntfa/ntfa_util.c >>>>>>>> b/osaf/libs/agents/saf/ntfa/ntfa_util.c >>>>>>>> --- a/osaf/libs/agents/saf/ntfa/ntfa_util.c >>>>>>>> +++ b/osaf/libs/agents/saf/ntfa/ntfa_util.c >>>>>>>> @@ -49,7 +49,7 @@ static unsigned int ntfa_create(void) >>>>>>>> } >>>>>>>> >>>>>>>> /* Block and wait for indication from MDS meaning NTFS is >>>>>>>> up */ >>>>>>>> - >>>>> osaf_poll_one_fd(m_GET_FD_FROM_SEL_OBJ(ntfa_cb.ntfs_sync_sel), >>>>> 30000); >>>>>>>> + >>>>> osaf_poll_one_fd(m_GET_FD_FROM_SEL_OBJ(ntfa_cb.ntfs_sync_sel), >>>>> 10000); >>>>>>> [Praveen] Did not get why it is changed to 10 seconds. >>>>>>> [Minh] I think 30 seconds is just too long >>>>>>>> pthread_mutex_lock(&ntfa_cb.cb_lock); >>>>>>>> ntfa_cb.ntfs_sync_awaited = 0; >>>>>>>> @@ -108,7 +108,25 @@ static bool ntfa_clear_mbx(NCSCONTEXT ar >>>>>>>> } >>>>>>>> return true; >>>>>>>> } >>>>>>>> >>>>> +/********************************************************* >>>>> ******************* >>>>>>>> + Name : ntfa_notification_list_del >>>>>>>> >>>>>>>> + Description : This routine free element allocated in list of >>>>>>>> notification >>>>>>>> + >>>>>>>> + Arguments : pointer to the list of notification records >>>>>>>> anchor. >>>>>>>> + >>>>>>>> + Return Values : None >>>>>>>> + >>>>>>>> + Notes : >>>>>>>> >>>>> +********************************************************* >>>>> *********************/ >>>>>>>> +static void >>>>>>>> ntfa_notification_list_del(ntfa_notification_hdl_rec_t >>>>>>>> **plstr_hdl) >>>>>>>> +{ >>>>>>>> + ntfa_notification_hdl_rec_t *lstr_hdl = *plstr_hdl; >>>>>>>> + while (lstr_hdl != NULL) { >>>>>>>> + ntfa_notification_destructor(lstr_hdl); >>>>>>>> + lstr_hdl = lstr_hdl->next; >>>>>>>> + } >>>>>>>> +} >>>>>>>> >>>>> /********************************************************** >>>>> ****************** >>>>>>>> Name : ntfa_notification_hdl_rec_list_del >>>>>>>> >>>>>>>> @@ -130,6 +148,70 @@ static void ntfa_notification_hdl_rec_li >>>>>>>> lstr_hdl = NULL; >>>>>>>> } >>>>>>>> } >>>>>>>> >>>>> +/********************************************************* >>>>> ******************* >>>>>>>> + Name : ntfa_filter_list_del >>>>>>>> + >>>>>>>> + Description : This routine free element allocated in list of >>>>>>>> filter >>>>>>>> + >>>>>>>> + Arguments : pointer to the list of filters records anchor. >>>>>>>> + >>>>>>>> + Return Values : None >>>>>>>> + >>>>>>>> + Notes : >>>>>>>> >>>>> +********************************************************* >>>>> *********************/ >>>>>>>> +static void ntfa_filter_list_del(ntfa_filter_hdl_rec_t >>>>>>>> **plstr_hdl) >>>>>>>> +{ >>>>>>>> + ntfa_filter_hdl_rec_t *lstr_hdl = *plstr_hdl; >>>>>>>> + >>>>>>>> + while (lstr_hdl != NULL) { >>>>>>>> + ntfa_filter_destructor(lstr_hdl); >>>>>>>> + lstr_hdl = lstr_hdl->next; >>>>>>>> + } >>>>>>>> +} >>>>>>>> >>>>> +/********************************************************* >>>>> ******************* >>>>>>>> + Name : ntfa_filter_hdl_rec_list_del >>>>>>>> + >>>>>>>> + Description : This routine deletes a list of allocated >>>>>>>> filters >>>>>>>> + >>>>>>>> + Arguments : pointer to the list of filters records anchor. >>>>>>>> + >>>>>>>> + Return Values : None >>>>>>>> + >>>>>>>> + Notes : >>>>>>>> >>>>> +********************************************************* >>>>> *********************/ >>>>>>>> +static void ntfa_filter_hdl_rec_list_del(ntfa_filter_hdl_rec_t >>>>>>>> **plstr_hdl) >>>>>>>> +{ >>>>>>>> + ntfa_filter_hdl_rec_t *lstr_hdl; >>>>>>>> + >>>>>>>> + while ((lstr_hdl = *plstr_hdl) != NULL) { >>>>>>>> + *plstr_hdl = lstr_hdl->next; >>>>>>>> + ncshm_destroy_hdl(NCS_SERVICE_ID_NTFA, >>>>>>>> lstr_hdl->filter_hdl); >>>>>>>> + free(lstr_hdl); >>>>>>>> + lstr_hdl = NULL; >>>>>>>> + } >>>>>>>> +} >>>>>>>> >>>>> +/********************************************************* >>>>> ******************* >>>>>>>> + Name : ntfa_reader_hdl_rec_list_del >>>>>>>> + >>>>>>>> + Description : This routine deletes a list of allocated >>>>>>>> readers >>>>>>>> + >>>>>>>> + Arguments : pointer to the list of readers records anchor. >>>>>>>> + >>>>>>>> + Return Values : None >>>>>>>> + >>>>>>>> + Notes : >>>>>>>> >>>>> +********************************************************* >>>>> *********************/ >>>>>>>> +static void ntfa_reader_hdl_rec_list_del(ntfa_reader_hdl_rec_t >>>>>>>> **plstr_hdl) >>>>>>>> +{ >>>>>>>> + ntfa_reader_hdl_rec_t *lstr_hdl; >>>>>>>> + while ((lstr_hdl = *plstr_hdl) != NULL) { >>>>>>>> + *plstr_hdl = lstr_hdl->next; >>>>>>>> + ncshm_destroy_hdl(NCS_SERVICE_ID_NTFA, lstr_hdl- >>>>>> reader_hdl); >>>>>>>> + ntfa_del_ntf_filter_ptrs(&lstr_hdl->filters); >>>>>>>> + free(lstr_hdl); >>>>>>>> + lstr_hdl = NULL; >>>>>>>> + } >>>>>>>> +} >>>>>>>> >>>>>>>> static SaAisErrorT >>>>>>>> ntfa_alloc_callback_notification(SaNtfNotificationsT >>>>>>>> *notification, >>>>>>>> ntfsv_send_not_req_t *not_cbk, >>>>>>>> ntfa_client_hdl_rec_t *hdl_rec) >>>>>>>> @@ -407,6 +489,10 @@ static SaAisErrorT ntfa_hdl_cbk_rec_prc( >>>>>>>> free(cbk_info->param.discarded_cbk.discardedNotificationIdentifiers); >>>>>>>> >>>>>>>> >>>>>>>> } >>>>>>>> break; >>>>>>>> + case NTFSV_DUMMY_CALLBACK: >>>>>>>> + TRACE("Do nothing with dummy callback, just return OK"); >>>>>>>> + rc = SA_AIS_OK; >>>>>>>> + break; >>>>>>>> default: >>>>>>>> TRACE("unsupported callback type: %d", >>>>>>>> cbk_info->type); >>>>>>>> rc = SA_AIS_ERR_LIBRARY; >>>>>>>> @@ -544,20 +630,21 @@ unsigned int ntfa_startup(void) >>>>>>>> * >>>>>>>> * @return unsigned int >>>>>>>> */ >>>>>>>> -unsigned int ntfa_shutdown(void) >>>>>>>> +unsigned int ntfa_shutdown(bool forced) >>>>>>>> { >>>>>>>> unsigned int rc = NCSCC_RC_SUCCESS; >>>>>>>> >>>>>>>> - TRACE_ENTER2("ntfa_use_count: %u", ntfa_use_count); >>>>>>>> + TRACE_ENTER2("ntfa_use_count: %u, forced: %u", >>>>>>>> ntfa_use_count, >>>>>>>> forced); >>>>>>>> pthread_mutex_lock(&ntfa_lock); >>>>>>>> >>>>>>>> - if (ntfa_use_count > 1) { >>>>>>>> - /* Users still exist, just decrement the use count */ >>>>>>>> - ntfa_use_count--; >>>>>>>> - } else if (ntfa_use_count == 1) { >>>>>>>> + if ((forced && (ntfa_use_count > 0)) || (ntfa_use_count == >>>>>>>> 1)) { >>>>>>>> ntfa_destroy(); >>>>>>>> rc = ncs_agents_shutdown(); >>>>>>>> ntfa_use_count = 0; >>>>>>>> + ntfa_cb.ntfa_ntfsv_state = NTFA_NTFSV_NONE; >>>>>>>> + } else if (ntfa_use_count > 1) { >>>>>>>> + /* Users still exist, just decrement the use count */ >>>>>>>> + ntfa_use_count--; >>>>>>>> } >>>>>>>> >>>>>>>> pthread_mutex_unlock(&ntfa_lock); >>>>>>>> @@ -633,7 +720,27 @@ ntfa_client_hdl_rec_t *ntfa_find_hdl_rec >>>>>>>> >>>>>>>> return NULL; >>>>>>>> } >>>>>>>> >>>>> +/********************************************************* >>>>> ******************* >>>>>>>> + Name : ntfa_subscriber_list_del >>>>>>>> >>>>>>>> + Description : This routine deletes a list of allocated >>>>>>>> subscribers >>>>>>>> + >>>>>>>> + Arguments : pointer to the list of subscribers records >>>>>>>> anchor. >>>>>>>> + >>>>>>>> + Return Values : None >>>>>>>> + >>>>>>>> + Notes : >>>>>>>> >>>>> +********************************************************* >>>>> *********************/ >>>>>>>> +void ntfa_subscriber_list_del() >>>>>>>> +{ >>>>>>>> + ntfa_subscriber_list_t *listPtr = subscriberNoList; >>>>>>>> + while (listPtr != NULL) { >>>>>>>> + ntfa_subscriber_list_t* tmpSub = listPtr; >>>>>>>> + listPtr = listPtr->next; >>>>>>>> + free(tmpSub); >>>>>>>> + } >>>>>>>> + subscriberNoList = NULL; >>>>>>>> +} >>>>>>>> >>>>> /********************************************************** >>>>> ****************** >>>>>>>> Name : ntfa_hdl_list_del >>>>>>>> >>>>>>>> @@ -651,15 +758,24 @@ void ntfa_hdl_list_del(ntfa_client_hdl_r >>>>>>>> >>>>>>>> while ((client_hdl = *p_client_hdl) != NULL) { >>>>>>>> *p_client_hdl = client_hdl->next; >>>>>>>> + m_NCS_IPC_DETACH(&client_hdl->mbx, ntfa_clear_mbx, NULL); >>>>>>>> + m_NCS_IPC_RELEASE(&client_hdl->mbx, NULL); >>>>>>>> ncshm_destroy_hdl(NCS_SERVICE_ID_NTFA, client_hdl- >>>>>> local_hdl); >>>>>>>> /** clean up the channel records for this ntfa-client >>>>>>>> **/ >>>>>>>> + ntfa_notification_list_del(&client_hdl->notification_list); >>>>>>>> ntfa_notification_hdl_rec_list_del(&client_hdl->notification_list); >>>>>>>> >>>>>>>> + >>>>>>>> + ntfa_filter_list_del(&client_hdl->filter_list); >>>>>>>> + ntfa_filter_hdl_rec_list_del(&client_hdl->filter_list); >>>>>>>> + >>>>>>>> + ntfa_reader_hdl_rec_list_del(&client_hdl->reader_list); >>>>>>>> /** remove the association with hdl-mngr >>>>>>>> **/ >>>>>>>> free(client_hdl); >>>>>>>> client_hdl = 0; >>>>>>>> } >>>>>>>> + ntfa_subscriber_list_del(); >>>>>>>> } >>>>>>>> >>>>>>>> >>>>> /********************************************************** >>>>> ****************** >>>>>>>> @@ -757,10 +873,80 @@ uint32_t ntfa_filter_hdl_rec_del(ntfa_fi >>>>>>>> TRACE("The node couldn't be deleted"); >>>>>>>> return NCSCC_RC_FAILURE; >>>>>>>> } >>>>>>>> >>>>> +/********************************************************* >>>>> ******************* >>>>>>>> + Name : ntfa_hdl_rec_force_del >>>>>>>> >>>>>>>> + Description : This routine deletes all memory allocated to >>>>>>>> client. >>>>>>>> + >>>>>>>> + Arguments : NTFA_CLIENT_HDL_REC **list_head >>>>>>>> + NTFA_CLIENT_HDL_REC *rm_node >>>>>>>> + >>>>>>>> + Return Values : None >>>>>>>> + >>>>>>>> + Notes : >>>>>>>> >>>>> +********************************************************* >>>>> *********************/ >>>>>>>> +void ntfa_hdl_rec_force_del(ntfa_client_hdl_rec_t **list_head, >>>>>>>> ntfa_client_hdl_rec_t *rm_node) >>>>>>>> +{ >>>>>>>> + ntfa_client_hdl_rec_t *list_iter = *list_head; >>>>>>>> + TRACE_ENTER(); >>>>>>>> + /* First remove the rm_node out of the list of client */ >>>>>>>> + if (list_iter == rm_node) >>>>>>>> + *list_head = rm_node->next; >>>>>>>> + else { >>>>>>>> + while (list_iter) { >>>>>>>> + if (list_iter->next == rm_node) { >>>>>>>> + list_iter->next = rm_node->next; >>>>>>>> + break; >>>>>>>> + } >>>>>>>> + list_iter = list_iter->next; >>>>>>>> + } >>>>>>>> + } >>>>>>>> + /* Release all msgs in mailbox */ >>>>>>>> + ntfsv_msg_t *cbk_msg; >>>>>>>> + while((cbk_msg = >>>>>>>> (ntfsv_msg_t*)m_NCS_IPC_NON_BLK_RECEIVE(&rm_node->mbx, >>>>> cbk_msg)) >>>>>>>> + != NULL) { >>>>>>>> + ntfa_msg_destroy(cbk_msg); >>>>>>>> + } >>>>>>>> + /* delete subscriber of this client out of the >>>>>>>> subcriberNoList*/ >>>>>>>> + ntfa_subscriber_list_t* subscriber_hdl = subscriberNoList; >>>>>>>> + while (subscriber_hdl != NULL) { >>>>>>>> + ntfa_subscriber_list_t *rm_subscriber = subscriber_hdl; >>>>>>>> + subscriber_hdl = subscriber_hdl->next; >>>>>>>> + if (rm_node->local_hdl == >>>>>>>> rm_subscriber->subscriberListNtfHandle) { >>>>>>>> + if (rm_subscriber->next != NULL) { >>>>>>>> + rm_subscriber->next->prev = rm_subscriber->prev; >>>>>>>> + } >>>>>>>> + >>>>>>>> + if (rm_subscriber->prev != NULL) { >>>>>>>> + rm_subscriber->prev->next = rm_subscriber->next; >>>>>>>> + } else { >>>>>>>> + if (rm_subscriber->next != NULL) >>>>>>>> + subscriberNoList = rm_subscriber->next; >>>>>>>> + else >>>>>>>> + subscriberNoList = NULL; >>>>>>>> + } >>>>>>>> + ntfa_del_ntf_filter_ptrs(&rm_subscriber->filters); >>>>>>>> + free(rm_subscriber); >>>>>>>> + } >>>>>>>> + } >>>>>>>> + /* Now delete client */ >>>>>>>> + m_NCS_IPC_DETACH(&rm_node->mbx, ntfa_clear_mbx, NULL); >>>>>>>> + m_NCS_IPC_RELEASE(&rm_node->mbx, NULL); >>>>>>>> + ncshm_destroy_hdl(NCS_SERVICE_ID_NTFA, rm_node->local_hdl); >>>>>>>> + ntfa_notification_list_del(&rm_node->notification_list); >>>>>>>> + ntfa_notification_hdl_rec_list_del(&rm_node->notification_list); >>>>>>>> + >>>>>>>> + ntfa_filter_list_del(&rm_node->filter_list); >>>>>>>> + ntfa_filter_hdl_rec_list_del(&rm_node->filter_list); >>>>>>>> + >>>>>>>> + ntfa_reader_hdl_rec_list_del(&rm_node->reader_list); >>>>>>>> + free(rm_node); >>>>>>>> + >>>>>>>> + TRACE_LEAVE(); >>>>>>>> +} >>>>>>>> >>>>> /********************************************************** >>>>> ****************** >>>>>>>> Name : ntfa_hdl_rec_del >>>>>>>> - >>>>>>>> + >>>>>>>> Description : This routine deletes the a client handle >>>>>>>> record from >>>>>>>> a list of client hdl records. >>>>>>>> >>>>>>>> @@ -962,7 +1148,7 @@ ntfa_client_hdl_rec_t *ntfa_hdl_rec_add( >>>>>>>> /** Associate with the client_id obtained from NTFS >>>>>>>> **/ >>>>>>>> rec->ntfs_client_id = client_id; >>>>>>>> - >>>>>>>> + rec->valid = true; >>>>>>>> /** Initialize and attach the IPC/Priority queue >>>>>>>> **/ >>>>>>>> >>>>>>>> @@ -1063,7 +1249,7 @@ static void logtrace_init_constructor(vo >>>>>>>> * >>>>>>>> * @param instance >>>>>>>> */ >>>>>>>> -void ntfa_hdl_rec_destructor(ntfa_notification_hdl_rec_t >>>>>>>> *instance) >>>>>>>> +void ntfa_notification_destructor(ntfa_notification_hdl_rec_t >>>>>>>> *instance) >>>>>>>> { >>>>>>>> ntfa_notification_hdl_rec_t *notificationInstance = >>>>>>>> instance; >>>>>>>> >>>>>>>> @@ -1111,7 +1297,7 @@ void ntfa_hdl_rec_destructor(ntfa_notifi >>>>>>>> * >>>>>>>> * @param instance >>>>>>>> */ >>>>>>>> -void ntfa_filter_hdl_rec_destructor(ntfa_filter_hdl_rec_t >>>>>>>> *filter_rec) >>>>>>>> +void ntfa_filter_destructor(ntfa_filter_hdl_rec_t *filter_rec) >>>>>>>> { >>>>>>>> switch (filter_rec->ntfType) { >>>>>>>> case SA_NTF_TYPE_OBJECT_CREATE_DELETE: >>>>>>>> @@ -1202,6 +1388,7 @@ uint32_t ntfa_reader_hdl_rec_del(ntfa_re >>>>>>>> **/ >>>>>>>> ncshm_give_hdl(rm_node->reader_hdl); >>>>>>>> ncshm_destroy_hdl(NCS_SERVICE_ID_NTFA, rm_node- >>>>>> reader_hdl); >>>>>>>> + ntfa_del_ntf_filter_ptrs(&rm_node->filters); >>>>>>>> free(rm_node); >>>>>>>> return NCSCC_RC_SUCCESS; >>>>>>>> } else { /* find the rec */ >>>>>>>> @@ -1213,6 +1400,7 @@ uint32_t ntfa_reader_hdl_rec_del(ntfa_re >>>>>>>> **/ >>>>>>>> ncshm_give_hdl(rm_node->reader_hdl); >>>>>>>> ncshm_destroy_hdl(NCS_SERVICE_ID_NTFA, >>>>>>>> rm_node->reader_hdl); >>>>>>>> + ntfa_del_ntf_filter_ptrs(&rm_node->filters); >>>>>>>> free(rm_node); >>>>>>>> return NCSCC_RC_SUCCESS; >>>>>>>> } >>>>>>>> @@ -1258,3 +1446,258 @@ void ntfa_add_to_async_cbk_msg_list(ntfs >>>>>>>> >>>>>>>> TRACE_LEAVE(); >>>>>>>> } >>>>>>>> + >>>>>>>> >>>>> +/********************************************************* >>>>> ******************* >>>>>>>> + Name : ntfa_notify_handle_invalid >>>>>>>> + >>>>>>>> + Description : This routine sends a dummy callback msg to >>>>>>>> client's mailbox >>>>>>>> + so that the client polls in and calls saNtfDispatch. >>>>>>>> + Arguments : >>>>>>>> + >>>>>>>> + Return Values : None >>>>>>>> + >>>>>>>> + Notes : None >>>>>>>> >>>>> +********************************************************* >>>>> *********************/ >>>>>>>> +void ntfa_notify_handle_invalid() { >>>>>>>> + ntfa_client_hdl_rec_t *client_hdl = ntfa_cb.client_list; >>>>>>>> + TRACE_ENTER(); >>>>>>>> + while (client_hdl != NULL) { >>>>>>>> + /* Only applicable for subscriber */ >>>>>>>> + if (client_hdl->reg_cbk.saNtfNotificationCallback != >>>>>>>> NULL || >>>>>>>> + client_hdl->reg_cbk.saNtfNotificationDiscardedCallback != >>>>>>>> NULL) { >>>>>>>> + /* Create a dummy msg */ >>>>>>>> + ntfsv_msg_t *msg = malloc(sizeof(ntfsv_msg_t)); >>>>>>>> + memset(msg, 0, sizeof(ntfsv_msg_t)); >>>>>>>> + msg->info.cbk_info.type = NTFSV_DUMMY_CALLBACK; >>>>>>>> + /* Send dummy msg to client mailbox */ >>>>>>> [Praveen] Is this dummy callback being sent to client in a way to >>>>>>> force it to recover client and subscriber? >>>>>> [Minh] Because agent doesn't recover client in mds callback, so in >>>>>> case >>>>>> of subscriber who is just waiting for notification, agent needs to >>>>>> send >>>>>> dummy callback to client's mailbox to wake up client's polling loop. >>>>>> Then client will call saAmfDispatch, and from there agent will >>>>>> recover >>>>>> client handles. This dummy callback is invisible to client. >>>>>>>> + if (m_NCS_IPC_SEND(&client_hdl->mbx, msg, >>>>>>>> MDS_SEND_PRIORITY_HIGH) != NCSCC_RC_SUCCESS) { >>>>>>>> + TRACE_1("m_NCS_IPC_SEND Failed to client(id:%u)", >>>>>>>> client_hdl->ntfs_client_id); >>>>>>>> + ntfa_msg_destroy(msg); >>>>>>>> + } >>>>>>>> + } >>>>>>>> + >>>>>>>> + client_hdl = client_hdl->next; >>>>>>>> + } >>>>>>>> + TRACE_LEAVE(); >>>>>>>> +} >>>>>>>> >>>>> +/********************************************************* >>>>> ******************* >>>>>>>> + Name : ntfa_update_ntfsv_state >>>>>>>> + >>>>>>>> + Description : Update current NTF Server state by the >>>>>>>> @changedState indicated >>>>>>>> + by MDS event >>>>>>>> + Arguments : @changedState [IN]: state to be changed of NTF >>>>>>>> Server >>>>>>>> + >>>>>>>> + Return Values : None >>>>>>>> + >>>>>>>> + Notes : None >>>>>>>> >>>>> +********************************************************* >>>>> *********************/ >>>>>>>> +void ntfa_update_ntfsv_state(ntfa_ntfsv_state_t changedState) >>>>>>>> +{ >>>>>>>> + TRACE_ENTER(); >>>>>>>> + TRACE_1("Current state: %u, Changed state: %u", >>>>>>>> ntfa_cb.ntfa_ntfsv_state, >>>>>>>> + changedState); >>>>>>>> + >>>>>>>> + ntfa_client_hdl_rec_t *client_hdl = ntfa_cb.client_list; >>>>>>>> + >>>>>>>> + switch (ntfa_cb.ntfa_ntfsv_state){ >>>>>>>> + case NTFA_NTFSV_NONE: >>>>>>>> + ntfa_cb.ntfa_ntfsv_state = changedState; >>>>>>>> + break; >>>>>>>> + case NTFA_NTFSV_DOWN: >>>>>>>> + if (changedState == NTFA_NTFSV_NEW_ACTIVE || >>>>>>>> + changedState == NTFA_NTFSV_UP) { >>>>>>>> + TRACE("Active NTF server has been restarted"); >>>>>>>> + ntfa_cb.ntfa_ntfsv_state = NTFA_NTFSV_UP; >>>>>>>> + ntfa_notify_handle_invalid(); >>>>>>>> + } else >>>>>>>> + TRACE("Unexpected state changes"); >>>>>>>> + break; >>>>>>>> + case NTFA_NTFSV_NO_ACTIVE: >>>>>>>> + if (changedState == NTFA_NTFSV_NEW_ACTIVE) { >>>>>>>> + TRACE("Standby NTF server becomes new Active"); >>>>>>>> + /* NTF server is functioning normally */ >>>>>>>> + ntfa_cb.ntfa_ntfsv_state = NTFA_NTFSV_UP; >>>>>>>> + } else if (changedState == NTFA_NTFSV_DOWN) { >>>>>>>> + TRACE("Active NTF Server is Down"); >>>>>>>> + ntfa_cb.ntfa_ntfsv_state = NTFA_NTFSV_DOWN; >>>>>>>> + /* Mark all client handles are invalid */ >>>>>>>> + while (client_hdl != NULL) { >>>>>>>> + client_hdl->valid = false; >>>>>>>> + client_hdl = client_hdl->next; >>>>>>>> + } >>>>>>>> + } >>>>>>>> + break; >>>>>>>> + case NTFA_NTFSV_NEW_ACTIVE: >>>>>>>> + TRACE("Unknown"); >>>>>>>> + break; >>>>>>>> + case NTFA_NTFSV_UP: >>>>>>>> + if (changedState == NTFA_NTFSV_NO_ACTIVE) { >>>>>>>> + TRACE("Active NTF server temporarily unavailable"); >>>>>>>> + /* Failover/Switchover is happening >>>>>>>> + * Any API calls result in TRY_AGAIN >>>>>>>> + */ >>>>>>>> + ntfa_cb.ntfa_ntfsv_state = NTFA_NTFSV_NO_ACTIVE; >>>>>>>> + } else >>>>>>>> + TRACE("Unexpected state changes"); >>>>>>>> + break; >>>>>>>> + default: >>>>>>>> + osafassert(false); >>>>>>>> + } >>>>>>>> + >>>>>>>> + TRACE_LEAVE(); >>>>>>>> +} >>>>>>>> >>>>> +/********************************************************* >>>>> ******************* >>>>>>>> + Name : ntfa_copy_ntf_filter_ptrs >>>>>>>> + >>>>>>>> + Description : Copy a list of filter from pSrc to pDes >>>>>>>> + >>>>>>>> + Arguments : pDes* [OUT]: list of outcome filter >>>>>>>> + pSrc* [IN]: list of input filter >>>>>>>> + >>>>>>>> + Return Values : SA_AIS_OK if succeed, other values as failed >>>>>>>> + >>>>>>>> + Notes : None >>>>>>>> >>>>> +********************************************************* >>>>> *********************/ >>>>>>>> +SaAisErrorT ntfa_copy_ntf_filter_ptrs(ntfsv_filter_ptrs_t* pDes, >>>>>>>> + const ntfsv_filter_ptrs_t* >>>>>>>> pSrc) { >>>>>>>> + SaAisErrorT rc = SA_AIS_OK; >>>>>>>> + SaNtfNotificationFilterHeaderT *des_header; >>>>>>>> + SaNtfNotificationFilterHeaderT *src_header; >>>>>>>> + TRACE_ENTER(); >>>>>>>> + >>>>>>>> + if (pSrc->alarm_filter) { >>>>>>>> + pDes->alarm_filter = calloc(1, >>>>>>>> sizeof(SaNtfAlarmNotificationFilterT)); >>>>>>>> + des_header = >>>>>>>> &(pDes->alarm_filter->notificationFilterHeader); >>>>>>>> + src_header = >>>>>>>> &(pSrc->alarm_filter->notificationFilterHeader); >>>>>>>> + if ((rc = ntfsv_filter_header_alloc(des_header, >>>>>>>> src_header->numEventTypes, >>>>>>>> + src_header->numNotificationObjects, >>>>>>>> + src_header->numNotifyingObjects, >>>>>>>> + src_header->numNotificationClassIds)) != SA_AIS_OK) >>>>>>>> + goto done; >>>>>>>> + if ((rc = ntfsv_filter_alarm_alloc(pDes->alarm_filter, >>>>>>>> + pSrc->alarm_filter->numProbableCauses, >>>>>>>> + pSrc->alarm_filter->numPerceivedSeverities, >>>>>>>> + pSrc->alarm_filter->numTrends)) != SA_AIS_OK) >>>>>>>> + goto done; >>>>>>>> + if ((rc = ntfsv_copy_ntf_filter_alarm(pDes->alarm_filter, >>>>>>>> + pSrc->alarm_filter)) != SA_AIS_OK) >>>>>>>> + goto done; >>>>>>>> + } >>>>>>>> + >>>>>>>> + if (pSrc->sec_al_filter) { >>>>>>>> + pDes->sec_al_filter = calloc(1, >>>>>>>> sizeof(SaNtfSecurityAlarmNotificationFilterT)); >>>>>>>> + des_header = >>>>>>>> &(pDes->sec_al_filter->notificationFilterHeader); >>>>>>>> + src_header = >>>>>>>> &(pSrc->sec_al_filter->notificationFilterHeader); >>>>>>>> + if ((rc = ntfsv_filter_header_alloc(des_header, >>>>>>>> src_header->numEventTypes, >>>>>>>> + src_header->numNotificationObjects, >>>>>>>> + src_header->numNotifyingObjects, >>>>>>>> + src_header->numNotificationClassIds)) != SA_AIS_OK) >>>>>>>> + goto done; >>>>>>>> + if ((rc = >>>>>>>> ntfsv_filter_sec_alarm_alloc(pDes->sec_al_filter, >>>>>>>> + pSrc->sec_al_filter->numProbableCauses, >>>>>>>> + pSrc->sec_al_filter->numSeverities, >>>>>>>> + pSrc->sec_al_filter->numSecurityAlarmDetectors, >>>>>>>> + pSrc->sec_al_filter->numServiceUsers, >>>>>>>> + pSrc->sec_al_filter->numServiceProviders)) != SA_AIS_OK) >>>>>>>> + goto done; >>>>>>>> + if ((rc = >>>>>>>> ntfsv_copy_ntf_filter_sec_alarm(pDes->sec_al_filter, >>>>>>>> + pSrc->sec_al_filter)) != SA_AIS_OK) >>>>>>>> + goto done; >>>>>>>> + } >>>>>>>> + >>>>>>>> + if (pSrc->sta_ch_filter) { >>>>>>>> + pDes->sta_ch_filter = calloc(1, >>>>>>>> sizeof(SaNtfStateChangeNotificationFilterT)); >>>>>>>> + des_header = >>>>>>>> &(pDes->sta_ch_filter->notificationFilterHeader); >>>>>>>> + src_header = >>>>>>>> &(pSrc->sta_ch_filter->notificationFilterHeader); >>>>>>>> + if ((rc = ntfsv_filter_header_alloc(des_header, >>>>>>>> src_header->numEventTypes, >>>>>>>> + src_header->numNotificationObjects, >>>>>>>> + src_header->numNotifyingObjects, >>>>>>>> + src_header->numNotificationClassIds)) != SA_AIS_OK) >>>>>>>> + goto done; >>>>>>>> + if ((rc = >>>>>>>> ntfsv_filter_state_ch_alloc(pDes->sta_ch_filter, >>>>>>>> + pSrc->sta_ch_filter->numSourceIndicators, >>>>>>>> + pSrc->sta_ch_filter->numStateChanges)) != SA_AIS_OK) >>>>>>>> + goto done; >>>>>>>> + if ((rc = >>>>>>>> ntfsv_copy_ntf_filter_state_ch(pDes->sta_ch_filter, >>>>>>>> + pSrc->sta_ch_filter)) != SA_AIS_OK) >>>>>>>> + goto done; >>>>>>>> + } >>>>>>>> + >>>>>>>> + if (pSrc->obj_cr_del_filter) { >>>>>>>> + pDes->obj_cr_del_filter = calloc(1, >>>>>>>> sizeof(SaNtfObjectCreateDeleteNotificationFilterT)); >>>>>>>> + des_header = >>>>>>>> &(pDes->obj_cr_del_filter->notificationFilterHeader); >>>>>>>> + src_header = >>>>>>>> &(pSrc->obj_cr_del_filter->notificationFilterHeader); >>>>>>>> + if ((rc = ntfsv_filter_header_alloc(des_header, >>>>>>>> src_header->numEventTypes, >>>>>>>> + src_header->numNotificationObjects, >>>>>>>> + src_header->numNotifyingObjects, >>>>>>>> + src_header->numNotificationClassIds)) != SA_AIS_OK) >>>>>>>> + goto done; >>>>>>>> + if ((rc = >>>>>>>> ntfsv_filter_obj_cr_del_alloc(pDes->obj_cr_del_filter, >>>>>>>> + pSrc->obj_cr_del_filter->numSourceIndicators)) != SA_AIS_OK) >>>>>>>> + goto done; >>>>>>>> + if ((rc = >>>>>>>> ntfsv_copy_ntf_filter_obj_cr_del(pDes->obj_cr_del_filter, >>>>>>>> + pSrc->obj_cr_del_filter)) != SA_AIS_OK) >>>>>>>> + goto done; >>>>>>>> + } >>>>>>>> + >>>>>>>> + if (pSrc->att_ch_filter) { >>>>>>>> + pDes->att_ch_filter = calloc(1, >>>>>>>> sizeof(SaNtfAttributeChangeNotificationFilterT)); >>>>>>>> + des_header = >>>>>>>> &(pDes->att_ch_filter->notificationFilterHeader); >>>>>>>> + src_header = >>>>>>>> &(pSrc->att_ch_filter->notificationFilterHeader); >>>>>>>> + if ((rc = ntfsv_filter_header_alloc(des_header, >>>>>>>> src_header->numEventTypes, >>>>>>>> + src_header->numNotificationObjects, >>>>>>>> + src_header->numNotifyingObjects, >>>>>>>> + src_header->numNotificationClassIds)) != SA_AIS_OK) >>>>>>>> + goto done; >>>>>>>> + if ((rc = >>>>>>>> ntfsv_filter_attr_change_alloc(pDes->att_ch_filter, >>>>>>>> + pSrc->att_ch_filter->numSourceIndicators)) != SA_AIS_OK) >>>>>>>> + goto done; >>>>>>>> + if ((rc = >>>>>>>> ntfsv_copy_ntf_filter_attr_ch(pDes->att_ch_filter, >>>>>>>> + pSrc->att_ch_filter)) != SA_AIS_OK) >>>>>>>> + goto done; >>>>>>>> + } >>>>>>>> +done: >>>>>>>> + TRACE_LEAVE(); >>>>>>>> + return rc; >>>>>>>> +} >>>>>>>> + >>>>>>>> >>>>> +/********************************************************* >>>>> ******************* >>>>>>>> + Name : ntfa_del_ntf_filter_ptrs >>>>>>>> + >>>>>>>> + Description : Delete the filter pointers >>>>>>>> + >>>>>>>> + Arguments : filter_ptrs* [IN/OUT]: filter pointers >>>>>>>> + >>>>>>>> + Return Values : SA_AIS_OK if succeed, other values as failed >>>>>>>> + >>>>>>>> + Notes : None >>>>>>>> >>>>> +********************************************************* >>>>> *********************/ >>>>>>>> +SaAisErrorT ntfa_del_ntf_filter_ptrs(ntfsv_filter_ptrs_t* >>>>>>>> filter_ptrs) >>>>>>>> +{ >>>>>>>> + SaAisErrorT rc = SA_AIS_OK; >>>>>>>> + if (filter_ptrs->alarm_filter) { >>>>>>>> + ntfsv_filter_alarm_free(filter_ptrs->alarm_filter, true); >>>>>>>> + free(filter_ptrs->alarm_filter); >>>>>>>> + } >>>>>>>> + >>>>>>>> + if (filter_ptrs->sec_al_filter) { >>>>>>>> + ntfsv_filter_sec_alarm_free(filter_ptrs->sec_al_filter, true); >>>>>>>> + free(filter_ptrs->sec_al_filter); >>>>>>>> + } >>>>>>>> + >>>>>>>> + if (filter_ptrs->sta_ch_filter) { >>>>>>>> + ntfsv_filter_state_ch_free(filter_ptrs->sta_ch_filter, true); >>>>>>>> + free(filter_ptrs->sta_ch_filter); >>>>>>>> + } >>>>>>>> + >>>>>>>> + if (filter_ptrs->obj_cr_del_filter) { >>>>>>>> + ntfsv_filter_obj_cr_del_free(filter_ptrs->obj_cr_del_filter, >>>>>>>> true); >>>>>>>> + free(filter_ptrs->obj_cr_del_filter); >>>>>>>> + } >>>>>>>> + >>>>>>>> + if (filter_ptrs->att_ch_filter) { >>>>>>>> + ntfsv_filter_attr_ch_free(filter_ptrs->att_ch_filter, true); >>>>>>>> + free(filter_ptrs->att_ch_filter); >>>>>>>> + } >>>>>>>> + return rc; >>>>>>>> +} >>>>>>>> >>> ------------------------------------------------------------------------------ >>> >>> >>> >>> Site24x7 APM Insight: Get Deep Visibility into Application Performance >>> APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month >>> Monitor end-to-end web transactions and take corrective actions now >>> Troubleshoot faster and improve end-user experience. Signup Now! >>> http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140 >>> _______________________________________________ >>> Opensaf-devel mailing list >>> Opensaf-devel@lists.sourceforge.net >>> https://lists.sourceforge.net/lists/listinfo/opensaf-devel >>> >> ------------------------------------------------------------------------------ Site24x7 APM Insight: Get Deep Visibility into Application Performance APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month Monitor end-to-end web transactions and take corrective actions now Troubleshoot faster and improve end-user experience. Signup Now! http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140 _______________________________________________ Opensaf-devel mailing list Opensaf-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/opensaf-devel