Hi Minh,

I had already acked v2.
Ack for version 3 also.


Thanks,
Praveen

On 21-Mar-16 5:36 AM, minh chau wrote:
> Hi Praveen, Vu
>
> Any comment on V3?
>
> Thanks,
> Minh
>
> On 18/03/16 19:01, Lennart Lund wrote:
>> 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=278785351&iu=/4140
_______________________________________________
Opensaf-devel mailing list
Opensaf-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/opensaf-devel

Reply via email to