Hi Minh Ack, sorry for beeing a bit unclear
Thanks Lennart > -----Original Message----- > From: minh chau [mailto:minh.c...@dektech.com.au] > Sent: den 18 mars 2016 07:36 > To: Lennart Lund; praveen.malv...@oracle.com; Vu Minh Nguyen > Cc: opensaf-devel@lists.sourceforge.net; Anders Widell > Subject: Re: [PATCH 2 of 5] NTF: Add support cloud resilience for NTF Agent > [#1180] V3 > > Hi Lennart, > > I guess it's an ACK from you? Vu and Praveen gave ACK on V2 and if don't > have any comment on V3, can you please push it? > > Thanks, > Minh > > On 17/03/16 23:09, Lennart Lund wrote: > > Hi Minh > > > > See my comments inline [Lennart] > > > > Thanks > > Lennart > > > >> -----Original Message----- > >> From: Minh Chau H > >> Sent: den 16 mars 2016 15:58 > >> To: Lennart Lund; praveen.malv...@oracle.com; Vu Minh Nguyen > >> Cc: opensaf-devel@lists.sourceforge.net; Anders Widell; Minh Chau H > >> Subject: Re: [PATCH 2 of 5] NTF: Add support cloud resilience for NTF > Agent > >> [#1180] V3 > >> > >> Hi Lennart, > >> > >> Please see my comment in line with [Minh] > >> > >> Thanks, > >> Minh > >> > >> On 15/03/16 21:05, Lennart Lund wrote: > >>> Hi Minh, > >>> > >>> I still think it is better to have all the mutex handling in the API > >>> function. > >> Mutex handling is actually not taken away from the API function by doing > it in > >> a function called from the API function it's only hidden and the risk of > >> creating deadlocks increase. However in this case it is under control and > >> anyway the usage of global variables within the function is hidden as well. > I > >> give it to you to decide. > >> [Minh] The reason I suggest that handling cb_lock mutex in separate > >> function, because I have seen the deadlock reported in #1521, it should > >> be generalized as below: > >> saNtfFinalize() in thread 1 Unsubscribe() in thread 2 > >> // take handle > >> > >> // lock cb_lock > >> > >> // give handle > >> // take handle > >> > >> // lock cb_lock > >> -> I'm locked > >> // destroy handle > >> -> I'm locked too > >> > >> I think the similar deadlock scenarios still there in other APIs > >> (readFinalize vs readNext , ...), the reason is when locking cb (or take > >> handle), the next is not unlocking cb (or give handle) respectively. And > >> the fact that in current APIs code, a mix of cb_lock/handle usage where > >> a lot of "go to" in the middle of function would increase the risk of > >> running into the above scenario. Separating cb_lock in function should > >> be helpful. > >> The cb_lock is used to protect cb resource, > >> subscriptionListAdd()/subscriberListItemRemove() are example of this. > >> However, the code is not using cb_lock in consistent way to protect cb > >> resource, ntfa_reader_hdl_rec_add/ntfa_reader_hdl_rec_del for > instance, > >> which increases the risk of above deadlock. > >> The hidden deadlock you mentioned I guess, it happens because *cb_lock > - > >> separate - function* called after locking cb. But this case should not > >> happen given that it's *glanced* over in advance, like locking cb should > >> not be called just before calling subscriptionListAdd() > >> > >> So I think that protects cb variables of #1180 in separate function is > >> not ideal to fit with current APIs code but it's acceptable in the scope > >> of cloud resilience. > >> > > [Lennart] I am OK with your decision > >>> I don't think handling a cb_lock in functions called from the API > >>> functions > is > >> a solution for the future. Instead the global cb structure and other global > >> structures e.g. client structure , reader structure etc. should be removed > as > >> global variables. > >>> Instead all variables should be owned by the functionality that actually > use > >> them cf. private variables in C++. > >>> E.g. Client handles and client structures shall be owned by a client > handler > >> that can do all needed operations related to a client. If this handler must > use > >> locks it shall own its own mutex. > >>> There is no need to lock a whole cb structure with a lot of unrelated > >> variables if one client variable is read or changed. The client handler has > no > >> interest in how MDS is initiated and what handles needed for that > purpose > >> etc... > >>> When writing C-code, variables that must be shared by several functions > >> within a handler, can be isolated within that handler by giving the handler > its > >> own file and not exposing the variables in any .h file. The handler .h file > shall > >> only expose its interface which consists of functions but no variables. > >>> This will make the API functions clean from any handling of mutexes. > >> [Minh] This raises a good idea that how to make API functions stay clean > >> from mutexes handling. So we may need some sort of cb handler (or > >> manager) that only exposes interfaces to be called in API functions. > >> These interfaces give access (add/remove/...) to each specific cb > >> resource (client_rec, filters, ...) , and has cb_lock protection at > >> entry/exit point. The body of interfaces consist of actual functions > >> that performing activities on cb resource. > >> > >> Another refactoring I think it would be useful that the data structure > >> relates to client_rec/reader_rec/subscriber_rec should reflect the > >> object orientation as mentioned in specification, where client could be > >> producer/reader/subscriber. Currently a client_rec contains a list of > >> reader, but a list of subscriber is declared globally outside > >> client_rec. Also, the reader_list declared in ntfa_cb_t structure seems > >> not being used at all. I think refactoring object orientation would give > >> a support to the idea of implementation of cb handler as above. > >> > >> If this sounds right to you, there seems to be some things to do > > [Lennart] Yes it would be nice to do some refactoring to fix this kind of > problems. We should try to get rid of all system global variables e.g. the cb > structure. The cb structure tends to be some sort of "all purpose" collection > of globals that are used for different things (not related). This means that > we > may end up in situations where one thread wants to handle some variables > and at the same time another thread wants to handle other variables > unrelated but still protected by the same mutex. > > Another thing we can do is to start using C++ also for the agent except for > > a > thin C wrapper for the external API. This will make it much easier to create > clean code and we can also get rid of some complicated things like Patricia > trees via ncs API (not a very good API). Yes, this will work. It has been > tested > in AMF but has not yet been contributed. It is likely that it will be > contributed. > > > >>> Thanks > >>> Lennart > >>> > >>>> -----Original Message----- > >>>> From: minh chau [mailto:minh.c...@dektech.com.au] > >>>> Sent: den 15 mars 2016 02:05 > >>>> To: Lennart Lund; praveen.malv...@oracle.com; Vu Minh Nguyen > >>>> Cc: opensaf-devel@lists.sourceforge.net; Anders Widell; Minh Chau H > >>>> Subject: Re: [PATCH 2 of 5] NTF: Add support cloud resilience for NTF > >> Agent > >>>> [#1180] V3 > >>>> > >>>> Hi Lennart, > >>>> > >>>> The current code in agent now is using both protection of ncshm > handle > >>>> and global cb_lock mutex, and this happens in most of APIs with below > >>>> patterns > >>>> > >>>> // take lock > >>>> // doing something > >>>> // if not success > >>>> // unlock > >>>> // goto done > >>>> // unlock > >>>> // continue doing something > >>>> // done: > >>>> > >>>> // take lock > >>>> // doing something > >>>> // if not success > >>>> // goto done > >>>> // done: > >>>> // unlock > >>>> > >>>> These two patterns are now used in mix of both ncshm handle and > >> cb_lock > >>>> as well. Because of this, a lot of release locking at the end of > >>>> function, and it becomes harder to maintain and easy to makes mistake > >>>> that leads to deadlock. > >>>> In this case for cloud resilience, if ntfa_ntfsv_state is protected by > >>>> cb_lock inside of calling functions which are APIs, that also introduces > >>>> more duplicated above patterns, not only checkNtfServerState() but > also > >>>> somewhere just ntfa_ntfsv_state to be checked (Finalize, > Unsubscribed, > >>>> ReadFinalize). > >>>> Your comment is right also, there would be a risk that overlapping > >>>> protection and this should be avoided in normal cases. > >>>> But I think in NTF API function it'd better: > >>>> - cb_lock is taken away from API function, accessing cb resource > >>>> should be written in separate function in which the cb_lock is used > >>>> - Only ncshm handle protection is used in API, don't worry about > >>>> cb_lock > >>>> > >>>> Doing this way, I think the API code would look clear and reduce > >>>> duplicated pattern. > >>>> > >>>> I think we had a quick discussion and agreed that a ticket should be > >>>> raised for this matter, but haven't come up a generic solution. The > >>>> above is not final solution but I hope it makes the code a bit clearer. > >>>> And that's the way I was trying to thread safe the cloud resilience > >>>> variables. If it sounds right to you I think we can leave the rest for > >>>> another ticket. Otherwise, I can also change back to the way that > >>>> cb_lock has being used in above patterns so far. Then we may have > >>>> further discussion on this. > >>>> > >>>> Thanks, > >>>> Minh > >>>> > >>>> > >>>> > >>>> On 14/03/16 22:59, Lennart Lund wrote: > >>>>> Hi Minh, > >>>>> > >>>>> I see that you are using mutexes inside the checkNtfServerState(). I > >> don't > >>>> think this is a good solution since the same mutex is used directly in > >>>> the > >>>> function calling checkNtfServerState(). The mutex usage in the > >>>> checkNtfServerState() is hidden and there is a risk that this function > may > >> be > >>>> placed within a protected area in the calling function. It is better to > write a > >>>> note in the checkNtfServerState() function head clearly telling that this > >>>> function is not thread safe and has to be protected with the cb_lock > >> mutex > >>>> and then use the mutex in the calling function. > >>>>> Also I found a lot more unprotected usage of the global ntfa_cb > >> structure > >>>> but that is not directly related to the resilience update e.g a lot of > >> functions > >>>> taking a pointer to this structure. I think a ticket for this should be > written > >>>> now. The fix for checkNtfServerState() will just make sure that the > >> resilience > >>>> patch don't add even more thread related issues. > >>>>> Thanks > >>>>> Lennart > >>>>> > >>>>>> -----Original Message----- > >>>>>> From: Minh Hon Chau [mailto:minh.c...@dektech.com.au] > >>>>>> Sent: den 14 mars 2016 03:08 > >>>>>> To: Lennart Lund; praveen.malv...@oracle.com; Vu Minh Nguyen; > >> Minh > >>>>>> Chau H > >>>>>> Cc: opensaf-devel@lists.sourceforge.net > >>>>>> Subject: [PATCH 2 of 5] NTF: Add support cloud resilience for NTF > Agent > >>>>>> [#1180] V3 > >>>>>> > >>>>>> osaf/libs/agents/saf/ntfa/ntfa.h | 31 +- > >>>>>> osaf/libs/agents/saf/ntfa/ntfa_api.c | 702 > >>>>>> +++++++++++++++++++++++++++------ > >>>>>> osaf/libs/agents/saf/ntfa/ntfa_mds.c | 14 +- > >>>>>> osaf/libs/agents/saf/ntfa/ntfa_util.c | 465 > >> +++++++++++++++++++++- > >>>>>> 4 files changed, 1057 insertions(+), 155 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,61 @@ > >>>>>> /* 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 Down and No Active > (temporary > >> no > >>>>>> active) > >>>>>> + */ > >>>>>> +static SaAisErrorT checkNtfServerState() > >>>>>> +{ > >>>>>> + SaAisErrorT rc = SA_AIS_ERR_NOT_SUPPORTED; > >>>>>> + > >>>>>> + osafassert(pthread_mutex_lock(&ntfa_cb.cb_lock) == 0); > >>>>>> + > >>>>>> + /* 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; > >>>>>> + } 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); > >>>>>> + > >>>>>> + osafassert(pthread_mutex_unlock(&ntfa_cb.cb_lock) == 0); > >>>>>> + > >>>>>> + return rc; > >>>>>> +} > >>>>>> + > >>>>>> +/* > >>>>>> + * @Brief: Return ntf server state in thread safe manner > >>>>>> + * @Param: None > >>>>>> + * @Return: Server state > >>>>>> + */ > >>>>>> +static ntfa_ntfsv_state_t getServerState() > >>>>>> +{ > >>>>>> + osafassert(pthread_mutex_lock(&ntfa_cb.cb_lock) == 0); > >>>>>> + > >>>>>> + ntfa_ntfsv_state_t state = ntfa_cb.ntfa_ntfsv_state; > >>>>>> + > >>>>>> + osafassert(pthread_mutex_unlock(&ntfa_cb.cb_lock) == 0); > >>>>>> + return state; > >>>>>> +} > >>>>>> + > >>>>>> static SaAisErrorT checkNtfValueTypeRange(SaNtfValueTypeT > type) > >>>>>> { > >>>>>> return (type < SA_NTF_VALUE_UINT8 || type > > >>>>>> SA_NTF_VALUE_ARRAY)? SA_AIS_ERR_INVALID_PARAM > >>>>>> @@ -871,7 +921,271 @@ 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); > >>>>>> + osafassert(pthread_mutex_lock(&ntfa_cb.cb_lock) == 0); > >>>>>> + > >>>>>> + if (client_hdl->valid == true) > >>>>>> + goto done; > >>>>>> + > >>>>>> + 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: > >>>>>> + osafassert(pthread_mutex_unlock(&ntfa_cb.cb_lock) == 0); > >>>>>> + TRACE_LEAVE(); > >>>>>> + return rc; > >>>>>> +} > >>>>>> > >>>>>> > >> > /********************************************************** > >>>>>> ***************** > >>>>>> * 8.4.1 > >>>>>> * > >>>>>> @@ -923,15 +1237,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 +1290,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 +1303,7 @@ SaAisErrorT saNtfInitialize(SaNtfHandleT > >>>>>> > >>>>>> if (rc != SA_AIS_OK) { > >>>>>> TRACE_2("NTFA INIT FAILED\n"); > >>>>>> - ntfa_shutdown(); > >>>>>> + ntfa_shutdown(false); > >>>>>> } > >>>>>> > >>>>>> done: > >>>>>> @@ -1101,6 +1414,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 +1480,13 @@ SaAisErrorT saNtfFinalize(SaNtfHandleT n > >>>>>> > >>>>>> TRACE_ENTER(); > >>>>>> > >>>>>> + /* Check NTF server availability */ > >>>>>> + if (getServerState() == 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 +1494,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 +1541,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 +1685,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 +1755,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 +1835,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 +1943,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 +1958,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 +1998,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 +2017,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 +2057,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 +2083,7 @@ SaAisErrorT saNtfNotificationSubscribe(c > >>>>>> if (o_msg) > >>>>>> ntfa_msg_destroy(o_msg); > >>>>>> done: > >>>>>> + > >>>>>> ncshm_give_hdl(ntfHandle); > >>>>>> if (notificationFilterHandles) { > >>>>>> if (notificationFilterHandles- > >>>>>>> attributeChangeFilterHandle) > >>>>>> @@ -1737,6 +2097,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 +2362,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 +2426,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 +2467,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 +2598,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 +3066,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. > >>>>>> @@ -2727,9 +3098,8 @@ SaAisErrorT saNtfNotificationFilterFree( > >>>>>> SaAisErrorT saNtfNotificationUnsubscribe(SaNtfSubscriptionIdT > >>>>>> subscriptionId) > >>>>>> { > >>>>>> TRACE_ENTER(); > >>>>>> - SaAisErrorT rc = SA_AIS_ERR_NOT_EXIST; > >>>>>> + SaAisErrorT rc = SA_AIS_OK; > >>>>>> SaNtfHandleT ntfHandle; > >>>>>> - > >>>>>> ntfa_client_hdl_rec_t *client_hdl_rec; > >>>>>> > >>>>>> ntfsv_msg_t msg, *o_msg = NULL; > >>>>>> @@ -2737,6 +3107,12 @@ SaAisErrorT saNtfNotificationUnsubscribe > >>>>>> ntfsv_unsubscribe_req_t *send_param; > >>>>>> uint32_t timeout = NTFS_WAIT_TIME; > >>>>>> > >>>>>> + /* Check NTF server availability */ > >>>>>> + if (getServerState() == NTFA_NTFSV_NO_ACTIVE) { > >>>>>> + TRACE("NTFS server is temporarily unavailable"); > >>>>>> + rc = SA_AIS_ERR_TRY_AGAIN; > >>>>>> + goto done; > >>>>>> + } > >>>>>> > >>>>>> ntfHandle = ntfHandleGet(subscriptionId); > >>>>>> if (ntfHandle == 0) { > >>>>>> @@ -2753,9 +3129,10 @@ SaAisErrorT saNtfNotificationUnsubscribe > >>>>>> goto done; > >>>>>> } > >>>>>> > >>>>>> - /** > >>>>>> - ** Populate a sync MDS message > >>>>>> - **/ > >>>>>> + 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 +3141,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 +3155,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 +3186,19 @@ SaAisErrorT saNtfNotificationUnsubscribe > >>>>>> done_give_hdl: > >>>>>> if (o_msg) > >>>>>> ntfa_msg_destroy(o_msg); > >>>>>> + > >>>>>> + if (!client_hdl_rec->valid && getServerState() == > >>>>>> NTFA_NTFSV_UP) { > >>>>>> + 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 +3222,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 +3257,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 +3281,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 +3315,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 +3341,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; > >>>>>> @@ -2955,7 +3355,7 @@ done: > >>>>>> /* 3.15.4.2 saNtfNotificationReadFinalize() */ > >>>>>> SaAisErrorT saNtfNotificationReadFinalize(SaNtfReadHandleT > >>>> readhandle) > >>>>>> { > >>>>>> - SaAisErrorT rc = SA_AIS_ERR_NOT_SUPPORTED; > >>>>>> + SaAisErrorT rc = SA_AIS_OK; > >>>>>> uint32_t oas_rc = NCSCC_RC_FAILURE; > >>>>>> > >>>>>> ntfa_client_hdl_rec_t *client_hdl_rec; > >>>>>> @@ -2966,6 +3366,12 @@ SaAisErrorT saNtfNotificationReadFinaliz > >>>>>> uint32_t timeout = NTFS_WAIT_TIME; > >>>>>> > >>>>>> TRACE_ENTER(); > >>>>>> + /* Check NTF server availability */ > >>>>>> + if (getServerState() == NTFA_NTFSV_NO_ACTIVE) { > >>>>>> + TRACE("NTFS server is temporarily unavailable"); > >>>>>> + rc = SA_AIS_ERR_TRY_AGAIN; > >>>>>> + goto done; > >>>>>> + } > >>>>>> > >>>>>> /* retrieve notification filter hdl rec */ > >>>>>> reader_hdl_rec = ncshm_take_hdl(NCS_SERVICE_ID_NTFA, > >>>>>> readhandle); > >>>>>> @@ -2983,42 +3389,39 @@ 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; > >>>>>> + 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; > >>>>>> + } > >>>>>> } > >>>>>> > >>>>>> - /* 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(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 +3432,20 @@ SaAisErrorT saNtfNotificationReadFinaliz > >>>>>> done_give_hdls: > >>>>>> if (o_msg) > >>>>>> ntfa_msg_destroy(o_msg); > >>>>>> + > >>>>>> + if (!client_hdl_rec->valid && getServerState() == > >>>>>> NTFA_NTFSV_UP) { > >>>>>> + 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 +3499,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 +3526,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,12 @@ 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; > >>>>>> + > >>>>>> + if (mds_cb_info- > >>>>>>> info.svc_evt.i_change == NCSMDS_NO_ACTIVE) { > >>>>>> + > >>>>>> ntfa_update_ntfsv_state(NTFA_NTFSV_NO_ACTIVE); > >>>>>> + } else > >>>>>> + > >>>>>> ntfa_update_ntfsv_state(NTFA_NTFSV_DOWN); > >>>>>> + > >>>>>> > >>>>>> pthread_mutex_unlock(&ntfa_cb.cb_lock); > >>>>>> } > >>>>>> break; > >>>>>> @@ -382,7 +387,12 @@ 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; > >>>>>> + > >>>>>> + if (mds_cb_info- > >>>>>>> info.svc_evt.i_change == NCSMDS_NEW_ACTIVE) { > >>>>>> + > >>>>>> ntfa_update_ntfsv_state(NTFA_NTFSV_NEW_ACTIVE); > >>>>>> + } else > >>>>>> + > >>>>>> ntfa_update_ntfsv_state(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_s > >>>>>> ync_sel), 30000); > >>>>>> + > >>>>>> osaf_poll_one_fd(m_GET_FD_FROM_SEL_OBJ(ntfa_cb.ntfs_s > >>>>>> ync_sel), 10000); > >>>>>> > >>>>>> 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 */ > >>>>>> + 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; > >>>>>> +} > > ------------------------------------------------------------------------------ Transform Data into Opportunity. Accelerate data analysis in your applications with Intel Data Analytics Acceleration Library. Click to learn more. http://pubads.g.doubleclick.net/gampad/clk?id=278785231&iu=/4140 _______________________________________________ Opensaf-devel mailing list Opensaf-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/opensaf-devel