Hi Minh

Ack, sorry for beeing a bit unclear

Thanks
Lennart

> -----Original Message-----
> From: minh chau [mailto:minh.c...@dektech.com.au]
> Sent: den 18 mars 2016 07:36
> To: Lennart Lund; praveen.malv...@oracle.com; Vu Minh Nguyen
> Cc: opensaf-devel@lists.sourceforge.net; Anders Widell
> Subject: Re: [PATCH 2 of 5] NTF: Add support cloud resilience for NTF Agent
> [#1180] V3
> 
> Hi Lennart,
> 
> I guess it's an ACK from you? Vu and Praveen gave ACK on V2 and if don't
> have any comment on V3, can you please push it?
> 
> Thanks,
> Minh
> 
> On 17/03/16 23:09, Lennart Lund wrote:
> > Hi Minh
> >
> > See my comments inline [Lennart]
> >
> > Thanks
> > Lennart
> >
> >> -----Original Message-----
> >> From: Minh Chau H
> >> Sent: den 16 mars 2016 15:58
> >> To: Lennart Lund; praveen.malv...@oracle.com; Vu Minh Nguyen
> >> Cc: opensaf-devel@lists.sourceforge.net; Anders Widell; Minh Chau H
> >> Subject: Re: [PATCH 2 of 5] NTF: Add support cloud resilience for NTF
> Agent
> >> [#1180] V3
> >>
> >> Hi Lennart,
> >>
> >> Please see my comment in line with [Minh]
> >>
> >> Thanks,
> >> Minh
> >>
> >> On 15/03/16 21:05, Lennart Lund wrote:
> >>> Hi Minh,
> >>>
> >>> I still think it is better to have all the mutex handling in the API 
> >>> function.
> >> Mutex handling is actually not taken away from the API function by doing
> it in
> >> a function called from the API function it's only hidden and the risk of
> >> creating deadlocks increase. However in this case it is under control and
> >> anyway the usage of global variables within the function is hidden as well.
> I
> >> give it to you to decide.
> >> [Minh] The reason I suggest that handling cb_lock mutex in separate
> >> function, because I have seen the deadlock reported in #1521, it should
> >> be generalized as below:
> >>          saNtfFinalize() in thread 1        Unsubscribe() in thread 2
> >>          // take handle
> >>
> >>          // lock cb_lock
> >>
> >>          // give handle
> >>                                                          // take handle
> >>
> >>                                                          // lock cb_lock
> >>                                                          -> I'm locked
> >>          // destroy handle
> >>          -> I'm locked too
> >>
> >> I think the similar deadlock scenarios still there in other APIs
> >> (readFinalize vs readNext , ...), the reason is when locking cb (or take
> >> handle), the next is not unlocking cb (or give handle) respectively. And
> >> the fact that in current APIs code, a mix of cb_lock/handle usage where
> >> a lot of "go to" in the middle of function  would increase the risk of
> >> running into the above scenario. Separating cb_lock in function should
> >> be helpful.
> >> The cb_lock is used to protect cb resource,
> >> subscriptionListAdd()/subscriberListItemRemove() are example of this.
> >> However, the code is not using cb_lock in consistent way to protect cb
> >> resource, ntfa_reader_hdl_rec_add/ntfa_reader_hdl_rec_del for
> instance,
> >> which increases the risk of above deadlock.
> >> The hidden deadlock you mentioned I guess, it happens because *cb_lock
> -
> >> separate - function* called after locking cb. But this case should not
> >> happen given that it's *glanced* over in advance, like locking cb should
> >> not be called just before calling subscriptionListAdd()
> >>
> >> So I think that protects cb variables of #1180 in separate function is
> >> not ideal to fit with current APIs code but it's acceptable in the scope
> >> of cloud resilience.
> >>
> > [Lennart] I am OK with your decision
> >>> I don't think handling a cb_lock in functions called from the API 
> >>> functions
> is
> >> a solution for the future. Instead the global cb structure and other global
> >> structures e.g. client structure , reader structure etc. should be removed
> as
> >> global variables.
> >>> Instead all variables should be owned by the functionality that actually
> use
> >> them cf. private variables in C++.
> >>> E.g. Client handles and client structures shall be owned by a client
> handler
> >> that can do all needed operations related to a client. If this handler must
> use
> >> locks it shall own its own mutex.
> >>> There is no need to lock a whole cb structure with a lot of unrelated
> >> variables if one client variable is read or changed. The client handler has
> no
> >> interest in how MDS is initiated and what handles needed for that
> purpose
> >> etc...
> >>> When writing C-code, variables that must be shared by several functions
> >> within a handler, can be isolated within that handler by giving the handler
> its
> >> own file and not exposing the variables in any .h file. The handler .h file
> shall
> >> only expose its interface which consists of functions but no variables.
> >>> This will make the API functions clean from any handling of mutexes.
> >> [Minh] This raises a good idea that how to make API functions stay clean
> >> from mutexes handling. So we may need some sort of cb handler (or
> >> manager) that only exposes interfaces to be called in API functions.
> >> These interfaces give access (add/remove/...) to each specific cb
> >> resource (client_rec, filters, ...) , and has cb_lock protection at
> >> entry/exit point. The body of interfaces consist of actual functions
> >> that performing activities on cb resource.
> >>
> >> Another refactoring I think it would be useful that the data structure
> >> relates to client_rec/reader_rec/subscriber_rec should reflect the
> >> object orientation as mentioned in specification, where client could be
> >> producer/reader/subscriber. Currently a client_rec contains a list of
> >> reader, but a list of subscriber is declared globally outside
> >> client_rec. Also, the reader_list declared in ntfa_cb_t structure seems
> >> not being used at all. I think refactoring object orientation would give
> >> a support to the idea of implementation of cb handler as above.
> >>
> >> If this sounds right to you, there seems to be some things to do
> > [Lennart] Yes it would be nice to do some refactoring to fix this kind of
> problems. We should try to get rid of all system global variables e.g. the cb
> structure. The cb structure tends to be some sort of "all purpose" collection
> of globals that are used for different things (not related). This means that 
> we
> may end up in situations where one thread wants to handle some variables
> and at the same time another thread wants to handle other variables
> unrelated but still protected by the same mutex.
> > Another thing we can do is to start using C++ also for the agent except for 
> > a
> thin C wrapper for the external API. This will make it much easier to create
> clean code and we can also get rid of some complicated things like Patricia
> trees via ncs API (not a very good API). Yes, this will work. It has been 
> tested
> in AMF but has not yet been contributed. It is likely that it will be 
> contributed.
> >
> >>> Thanks
> >>> Lennart
> >>>
> >>>> -----Original Message-----
> >>>> From: minh chau [mailto:minh.c...@dektech.com.au]
> >>>> Sent: den 15 mars 2016 02:05
> >>>> To: Lennart Lund; praveen.malv...@oracle.com; Vu Minh Nguyen
> >>>> Cc: opensaf-devel@lists.sourceforge.net; Anders Widell; Minh Chau H
> >>>> Subject: Re: [PATCH 2 of 5] NTF: Add support cloud resilience for NTF
> >> Agent
> >>>> [#1180] V3
> >>>>
> >>>> Hi Lennart,
> >>>>
> >>>> The current code in agent now is using both protection of ncshm
> handle
> >>>> and global cb_lock mutex, and this happens in most of APIs with below
> >>>> patterns
> >>>>
> >>>> // take lock
> >>>> // doing something
> >>>> // if not success
> >>>>       // unlock
> >>>>       // goto done
> >>>> // unlock
> >>>> // continue doing something
> >>>> // done:
> >>>>
> >>>> // take lock
> >>>> // doing something
> >>>> // if not success
> >>>>       // goto done
> >>>> // done:
> >>>>       // unlock
> >>>>
> >>>> These two patterns are now used in mix of both ncshm handle and
> >> cb_lock
> >>>> as well. Because of this, a lot of release locking at the end of
> >>>> function, and it becomes harder to maintain and easy to makes mistake
> >>>> that leads to deadlock.
> >>>> In this case for cloud resilience, if ntfa_ntfsv_state is protected by
> >>>> cb_lock inside of calling functions which are APIs, that also introduces
> >>>> more duplicated above patterns, not only checkNtfServerState() but
> also
> >>>> somewhere just ntfa_ntfsv_state to be checked (Finalize,
> Unsubscribed,
> >>>> ReadFinalize).
> >>>> Your comment is right also, there would be a risk that overlapping
> >>>> protection and this should be avoided in normal cases.
> >>>> But I think in NTF API function it'd better:
> >>>>        - cb_lock is taken away from API function, accessing cb resource
> >>>> should be written in separate function in which the cb_lock is used
> >>>>        - Only ncshm handle protection is used in API, don't worry about
> >>>> cb_lock
> >>>>
> >>>> Doing this way, I think the API code would look clear and reduce
> >>>> duplicated pattern.
> >>>>
> >>>> I think we had a quick discussion and agreed that a ticket should be
> >>>> raised for this matter, but haven't come up a generic solution. The
> >>>> above is not final solution but I hope it makes the code a bit clearer.
> >>>> And that's the way I was trying to thread safe the cloud resilience
> >>>> variables. If it sounds right to you I think we can leave the rest for
> >>>> another ticket. Otherwise, I can also change back to the way that
> >>>> cb_lock has being used in above patterns so far. Then we may have
> >>>> further discussion on this.
> >>>>
> >>>> Thanks,
> >>>> Minh
> >>>>
> >>>>
> >>>>
> >>>> On 14/03/16 22:59, Lennart Lund wrote:
> >>>>> Hi Minh,
> >>>>>
> >>>>> I see that you are using mutexes inside the checkNtfServerState(). I
> >> don't
> >>>> think this is a good solution since the same mutex  is used directly in 
> >>>> the
> >>>> function calling checkNtfServerState(). The mutex usage in the
> >>>> checkNtfServerState() is hidden and there is a risk that this function
> may
> >> be
> >>>> placed within a protected area in the calling function. It is better to
> write a
> >>>> note in the checkNtfServerState() function head clearly telling that this
> >>>> function is not thread safe and has to be protected with the cb_lock
> >> mutex
> >>>> and then use the mutex in the calling function.
> >>>>> Also I found a lot more unprotected usage of the global ntfa_cb
> >> structure
> >>>> but that is not directly related to the resilience update e.g a lot of
> >> functions
> >>>> taking a pointer to this structure. I think a ticket for this should be
> written
> >>>> now. The fix for checkNtfServerState() will just make sure that the
> >> resilience
> >>>> patch don't add even more thread related issues.
> >>>>> Thanks
> >>>>> Lennart
> >>>>>
> >>>>>> -----Original Message-----
> >>>>>> From: Minh Hon Chau [mailto:minh.c...@dektech.com.au]
> >>>>>> Sent: den 14 mars 2016 03:08
> >>>>>> To: Lennart Lund; praveen.malv...@oracle.com; Vu Minh Nguyen;
> >> Minh
> >>>>>> Chau H
> >>>>>> Cc: opensaf-devel@lists.sourceforge.net
> >>>>>> Subject: [PATCH 2 of 5] NTF: Add support cloud resilience for NTF
> Agent
> >>>>>> [#1180] V3
> >>>>>>
> >>>>>>     osaf/libs/agents/saf/ntfa/ntfa.h      |   31 +-
> >>>>>>     osaf/libs/agents/saf/ntfa/ntfa_api.c  |  702
> >>>>>> +++++++++++++++++++++++++++------
> >>>>>>     osaf/libs/agents/saf/ntfa/ntfa_mds.c  |   14 +-
> >>>>>>     osaf/libs/agents/saf/ntfa/ntfa_util.c |  465
> >> +++++++++++++++++++++-
> >>>>>>     4 files changed, 1057 insertions(+), 155 deletions(-)
> >>>>>>
> >>>>>>
> >>>>>> The patch contains support for cloud resilience feature
> >>>>>> in NTF Agent code. Please refer README.HYDRA for content
> >>>>>> of the changes
> >>>>>>
> >>>>>> diff --git a/osaf/libs/agents/saf/ntfa/ntfa.h
> >>>>>> b/osaf/libs/agents/saf/ntfa/ntfa.h
> >>>>>> --- a/osaf/libs/agents/saf/ntfa/ntfa.h
> >>>>>> +++ b/osaf/libs/agents/saf/ntfa/ntfa.h
> >>>>>> @@ -91,6 +91,7 @@ typedef struct ntfa_filter_hdl_rec {
> >>>>>>     typedef struct subscriberList {
> >>>>>>        SaNtfHandleT subscriberListNtfHandle;
> >>>>>>        SaNtfSubscriptionIdT subscriberListSubscriptionId;
> >>>>>> +      ntfsv_filter_ptrs_t filters; /* remember the filters used by 
> >>>>>> this
> >>>>>> subscriber */
> >>>>>>        struct subscriberList *prev;
> >>>>>>        struct subscriberList *next;
> >>>>>>     } ntfa_subscriber_list_t;
> >>>>>> @@ -100,6 +101,10 @@ typedef struct ntfa_reader_hdl_rec {
> >>>>>>        unsigned int reader_id; /* handle value returned by NTFS
> >>>>>> for this client */
> >>>>>>        SaNtfHandleT ntfHandle;
> >>>>>>        unsigned int reader_hdl;        /* READER handle from handle
> >>>>>> mgr */
> >>>>>> +
> >>>>>> +      ntfsv_filter_ptrs_t filters; /* remember the filters used by 
> >>>>>> this
> >>>>>> reader */
> >>>>>> +      SaNtfSearchCriteriaT searchCriteria; /* remember the
> >>>>>> searchCriteria for recovery */
> >>>>>> +
> >>>>>>        struct ntfa_reader_hdl_rec *next;       /* next pointer for
> >>>>>> the list in ntfa_cb_t */
> >>>>>>        struct ntfa_client_hdl_rec *parent_hdl; /* Back Pointer to
> >>>>>> the client instantiation */
> >>>>>>     } ntfa_reader_hdl_rec_t;
> >>>>>> @@ -114,24 +119,35 @@ typedef struct ntfa_client_hdl_rec {
> >>>>>>        ntfa_reader_hdl_rec_t *reader_list;
> >>>>>>        SYSF_MBX mbx;           /* priority q mbx
> >>>>>> b/w MDS & Library */
> >>>>>>        struct ntfa_client_hdl_rec *next;       /* next pointer for
> >>>>>> the list in ntfa_cb_t */
> >>>>>> +      bool valid;             /* handle is valid if it's known by
> >>>>>> NTF server, used for headless hydra */
> >>>>>> +      SaVersionT version; /* the API version is being used by client,
> >>>>>> used for recover after headless */
> >>>>>>     } ntfa_client_hdl_rec_t;
> >>>>>>
> >>>>>>     /*
> >>>>>>      * The NTFA control block is the master anchor structure for all
> NTFA
> >>>>>>      * instantiations within a process.
> >>>>>>      */
> >>>>>> +typedef enum {
> >>>>>> +      NTFA_NTFSV_NONE = 0,
> >>>>>> +      NTFA_NTFSV_DOWN,
> >>>>>> +      NTFA_NTFSV_NO_ACTIVE,
> >>>>>> +      NTFA_NTFSV_NEW_ACTIVE,
> >>>>>> +      NTFA_NTFSV_UP
> >>>>>> +}ntfa_ntfsv_state_t;
> >>>>>> +
> >>>>>>     typedef struct {
> >>>>>>        pthread_mutex_t cb_lock;        /* CB lock */
> >>>>>>        ntfa_client_hdl_rec_t *client_list;     /* NTFA client
> >>>>>> handle database */
> >>>>>>        ntfa_reader_hdl_rec_t *reader_list;
> >>>>>>        MDS_HDL mds_hdl;        /* MDS handle */
> >>>>>>        MDS_DEST ntfs_mds_dest; /* NTFS absolute/virtual address
> >>>>>> */
> >>>>>> -      int ntfs_up;            /* Indicate that MDS subscription
> >>>>>> -                               * is complete */
> >>>>>> +
> >>>>>>        /* NTFS NTFA sync params */
> >>>>>>        int ntfs_sync_awaited;
> >>>>>>        NCS_SEL_OBJ ntfs_sync_sel;
> >>>>>>        SaUint32T ntf_var_data_limit;   /* max allowed
> >>>>>> variableDataSize */
> >>>>>> +      /* NTF Server state */
> >>>>>> +      ntfa_ntfsv_state_t ntfa_ntfsv_state;
> >>>>>>     } ntfa_cb_t;
> >>>>>>
> >>>>>>     /* ntfa_saf_api.c */
> >>>>>> @@ -149,7 +165,7 @@ extern void ntfsv_ntfa_evt_free(struct n
> >>>>>>
> >>>>>>     /* ntfa_init.c */
> >>>>>>     extern unsigned int ntfa_startup(void);
> >>>>>> -extern unsigned int ntfa_shutdown(void);
> >>>>>> +extern unsigned int ntfa_shutdown(bool forced);
> >>>>>>
> >>>>>>     /* ntfa_hdl.c */
> >>>>>>     extern SaAisErrorT ntfa_hdl_cbk_dispatch(ntfa_cb_t *,
> >>>>>> ntfa_client_hdl_rec_t *, SaDispatchFlagsT);
> >>>>>> @@ -159,6 +175,7 @@ extern ntfa_notification_hdl_rec_t *ntfa
> >>>>>>     extern ntfa_filter_hdl_rec_t
> >>>>>> *ntfa_filter_hdl_rec_add(ntfa_client_hdl_rec_t **hdl_rec);
> >>>>>>     extern void ntfa_hdl_list_del(ntfa_client_hdl_rec_t **);
> >>>>>>     extern uint32_t ntfa_hdl_rec_del(ntfa_client_hdl_rec_t **,
> >>>>>> ntfa_client_hdl_rec_t *);
> >>>>>> +extern void ntfa_hdl_rec_force_del(ntfa_client_hdl_rec_t **,
> >>>>>> ntfa_client_hdl_rec_t *);
> >>>>>>     extern uint32_t
> >>>> ntfa_notification_hdl_rec_del(ntfa_notification_hdl_rec_t
> >>>>>> **, ntfa_notification_hdl_rec_t *);
> >>>>>>     extern uint32_t ntfa_filter_hdl_rec_del(ntfa_filter_hdl_rec_t **,
> >>>>>> ntfa_filter_hdl_rec_t *);
> >>>>>>     extern bool ntfa_validate_ntfa_client_hdl(ntfa_cb_t *ntfa_cb,
> >>>>>> ntfa_client_hdl_rec_t *find_hdl_rec);
> >>>>>> @@ -166,11 +183,15 @@ extern bool ntfa_validate_ntfa_client_hd
> >>>>>>     /* ntfa_util.c */
> >>>>>>     extern ntfa_client_hdl_rec_t
> >>>> *ntfa_find_hdl_rec_by_client_id(ntfa_cb_t
> >>>>>> *ntfa_cb, uint32_t client_id);
> >>>>>>     extern void ntfa_msg_destroy(ntfsv_msg_t *msg);
> >>>>>> -extern void ntfa_hdl_rec_destructor(ntfa_notification_hdl_rec_t
> >>>>>> *instance);
> >>>>>> -extern void ntfa_filter_hdl_rec_destructor(ntfa_filter_hdl_rec_t
> >>>>>> +extern void
> ntfa_notification_destructor(ntfa_notification_hdl_rec_t
> >>>>>> *instance);
> >>>>>> +extern void ntfa_filter_destructor(ntfa_filter_hdl_rec_t
> >>>>>>
> >>>>>> *notificationFilterInstance);
> >>>>>>     extern ntfa_reader_hdl_rec_t
> >>>>>> *ntfa_reader_hdl_rec_add(ntfa_client_hdl_rec_t **hdl_rec);
> >>>>>>     extern uint32_t ntfa_reader_hdl_rec_del(ntfa_reader_hdl_rec_t
> **,
> >>>>>> ntfa_reader_hdl_rec_t *);
> >>>>>>     extern void ntfa_add_to_async_cbk_msg_list(ntfsv_msg_t **
> head,
> >>>>>> ntfsv_msg_t * new_node);
> >>>>>>     extern uint32_t ntfa_ntfs_msg_proc(ntfa_cb_t *cb, ntfsv_msg_t
> >>>>>> *ntfsv_msg, MDS_SEND_PRIORITY_TYPE prio);
> >>>>>> +extern void ntfa_update_ntfsv_state(ntfa_ntfsv_state_t
> >>>> changedState);
> >>>>>> +extern SaAisErrorT ntfa_copy_ntf_filter_ptrs(ntfsv_filter_ptrs_t*
> >> pDes,
> >>>>>> +
> >>>>>>                        const ntfsv_filter_ptrs_t* pSrc);
> >>>>>> +extern SaAisErrorT ntfa_del_ntf_filter_ptrs(ntfsv_filter_ptrs_t*
> >>>> filter_ptrs);
> >>>>>>     #endif   /* !NTFA_H */
> >>>>>> diff --git a/osaf/libs/agents/saf/ntfa/ntfa_api.c
> >>>>>> b/osaf/libs/agents/saf/ntfa/ntfa_api.c
> >>>>>> --- a/osaf/libs/agents/saf/ntfa/ntfa_api.c
> >>>>>> +++ b/osaf/libs/agents/saf/ntfa/ntfa_api.c
> >>>>>> @@ -34,11 +34,61 @@
> >>>>>>     /* The main controle block */
> >>>>>>     ntfa_cb_t ntfa_cb = {
> >>>>>>        .cb_lock = PTHREAD_MUTEX_INITIALIZER,
> >>>>>> +      .ntfa_ntfsv_state = NTFA_NTFSV_NONE,
> >>>>>>     };
> >>>>>>
> >>>>>>     /* list of subscriptions for this process */
> >>>>>>     ntfa_subscriber_list_t *subscriberNoList = NULL;
> >>>>>>
> >>>>>> +/*
> >>>>>> + * @Brief: Determine the common "availability" of API, which
> >> depends
> >>>> on
> >>>>>> the
> >>>>>> + *         NTF Server state
> >>>>>> + * @Param: None
> >>>>>> + * @Return: OK - If Server state is UP
> >>>>>> + *          TRY_AGAIN - If Server state is Down and No Active
> (temporary
> >> no
> >>>>>> active)
> >>>>>> + */
> >>>>>> +static SaAisErrorT checkNtfServerState()
> >>>>>> +{
> >>>>>> +      SaAisErrorT rc = SA_AIS_ERR_NOT_SUPPORTED;
> >>>>>> +
> >>>>>> +      osafassert(pthread_mutex_lock(&ntfa_cb.cb_lock) == 0);
> >>>>>> +
> >>>>>> +      /* Check NTF server availability */
> >>>>>> +      if (ntfa_cb.ntfa_ntfsv_state == NTFA_NTFSV_UP) {
> >>>>>> +              rc = SA_AIS_OK;
> >>>>>> +      } else if (ntfa_cb.ntfa_ntfsv_state == NTFA_NTFSV_DOWN) {
> >>>>>> +              TRACE("NTFS server is down");
> >>>>>> +              rc = SA_AIS_ERR_TRY_AGAIN;
> >>>>>> +      } else if (ntfa_cb.ntfa_ntfsv_state ==
> >>>>>> NTFA_NTFSV_NO_ACTIVE) {
> >>>>>> +              TRACE("NTFS server is unavailable");
> >>>>>> +              rc = SA_AIS_ERR_TRY_AGAIN;
> >>>>>> +      } else if (ntfa_cb.ntfa_ntfsv_state == NTFA_NTFSV_NONE) {
> >>>>>> +              TRACE("No NTF server is detected, or API is
> >>>>>> called during headless");
> >>>>>> +              rc = SA_AIS_ERR_TRY_AGAIN;
> >>>>>> +      } else
> >>>>>> +              TRACE("Not supported API call under NTF Server
> >>>>>> state (%u)",
> >>>>>> +
> >>>>>>        ntfa_cb.ntfa_ntfsv_state);
> >>>>>> +
> >>>>>> +      osafassert(pthread_mutex_unlock(&ntfa_cb.cb_lock) == 0);
> >>>>>> +
> >>>>>> +      return rc;
> >>>>>> +}
> >>>>>> +
> >>>>>> +/*
> >>>>>> + * @Brief: Return ntf server state in thread safe manner
> >>>>>> + * @Param: None
> >>>>>> + * @Return: Server state
> >>>>>> + */
> >>>>>> +static ntfa_ntfsv_state_t getServerState()
> >>>>>> +{
> >>>>>> +      osafassert(pthread_mutex_lock(&ntfa_cb.cb_lock) == 0);
> >>>>>> +
> >>>>>> +      ntfa_ntfsv_state_t state = ntfa_cb.ntfa_ntfsv_state;
> >>>>>> +
> >>>>>> +      osafassert(pthread_mutex_unlock(&ntfa_cb.cb_lock) == 0);
> >>>>>> +      return state;
> >>>>>> +}
> >>>>>> +
> >>>>>>     static SaAisErrorT checkNtfValueTypeRange(SaNtfValueTypeT
> type)
> >>>>>>     {
> >>>>>>        return (type < SA_NTF_VALUE_UINT8 || type >
> >>>>>> SA_NTF_VALUE_ARRAY)? SA_AIS_ERR_INVALID_PARAM
> >>>>>> @@ -871,7 +921,271 @@ SaAisErrorT getFilters(const SaNtfNotifi
> >>>>>>     }
> >>>>>>
> >>>>>>     /* end help functions */
> >>>>>> -
> >>>>>>
> >>
> +/*********************************************************
> >>>>>> *******************
> >>>>>> +  Name          : reinitializeClient
> >>>>>> +
> >>>>>> +  Description   : This routine sends initialize messages to NTF Server
> in
> >>>>>> +                order to obtain new client id
> >>>>>> +
> >>>>>> +  Arguments     : client_hdl* [IN]: client handle
> >>>>>> +
> >>>>>> +  Return Values : SA_AIS_OK if success, others are failure
> >>>>>> +
> >>>>>> +  Notes         : None
> >>>>>>
> >>
> +*********************************************************
> >>>>>> *********************/
> >>>>>> +SaAisErrorT reinitializeClient(ntfa_client_hdl_rec_t* client_hdl) {
> >>>>>> +      uint32_t mds_rc;
> >>>>>> +      SaAisErrorT rc = SA_AIS_OK;
> >>>>>> +      ntfsv_msg_t i_msg, *o_msg = NULL;
> >>>>>> +
> >>>>>> +      TRACE_ENTER();
> >>>>>> +
> >>>>>> +      memset(&i_msg, 0, sizeof(ntfsv_msg_t));
> >>>>>> +      i_msg.type = NTFSV_NTFA_API_MSG;
> >>>>>> +      i_msg.info.api_info.type = NTFSV_INITIALIZE_REQ;
> >>>>>> +      i_msg.info.api_info.param.init.version = client_hdl->version;
> >>>>>> +
> >>>>>> +      mds_rc = ntfa_mds_msg_sync_send(&ntfa_cb, &i_msg,
> >>>>>> &o_msg, NTFS_WAIT_TIME);
> >>>>>> +      switch (mds_rc) {
> >>>>>> +      case NCSCC_RC_SUCCESS:
> >>>>>> +              break;
> >>>>>> +      case NCSCC_RC_REQ_TIMOUT:
> >>>>>> +              rc = SA_AIS_ERR_TRY_AGAIN;
> >>>>>> +              goto done;
> >>>>>> +      default:
> >>>>>> +              rc = SA_AIS_ERR_BAD_HANDLE;
> >>>>>> +              goto done;
> >>>>>> +      }
> >>>>>> +
> >>>>>> +      osafassert(o_msg != NULL);
> >>>>>> +      /* Check response msg: type, rc */
> >>>>>> +      if (o_msg->info.api_resp_info.type != NTFSV_INITIALIZE_RSP)
> >>>>>> {
> >>>>>> +              TRACE("info.api_resp_info.type:%u", o_msg-
> >>>>>>> info.api_resp_info.type);
> >>>>>> +              rc = SA_AIS_ERR_LIBRARY;
> >>>>>> +              goto done;
> >>>>>> +      }
> >>>>>> +      if ((rc = o_msg->info.api_resp_info.rc) != SA_AIS_OK) {
> >>>>>> +              TRACE("info.api_resp_info.rc:%u", o_msg-
> >>>>>>> info.api_resp_info.rc);
> >>>>>> +              rc = SA_AIS_ERR_BAD_HANDLE;
> >>>>>> +              goto done;
> >>>>>> +      }
> >>>>>> +
> >>>>>> +      client_hdl->ntfs_client_id = o_msg-
> >>>>>>> info.api_resp_info.param.init_rsp.client_id;
> >>>>>> +      TRACE("Successfully recover client_id, new client_id:%u",
> >>>>>> +                      client_hdl->ntfs_client_id);
> >>>>>> +
> >>>>>> +done:
> >>>>>> +      if (o_msg)
> >>>>>> +              ntfa_msg_destroy(o_msg);
> >>>>>> +      TRACE_LEAVE();
> >>>>>> +      return rc;
> >>>>>> +}
> >>>>>>
> >>
> +/*********************************************************
> >>>>>> *******************
> >>>>>> +  Name          : recoverReader
> >>>>>> +
> >>>>>> +  Description   : This routine sends read_initialize messages to NTF
> >> Server
> >>>> in
> >>>>>> +                order to reintroduce this reader to NTF Server
> >>>>>> +
> >>>>>> +  Arguments     : client_hdl* [IN]: client handle
> >>>>>> +                reader_hdl* [IN]: reader handle
> >>>>>> +
> >>>>>> +  Return Values : SA_AIS_OK if success, others are failure
> >>>>>> +
> >>>>>> +  Notes         : None
> >>>>>>
> >>
> +*********************************************************
> >>>>>> *********************/
> >>>>>> +SaAisErrorT recoverReader(ntfa_client_hdl_rec_t* client_hdl,
> >>>>>> ntfa_reader_hdl_rec_t* reader_hdl) {
> >>>>>> +      uint32_t mds_rc;
> >>>>>> +      SaAisErrorT rc = SA_AIS_OK;
> >>>>>> +      ntfsv_msg_t i_msg, *o_msg = NULL;
> >>>>>> +      ntfsv_reader_init_req_2_t *send_param;
> >>>>>> +
> >>>>>> +      TRACE_ENTER();
> >>>>>> +
> >>>>>> +      /* Make sure the filters have not been deleted */
> >>>>>> +      if (reader_hdl->filters.alarm_filter == NULL &&
> >>>>>> +              reader_hdl->filters.att_ch_filter == NULL &&
> >>>>>> +              reader_hdl->filters.obj_cr_del_filter == NULL
> >>>>>> &&
> >>>>>> +              reader_hdl->filters.sec_al_filter == NULL &&
> >>>>>> +              reader_hdl->filters.sta_ch_filter == NULL)
> >>>>>> +              return SA_AIS_ERR_BAD_HANDLE;
> >>>>>> +
> >>>>>> +      memset(&i_msg, 0, sizeof(ntfsv_msg_t));
> >>>>>> +      i_msg.type = NTFSV_NTFA_API_MSG;
> >>>>>> +      i_msg.info.api_info.type = NTFSV_READER_INITIALIZE_REQ_2;
> >>>>>> +      send_param = &i_msg.info.api_info.param.reader_init_2;
> >>>>>> +      send_param->head.client_id = client_hdl->ntfs_client_id;
> >>>>>> +      send_param->head.searchCriteria = reader_hdl-
> >>>>>>> searchCriteria;
> >>>>>> +      send_param->f_rec = reader_hdl->filters;
> >>>>>> +
> >>>>>> +      mds_rc = ntfa_mds_msg_sync_send(&ntfa_cb, &i_msg,
> >>>>>> &o_msg, NTFS_WAIT_TIME);
> >>>>>> +
> >>>>>> +      switch (mds_rc) {
> >>>>>> +      case NCSCC_RC_SUCCESS:
> >>>>>> +              break;
> >>>>>> +      case NCSCC_RC_REQ_TIMOUT:
> >>>>>> +              rc = SA_AIS_ERR_TRY_AGAIN;
> >>>>>> +              goto done;
> >>>>>> +      default:
> >>>>>> +              rc = SA_AIS_ERR_BAD_HANDLE;
> >>>>>> +              goto done;
> >>>>>> +      }
> >>>>>> +
> >>>>>> +      osafassert(o_msg != NULL);
> >>>>>> +      if ((rc = o_msg->info.api_resp_info.rc) != SA_AIS_OK) {
> >>>>>> +              TRACE("o_msg->info.api_resp_info.rc:%u",
> >>>>>> o_msg->info.api_resp_info.rc);
> >>>>>> +              rc = SA_AIS_ERR_BAD_HANDLE;
> >>>>>> +              goto done;
> >>>>>> +      }
> >>>>>> +
> >>>>>> +      if (o_msg->info.api_resp_info.type !=
> >>>>>> NTFSV_READER_INITIALIZE_RSP) {
> >>>>>> +              TRACE("msg type (%d) failed", (int)o_msg-
> >>>>>>> info.api_resp_info.type);
> >>>>>> +              rc = SA_AIS_ERR_LIBRARY;
> >>>>>> +              goto done;
> >>>>>> +      }
> >>>>>> +      /* Update reader_id since it may be changed */
> >>>>>> +      reader_hdl->reader_id = o_msg-
> >>>>>>> info.api_resp_info.param.reader_init_rsp.readerId;
> >>>>>> +
> >>>>>> +      TRACE("Recover reader successfully");
> >>>>>> +done:
> >>>>>> +      if (o_msg)
> >>>>>> +              ntfa_msg_destroy(o_msg);
> >>>>>> +      TRACE_LEAVE();
> >>>>>> +      return rc;
> >>>>>> +}
> >>>>>>
> >>
> +/*********************************************************
> >>>>>> *******************
> >>>>>> +  Name          : recoverSubscriber
> >>>>>> +
> >>>>>> +  Description   : This routine sends subscribe messages to NTF
> Server in
> >>>>>> +                order to reintroduce this subscriber to NTF
> >>>>>> Server
> >>>>>> +
> >>>>>> +  Arguments     : client_hdl* [IN]: client handle
> >>>>>> +                subscriber_hdl* [IN]: subscriber handle
> >>>>>> +
> >>>>>> +  Return Values : SA_AIS_OK if success, others are failure
> >>>>>> +
> >>>>>> +  Notes         : None
> >>>>>>
> >>
> +*********************************************************
> >>>>>> *********************/
> >>>>>> +SaAisErrorT recoverSubscriber(ntfa_client_hdl_rec_t* client_hdl,
> >>>>>> +
> >>>>>>
> >>>>>>        ntfa_subscriber_list_t* subscriber_hdl) {
> >>>>>> +      uint32_t mds_rc;
> >>>>>> +      SaAisErrorT rc = SA_AIS_OK;
> >>>>>> +      ntfsv_msg_t i_msg, *o_msg = NULL;
> >>>>>> +      ntfsv_subscribe_req_t *send_param;
> >>>>>> +
> >>>>>> +      TRACE_ENTER();
> >>>>>> +
> >>>>>> +      /* Make sure the filters have not been deleted */
> >>>>>> +      if (subscriber_hdl->filters.alarm_filter == NULL &&
> >>>>>> +              subscriber_hdl->filters.att_ch_filter == NULL &&
> >>>>>> +              subscriber_hdl->filters.obj_cr_del_filter ==
> >>>>>> NULL &&
> >>>>>> +              subscriber_hdl->filters.sec_al_filter == NULL &&
> >>>>>> +              subscriber_hdl->filters.sta_ch_filter == NULL)
> >>>>>> +              return SA_AIS_ERR_BAD_HANDLE;
> >>>>>> +
> >>>>>> +      memset(&i_msg, 0, sizeof(ntfsv_msg_t));
> >>>>>> +      i_msg.type = NTFSV_NTFA_API_MSG;
> >>>>>> +      i_msg.info.api_info.type = NTFSV_SUBSCRIBE_REQ;
> >>>>>> +      send_param = &i_msg.info.api_info.param.subscribe;
> >>>>>> +
> >>>>>> +      send_param->client_id = client_hdl->ntfs_client_id;
> >>>>>> +      send_param->subscriptionId = subscriber_hdl-
> >>>>>>> subscriberListSubscriptionId;
> >>>>>> +      send_param->f_rec = subscriber_hdl->filters;
> >>>>>> +
> >>>>>> +      mds_rc = ntfa_mds_msg_sync_send(&ntfa_cb, &i_msg,
> >>>>>> &o_msg, NTFS_WAIT_TIME);
> >>>>>> +
> >>>>>> +      switch (mds_rc) {
> >>>>>> +      case NCSCC_RC_SUCCESS:
> >>>>>> +              break;
> >>>>>> +      case NCSCC_RC_REQ_TIMOUT:
> >>>>>> +              rc = SA_AIS_ERR_TRY_AGAIN;
> >>>>>> +              goto done;
> >>>>>> +      default:
> >>>>>> +              rc = SA_AIS_ERR_BAD_HANDLE;
> >>>>>> +              goto done;
> >>>>>> +      }
> >>>>>> +
> >>>>>> +      osafassert(o_msg != NULL);
> >>>>>> +
> >>>>>> +      if ((rc = o_msg->info.api_resp_info.rc) != SA_AIS_OK) {
> >>>>>> +              TRACE("o_msg->info.api_resp_info.rc:%u",
> >>>>>> o_msg->info.api_resp_info.rc);
> >>>>>> +              rc = SA_AIS_ERR_BAD_HANDLE;
> >>>>>> +              goto done;
> >>>>>> +      }
> >>>>>> +
> >>>>>> +      if (o_msg->info.api_resp_info.type !=
> >>>>>> NTFSV_SUBSCRIBE_RSP) {
> >>>>>> +              TRACE("msg type (%d) failed", (int)o_msg-
> >>>>>>> info.api_resp_info.type);
> >>>>>> +              rc = SA_AIS_ERR_LIBRARY;
> >>>>>> +              goto done;
> >>>>>> +      }
> >>>>>> +      TRACE("Recover subscriber successfully");
> >>>>>> +done:
> >>>>>> +      if (o_msg)
> >>>>>> +              ntfa_msg_destroy(o_msg);
> >>>>>> +
> >>>>>> +      TRACE_LEAVE();
> >>>>>> +      return rc;
> >>>>>> +}
> >>>>>>
> >>
> +/*********************************************************
> >>>>>> *******************
> >>>>>> +  Name          : recoverClient
> >>>>>> +
> >>>>>> +  Description   : In NTF-A.03.01, section 2.1.2. A client can be
> producer,
> >>>>>> +                subscriber, and reader at the same time.
> >>>>>> +                This routine will recovery:
> >>>>>> +                (1) client_id
> >>>>>> +                (2) Then it will continue the recovery if this
> >>>>>> client also
> >>>>>> +                has instance of subscriber or reader.
> >>>>>> +  Arguments     : client_hdl* [IN]: client handle
> >>>>>> +
> >>>>>> +  Return Values : SA_AIS_OK if success, others are failure
> >>>>>> +
> >>>>>> +  Notes         : None
> >>>>>>
> >>
> +*********************************************************
> >>>>>> *********************/
> >>>>>> +SaAisErrorT recoverClient(ntfa_client_hdl_rec_t *client_hdl) {
> >>>>>> +
> >>>>>> +      TRACE_ENTER();
> >>>>>> +      SaAisErrorT rc = SA_AIS_OK;
> >>>>>> +
> >>>>>> +      osafassert(client_hdl);
> >>>>>> +      osafassert(pthread_mutex_lock(&ntfa_cb.cb_lock) == 0);
> >>>>>> +
> >>>>>> +      if (client_hdl->valid == true)
> >>>>>> +              goto done;
> >>>>>> +
> >>>>>> +      if ((rc = reinitializeClient(client_hdl)) == SA_AIS_OK) {
> >>>>>> +              /* Restore reader */
> >>>>>> +              ntfa_reader_hdl_rec_t* reader_hdl =
> >>>>>> client_hdl->reader_list;
> >>>>>> +              while (reader_hdl != NULL && rc == SA_AIS_OK)
> >>>>>> {
> >>>>>> +                      rc = recoverReader(client_hdl,
> >>>>>> reader_hdl);
> >>>>>> +                      reader_hdl = reader_hdl->next;
> >>>>>> +              }
> >>>>>> +              if (rc != SA_AIS_OK) {
> >>>>>> +                      TRACE("Failed to restore reader
> >>>>>> (readerId:%d)",
> >>>>>> +
> >>>>>>        reader_hdl->reader_id);
> >>>>>> +                      goto done;
> >>>>>> +              }
> >>>>>> +              /* Restore subscriber */
> >>>>>> +              ntfa_subscriber_list_t* subscriber_hdl =
> >>>>>> subscriberNoList;
> >>>>>> +              while (subscriber_hdl != NULL && rc ==
> >>>>>> SA_AIS_OK) {
> >>>>>> +                      if (client_hdl->local_hdl ==
> >>>>>> subscriber_hdl->subscriberListNtfHandle)
> >>>>>> +                              rc =
> >>>>>> recoverSubscriber(client_hdl, subscriber_hdl);
> >>>>>> +                      subscriber_hdl = subscriber_hdl-
> >>>>>>> next;
> >>>>>> +              }
> >>>>>> +              if (rc != SA_AIS_OK) {
> >>>>>> +                      TRACE("Failed to restore
> >>>>>> subscriber (subscriptionId:%d)",
> >>>>>> +
> >>>>>>        subscriber_hdl->subscriberListSubscriptionId);
> >>>>>> +                      goto done;
> >>>>>> +              }
> >>>>>> +              client_hdl->valid = true;
> >>>>>> +      } else {
> >>>>>> +              TRACE("Failed to restore client (id:%d)",
> >>>>>> client_hdl->ntfs_client_id);
> >>>>>> +              goto done;
> >>>>>> +      }
> >>>>>> +
> >>>>>> +done:
> >>>>>> +      osafassert(pthread_mutex_unlock(&ntfa_cb.cb_lock) == 0);
> >>>>>> +      TRACE_LEAVE();
> >>>>>> +      return rc;
> >>>>>> +}
> >>>>>>
> >>>>>>
> >>
> /**********************************************************
> >>>>>> *****************
> >>>>>>      * 8.4.1
> >>>>>>      *
> >>>>>> @@ -923,15 +1237,14 @@ SaAisErrorT saNtfInitialize(SaNtfHandleT
> >>>>>>                version->releaseCode = NTF_RELEASE_CODE;
> >>>>>>                version->majorVersion =
> >>>>>> NTF_MAJOR_VERSION;
> >>>>>>                version->minorVersion =
> >>>>>> NTF_MINOR_VERSION;
> >>>>>> -              ntfa_shutdown();
> >>>>>> +              ntfa_shutdown(false);
> >>>>>>                rc = SA_AIS_ERR_VERSION;
> >>>>>>                goto done;
> >>>>>>        }
> >>>>>>
> >>>>>> -      if (!ntfa_cb.ntfs_up) {
> >>>>>> -              ntfa_shutdown();
> >>>>>> -              TRACE("NTFS server is down");
> >>>>>> -              rc = SA_AIS_ERR_TRY_AGAIN;
> >>>>>> +      /* Check NTF server availability */
> >>>>>> +      if ((rc = checkNtfServerState()) != SA_AIS_OK) {
> >>>>>> +              ntfa_shutdown(false);
> >>>>>>                goto done;
> >>>>>>        }
> >>>>>>
> >>>>>> @@ -977,7 +1290,7 @@ SaAisErrorT saNtfInitialize(SaNtfHandleT
> >>>>>>                rc = SA_AIS_ERR_NO_MEMORY;
> >>>>>>                goto err;
> >>>>>>        }
> >>>>>> -
> >>>>>> +      ntfa_hdl_rec->version = *version;
> >>>>>>        /* pass the handle value to the appl */
> >>>>>>        if (SA_AIS_OK == rc)
> >>>>>>                *ntfHandle = ntfa_hdl_rec->local_hdl;
> >>>>>> @@ -990,7 +1303,7 @@ SaAisErrorT saNtfInitialize(SaNtfHandleT
> >>>>>>
> >>>>>>        if (rc != SA_AIS_OK) {
> >>>>>>                TRACE_2("NTFA INIT FAILED\n");
> >>>>>> -              ntfa_shutdown();
> >>>>>> +              ntfa_shutdown(false);
> >>>>>>        }
> >>>>>>
> >>>>>>      done:
> >>>>>> @@ -1101,6 +1414,28 @@ SaAisErrorT saNtfDispatch(SaNtfHandleT n
> >>>>>>                goto done;
> >>>>>>        }
> >>>>>>
> >>>>>> +      /* Need to check NTF server availability here
> >>>>>> +       * Because if the notificationCallback just comes after
> >>>>>> MDS_DOWN
> >>>>>> +       * it will go to recovery then result in failure due to no 
> >>>>>> director
> >>>>>> +       */
> >>>>>> +      if ((rc = checkNtfServerState()) != SA_AIS_OK) {
> >>>>>> +              ncshm_give_hdl(ntfHandle);
> >>>>>> +              goto done;
> >>>>>> +      }
> >>>>>> +
> >>>>>> +      if (!hdl_rec->valid) {
> >>>>>> +              /* recovery */
> >>>>>> +              if ((rc = recoverClient(hdl_rec)) != SA_AIS_OK) {
> >>>>>> +                      if (rc ==
> >>>>>> SA_AIS_ERR_BAD_HANDLE) {
> >>>>>> +
> >>>>>>        ncshm_give_hdl(ntfHandle);
> >>>>>> +
> >>>>>>        osafassert(pthread_mutex_lock(&ntfa_cb.cb_lock) == 0);
> >>>>>> +
> >>>>>>        ntfa_hdl_rec_force_del(&ntfa_cb.client_list, hdl_rec);
> >>>>>> +
> >>>>>>        osafassert(pthread_mutex_unlock(&ntfa_cb.cb_lock) == 0);
> >>>>>> +
> >>>>>>        ntfa_shutdown(false);
> >>>>>> +                              goto done;
> >>>>>> +                      }
> >>>>>> +              }
> >>>>>> +      }
> >>>>>>        if ((rc = ntfa_hdl_cbk_dispatch(&ntfa_cb, hdl_rec,
> >>>>>> dispatchFlags)) != SA_AIS_OK)
> >>>>>>                TRACE("NTFA_DISPATCH_FAILURE");
> >>>>>>
> >>>>>> @@ -1145,6 +1480,13 @@ SaAisErrorT saNtfFinalize(SaNtfHandleT n
> >>>>>>
> >>>>>>        TRACE_ENTER();
> >>>>>>
> >>>>>> +      /* Check NTF server availability */
> >>>>>> +      if (getServerState() == NTFA_NTFSV_NO_ACTIVE) {
> >>>>>> +              TRACE("NTFS server is temporarily unavailable");
> >>>>>> +              rc = SA_AIS_ERR_TRY_AGAIN;
> >>>>>> +              goto done;
> >>>>>> +      }
> >>>>>> +
> >>>>>>        /* retrieve hdl rec */
> >>>>>>        hdl_rec = ncshm_take_hdl(NCS_SERVICE_ID_NTFA,
> >>>>>> ntfHandle);
> >>>>>>        if (hdl_rec == NULL) {
> >>>>>> @@ -1152,43 +1494,37 @@ SaAisErrorT saNtfFinalize(SaNtfHandleT n
> >>>>>>                rc = SA_AIS_ERR_BAD_HANDLE;
> >>>>>>                goto done;
> >>>>>>        }
> >>>>>> -
> >>>>>> -      /* Check Whether NTFS is up or not */
> >>>>>> -      if (!ntfa_cb.ntfs_up) {
> >>>>>> -              TRACE("NTFS down");
> >>>>>> -              rc = SA_AIS_ERR_TRY_AGAIN;
> >>>>>> -              goto done_give_hdl;
> >>>>>> +      if (hdl_rec->valid) {
> >>>>>> +              /** populate & send the finalize message
> >>>>>> +               ** and make sure the finalize from the server
> >>>>>> +               ** end returned before deleting the local
> >>>>>> records.
> >>>>>> +               **/
> >>>>>> +              memset(&msg, 0, sizeof(ntfsv_msg_t));
> >>>>>> +              msg.type = NTFSV_NTFA_API_MSG;
> >>>>>> +              msg.info.api_info.type = NTFSV_FINALIZE_REQ;
> >>>>>> +              msg.info.api_info.param.finalize.client_id =
> >>>>>> hdl_rec->ntfs_client_id;
> >>>>>> +
> >>>>>> +              mds_rc = ntfa_mds_msg_sync_send(&ntfa_cb,
> >>>>>> &msg, &o_msg, NTFS_WAIT_TIME);
> >>>>>> +              switch (mds_rc) {
> >>>>>> +              case NCSCC_RC_SUCCESS:
> >>>>>> +                      break;
> >>>>>> +              case NCSCC_RC_REQ_TIMOUT:
> >>>>>> +                      rc = SA_AIS_ERR_TIMEOUT;
> >>>>>> +
> >>>>>>        TRACE("ntfa_mds_msg_sync_send FAILED: %u", rc);
> >>>>>> +                      goto done_give_hdl;
> >>>>>> +              default:
> >>>>>> +
> >>>>>>        TRACE("ntfa_mds_msg_sync_send FAILED: %u", rc);
> >>>>>> +                      rc =
> >>>>>> SA_AIS_ERR_NO_RESOURCES;
> >>>>>> +                      goto done_give_hdl;
> >>>>>> +              }
> >>>>>> +
> >>>>>> +              if (o_msg != NULL) {
> >>>>>> +                      rc = o_msg-
> >>>>>>> info.api_resp_info.rc;
> >>>>>> +                      ntfa_msg_destroy(o_msg);
> >>>>>> +              } else
> >>>>>> +                      rc =
> >>>>>> SA_AIS_ERR_NO_RESOURCES;
> >>>>>>        }
> >>>>>>
> >>>>>> -    /** populate & send the finalize message
> >>>>>> -     ** and make sure the finalize from the server
> >>>>>> -     ** end returned before deleting the local records.
> >>>>>> -     **/
> >>>>>> -      memset(&msg, 0, sizeof(ntfsv_msg_t));
> >>>>>> -      msg.type = NTFSV_NTFA_API_MSG;
> >>>>>> -      msg.info.api_info.type = NTFSV_FINALIZE_REQ;
> >>>>>> -      msg.info.api_info.param.finalize.client_id = hdl_rec-
> >>>>>>> ntfs_client_id;
> >>>>>> -
> >>>>>> -      mds_rc = ntfa_mds_msg_sync_send(&ntfa_cb, &msg,
> >>>>>> &o_msg, NTFS_WAIT_TIME);
> >>>>>> -      switch (mds_rc) {
> >>>>>> -      case NCSCC_RC_SUCCESS:
> >>>>>> -              break;
> >>>>>> -      case NCSCC_RC_REQ_TIMOUT:
> >>>>>> -              rc = SA_AIS_ERR_TIMEOUT;
> >>>>>> -              TRACE("ntfa_mds_msg_sync_send FAILED: %u",
> >>>>>> rc);
> >>>>>> -              goto done_give_hdl;
> >>>>>> -      default:
> >>>>>> -              TRACE("ntfa_mds_msg_sync_send FAILED: %u",
> >>>>>> rc);
> >>>>>> -              rc = SA_AIS_ERR_NO_RESOURCES;
> >>>>>> -              goto done_give_hdl;
> >>>>>> -      }
> >>>>>> -
> >>>>>> -      if (o_msg != NULL) {
> >>>>>> -              rc = o_msg->info.api_resp_info.rc;
> >>>>>> -              ntfa_msg_destroy(o_msg);
> >>>>>> -      } else
> >>>>>> -              rc = SA_AIS_ERR_NO_RESOURCES;
> >>>>>> -
> >>>>>>        if (rc == SA_AIS_OK) {
> >>>>>>        /** delete the hdl rec
> >>>>>>              ** including all resources allocated by client if MDS 
> >>>>>> send is
> >>>>>> @@ -1205,7 +1541,7 @@ SaAisErrorT saNtfFinalize(SaNtfHandleT n
> >>>>>>        ncshm_give_hdl(ntfHandle);
> >>>>>>
> >>>>>>        if (rc == SA_AIS_OK) {
> >>>>>> -              rc = ntfa_shutdown();
> >>>>>> +              rc = ntfa_shutdown(false);
> >>>>>>                if (rc != NCSCC_RC_SUCCESS)
> >>>>>>                        TRACE_1("ntfa_shutdown
> >>>>>> failed");
> >>>>>>        }
> >>>>>> @@ -1349,7 +1685,7 @@ SaAisErrorT saNtfNotificationFree(SaNtfN
> >>>>>>        }
> >>>>>>
> >>>>>>        /* free the resources allocated by
> >>>>>> saNtf<ntfType>NotificationAllocate */
> >>>>>> -      ntfa_hdl_rec_destructor(notification_hdl_rec);
> >>>>>> +      ntfa_notification_destructor(notification_hdl_rec);
> >>>>>>
> >>>>>>         /** Delete the resources related to the notificationHandle &
> >>>>>>          *  remove reference in the client.
> >>>>>> @@ -1419,6 +1755,24 @@ SaAisErrorT saNtfNotificationSend(SaNtfN
> >>>>>>        }
> >>>>>>        osafassert(pthread_mutex_unlock(&ntfa_cb.cb_lock) == 0);
> >>>>>>
> >>>>>> +      /* Check NTF server availability */
> >>>>>> +      if ((rc = checkNtfServerState()) != SA_AIS_OK)
> >>>>>> +              goto done_give_hdls;
> >>>>>> +
> >>>>>> +      /* Recover if this is invalid handle */
> >>>>>> +      if (!client_rec->valid) {
> >>>>>> +              if ((rc = recoverClient(client_rec)) !=
> >>>>>> SA_AIS_OK) {
> >>>>>> +                      ncshm_give_hdl(client_handle);
> >>>>>> +
> >>>>>>        ncshm_give_hdl(notificationHandle);
> >>>>>> +                      if (rc ==
> >>>>>> SA_AIS_ERR_BAD_HANDLE) {
> >>>>>> +
> >>>>>>        osafassert(pthread_mutex_lock(&ntfa_cb.cb_lock) == 0);
> >>>>>> +
> >>>>>>        ntfa_hdl_rec_force_del(&ntfa_cb.client_list, client_rec);
> >>>>>> +
> >>>>>>        osafassert(pthread_mutex_unlock(&ntfa_cb.cb_lock) == 0);
> >>>>>> +
> >>>>>>        ntfa_shutdown(false);
> >>>>>> +                      }
> >>>>>> +                      goto err_free;
> >>>>>> +              }
> >>>>>> +      }
> >>>>>>         /**
> >>>>>>          ** Populate a sync MDS message
> >>>>>>          **/
> >>>>>> @@ -1481,13 +1835,6 @@ SaAisErrorT saNtfNotificationSend(SaNtfN
> >>>>>>                goto done_give_hdls;
> >>>>>>        }
> >>>>>>
> >>>>>> -      /* Check whether NTFS is up or not */
> >>>>>> -      if (!ntfa_cb.ntfs_up) {
> >>>>>> -              TRACE("NTFS down");
> >>>>>> -              rc = SA_AIS_ERR_TRY_AGAIN;
> >>>>>> -              goto done_give_hdls;
> >>>>>> -      }
> >>>>>> -
> >>>>>>        /* Send a sync MDS message to obtain a notification id */
> >>>>>>        mds_rc = ntfa_mds_msg_sync_send(&ntfa_cb, &msg,
> >>>>>> &o_msg, timeout);
> >>>>>>        switch (mds_rc) {
> >>>>>> @@ -1596,7 +1943,8 @@ static  SaNtfHandleT ntfHandleGet(SaNtfS
> >>>>>>        return ntfHandle;
> >>>>>>     }
> >>>>>>
> >>>>>> -static SaAisErrorT subscriptionListAdd(SaNtfHandleT ntfHandle,
> >>>>>> SaNtfSubscriptionIdT subscriptionId)
> >>>>>> +static SaAisErrorT subscriptionListAdd(SaNtfHandleT ntfHandle,
> >>>>>> SaNtfSubscriptionIdT subscriptionId,
> >>>>>> +
> >>>>>>
> >>>>>>        ntfsv_filter_ptrs_t filters)
> >>>>>>     {
> >>>>>>        SaAisErrorT rc = SA_AIS_OK;
> >>>>>>        ntfa_subscriber_list_t* ntfSubscriberList;
> >>>>>> @@ -1610,7 +1958,9 @@ static SaAisErrorT subscriptionListAdd(S
> >>>>>>        /* Add ntfHandle and subscriptionId into list */
> >>>>>>        ntfSubscriberList->subscriberListNtfHandle = ntfHandle;
> >>>>>>        ntfSubscriberList->subscriberListSubscriptionId =
> >>>>>> subscriptionId;
> >>>>>> -
> >>>>>> +      memset(&ntfSubscriberList->filters, 0,
> >>>>>> sizeof(ntfsv_filter_ptrs_t));
> >>>>>> +      ntfa_copy_ntf_filter_ptrs(&ntfSubscriberList->filters, 
> >>>>>> &filters);
> >>>>>> +
> >>>>>>        osafassert(pthread_mutex_lock(&ntfa_cb.cb_lock) == 0);
> >>>>>>        if (NULL == subscriberNoList) {
> >>>>>>                subscriberNoList = ntfSubscriberList;
> >>>>>> @@ -1648,6 +1998,7 @@ static void subscriberListItemRemove(SaN
> >>>>>>                        subscriberNoList = NULL;
> >>>>>>        }
> >>>>>>        TRACE_1("REMOVE: listPtr->SubscriptionId %d", listPtr-
> >>>>>>> subscriberListSubscriptionId);
> >>>>>> +      ntfa_del_ntf_filter_ptrs(&listPtr->filters);
> >>>>>>        free(listPtr);
> >>>>>>        osafassert(pthread_mutex_unlock(&ntfa_cb.cb_lock) == 0);
> >>>>>>     }
> >>>>>> @@ -1666,20 +2017,33 @@ SaAisErrorT saNtfNotificationSubscribe(c
> >>>>>>        ntfsv_msg_t msg, *o_msg = NULL;
> >>>>>>        ntfsv_subscribe_req_t *send_param;
> >>>>>>        uint32_t timeout = NTFS_WAIT_TIME;
> >>>>>> -
> >>>>>> +      bool recovery_failed = false;
> >>>>>>        TRACE_ENTER();
> >>>>>> +
> >>>>>>        rc = getFilters(notificationFilterHandles, &filters, &ntfHandle,
> >>>>>> &client_hdl_rec);
> >>>>>>        if (rc != SA_AIS_OK) {
> >>>>>>                TRACE("getFilters failed");
> >>>>>>                goto done;
> >>>>>>        }
> >>>>>>
> >>>>>> +      /* Check NTF server availability */
> >>>>>> +      if ((rc = checkNtfServerState()) != SA_AIS_OK)
> >>>>>> +              goto done;
> >>>>>> +
> >>>>>> +      /* recovery */
> >>>>>> +      if (client_hdl_rec != NULL && !client_hdl_rec->valid) {
> >>>>>> +              if ((rc = recoverClient(client_hdl_rec)) !=
> >>>>>> SA_AIS_OK) {
> >>>>>> +                      recovery_failed = true;
> >>>>>> +                      goto done;
> >>>>>> +              }
> >>>>>> +      }
> >>>>>> +
> >>>>>>        tmpHandle = ntfHandleGet(subscriptionId);
> >>>>>>        if (tmpHandle != 0) {
> >>>>>>                rc = SA_AIS_ERR_EXIST;
> >>>>>>                goto done;
> >>>>>>        }
> >>>>>> -      rc = subscriptionListAdd(ntfHandle, subscriptionId);
> >>>>>> +      rc = subscriptionListAdd(ntfHandle, subscriptionId, filters);
> >>>>>>        if (rc != SA_AIS_OK) {
> >>>>>>                goto done;
> >>>>>>        }
> >>>>>> @@ -1693,29 +2057,24 @@ SaAisErrorT saNtfNotificationSubscribe(c
> >>>>>>        send_param->client_id = client_hdl_rec->ntfs_client_id;
> >>>>>>        send_param->subscriptionId = subscriptionId;
> >>>>>>        send_param->f_rec = filters;
> >>>>>> -      /* Check whether NTFS is up or not */
> >>>>>> -      if (ntfa_cb.ntfs_up) {
> >>>>>> -              uint32_t rv;
> >>>>>> -              /* Send a sync MDS message to obtain a log
> >>>>>> stream id */
> >>>>>> -              rv = ntfa_mds_msg_sync_send(&ntfa_cb,
> >>>>>> &msg, &o_msg, timeout);
> >>>>>> -              if (rv == NCSCC_RC_SUCCESS) {
> >>>>>> -                      osafassert(o_msg != NULL);
> >>>>>> -                      if (SA_AIS_OK == o_msg-
> >>>>>>> info.api_resp_info.rc) {
> >>>>>> -
> >>>>>>        TRACE_1("subscriptionId from server %u",
> >>>>>> -
> >>>>>>        o_msg-
> >>>>>>> info.api_resp_info.param.subscribe_rsp.subscriptionId);
> >>>>>> -                      } else {
> >>>>>> -                              rc = o_msg-
> >>>>>>> info.api_resp_info.rc;
> >>>>>> -                              TRACE("Bad return
> >>>>>> status!!! rc = %d", rc);
> >>>>>> -                      }
> >>>>>> +
> >>>>>> +      uint32_t rv;
> >>>>>> +      /* Send a sync MDS message to obtain a log stream id */
> >>>>>> +      rv = ntfa_mds_msg_sync_send(&ntfa_cb, &msg, &o_msg,
> >>>>>> timeout);
> >>>>>> +      if (rv == NCSCC_RC_SUCCESS) {
> >>>>>> +              osafassert(o_msg != NULL);
> >>>>>> +              if (SA_AIS_OK == o_msg->info.api_resp_info.rc)
> >>>>>> {
> >>>>>> +                      TRACE_1("subscriptionId from
> >>>>>> server %u",
> >>>>>> +                              o_msg-
> >>>>>>> info.api_resp_info.param.subscribe_rsp.subscriptionId);
> >>>>>>                } else {
> >>>>>> -                      if(rv ==
> >>>>>> NCSCC_RC_INVALID_INPUT)
> >>>>>> -                              rc =
> >>>>>> SA_AIS_ERR_INVALID_PARAM;
> >>>>>> -                      else
> >>>>>> -                              rc =
> >>>>>> SA_AIS_ERR_TRY_AGAIN;
> >>>>>> +                      rc = o_msg-
> >>>>>>> info.api_resp_info.rc;
> >>>>>> +                      TRACE("Bad return status!!! rc =
> >>>>>> %d", rc);
> >>>>>>                }
> >>>>>>        } else {
> >>>>>> -              TRACE_1("NTFS down");
> >>>>>> -              rc = SA_AIS_ERR_TRY_AGAIN;
> >>>>>> +              if(rv == NCSCC_RC_INVALID_INPUT)
> >>>>>> +                      rc =
> >>>>>> SA_AIS_ERR_INVALID_PARAM;
> >>>>>> +              else
> >>>>>> +                      rc = SA_AIS_ERR_TRY_AGAIN;
> >>>>>>        }
> >>>>>>
> >>>>>>        if (rc != SA_AIS_OK) {
> >>>>>> @@ -1724,6 +2083,7 @@ SaAisErrorT saNtfNotificationSubscribe(c
> >>>>>>        if (o_msg)
> >>>>>>                ntfa_msg_destroy(o_msg);
> >>>>>>        done:
> >>>>>> +
> >>>>>>        ncshm_give_hdl(ntfHandle);
> >>>>>>        if (notificationFilterHandles) {
> >>>>>>                if (notificationFilterHandles-
> >>>>>>> attributeChangeFilterHandle)
> >>>>>> @@ -1737,6 +2097,13 @@ SaAisErrorT saNtfNotificationSubscribe(c
> >>>>>>                if (notificationFilterHandles->alarmFilterHandle)
> >>>>>>
> >>>>>>        ncshm_give_hdl(notificationFilterHandles-
> >>>>>>> alarmFilterHandle);
> >>>>>>        }
> >>>>>> +      if (recovery_failed && rc == SA_AIS_ERR_BAD_HANDLE) {
> >>>>>> +
> >>>>>>        osafassert(pthread_mutex_lock(&ntfa_cb.cb_lock) == 0);
> >>>>>> +              ntfa_hdl_rec_force_del(&ntfa_cb.client_list,
> >>>>>> client_hdl_rec);
> >>>>>> +
> >>>>>>        osafassert(pthread_mutex_unlock(&ntfa_cb.cb_lock) == 0);
> >>>>>> +              ntfa_shutdown(false);
> >>>>>> +      }
> >>>>>> +
> >>>>>>        TRACE_LEAVE();
> >>>>>>        return rc;
> >>>>>>     }
> >>>>>> @@ -1995,6 +2362,7 @@ SaAisErrorT saNtfSecurityAlarmNotificati
> >>>>>>                rc = SA_AIS_ERR_INVALID_PARAM;
> >>>>>>                goto done;
> >>>>>>        }
> >>>>>> +
> >>>>>>        /* retrieve hdl rec */
> >>>>>>        hdl_rec = ncshm_take_hdl(NCS_SERVICE_ID_NTFA,
> >>>>>> ntfHandle);
> >>>>>>        if (hdl_rec == NULL) {
> >>>>>> @@ -2058,6 +2426,7 @@ SaAisErrorT saNtfPtrValAllocate(SaNtfNot
> >>>>>>                rc = SA_AIS_ERR_INVALID_PARAM;
> >>>>>>                goto done;
> >>>>>>        }
> >>>>>> +
> >>>>>>        notification_hdl_rec =
> >>>>>> ncshm_take_hdl(NCS_SERVICE_ID_NTFA, notificationHandle);
> >>>>>>        if (notification_hdl_rec == NULL) {
> >>>>>>                TRACE("ncshm_take_hdl notificationHandle
> >>>>>> failed");
> >>>>>> @@ -2098,6 +2467,7 @@ SaAisErrorT saNtfArrayValAllocate(SaNtfN
> >>>>>>                rc = SA_AIS_ERR_INVALID_PARAM;
> >>>>>>                goto done;
> >>>>>>        }
> >>>>>> +
> >>>>>>        notification_hdl_rec =
> >>>>>> ncshm_take_hdl(NCS_SERVICE_ID_NTFA, notificationHandle);
> >>>>>>        if (notification_hdl_rec == NULL) {
> >>>>>>                TRACE("ncshm_take_hdl notificationHandle
> >>>>>> failed");
> >>>>>> @@ -2228,6 +2598,7 @@ SaAisErrorT saNtfArrayValGet(SaNtfNotifi
> >>>>>>                rc = SA_AIS_ERR_INVALID_PARAM;
> >>>>>>                goto done;
> >>>>>>        }
> >>>>>> +
> >>>>>>        notification_hdl_rec =
> >>>>>> ncshm_take_hdl(NCS_SERVICE_ID_NTFA, notificationHandle);
> >>>>>>        if (notification_hdl_rec == NULL) {
> >>>>>>                TRACE("ncshm_take_hdl notificationHandle
> >>>>>> failed");
> >>>>>> @@ -2695,7 +3066,7 @@ SaAisErrorT saNtfNotificationFilterFree(
> >>>>>>        }
> >>>>>>
> >>>>>>        /* free the resources allocated by
> >>>>>> saNtf<ntfType>FilterAllocate */
> >>>>>> -      ntfa_filter_hdl_rec_destructor(filter_hdl_rec);
> >>>>>> +      ntfa_filter_destructor(filter_hdl_rec);
> >>>>>>
> >>>>>>         /** Delete the resources related to the 
> >>>>>> notificationFilterHandle
> &
> >>>>>>          *  remove reference in the client.
> >>>>>> @@ -2727,9 +3098,8 @@ SaAisErrorT saNtfNotificationFilterFree(
> >>>>>>     SaAisErrorT saNtfNotificationUnsubscribe(SaNtfSubscriptionIdT
> >>>>>> subscriptionId)
> >>>>>>     {
> >>>>>>        TRACE_ENTER();
> >>>>>> -      SaAisErrorT rc = SA_AIS_ERR_NOT_EXIST;
> >>>>>> +      SaAisErrorT rc = SA_AIS_OK;
> >>>>>>        SaNtfHandleT ntfHandle;
> >>>>>> -
> >>>>>>        ntfa_client_hdl_rec_t *client_hdl_rec;
> >>>>>>
> >>>>>>        ntfsv_msg_t msg, *o_msg = NULL;
> >>>>>> @@ -2737,6 +3107,12 @@ SaAisErrorT saNtfNotificationUnsubscribe
> >>>>>>        ntfsv_unsubscribe_req_t *send_param;
> >>>>>>        uint32_t timeout = NTFS_WAIT_TIME;
> >>>>>>
> >>>>>> +      /* Check NTF server availability */
> >>>>>> +      if (getServerState() == NTFA_NTFSV_NO_ACTIVE) {
> >>>>>> +              TRACE("NTFS server is temporarily unavailable");
> >>>>>> +              rc = SA_AIS_ERR_TRY_AGAIN;
> >>>>>> +              goto done;
> >>>>>> +      }
> >>>>>>
> >>>>>>        ntfHandle = ntfHandleGet(subscriptionId);
> >>>>>>        if (ntfHandle == 0) {
> >>>>>> @@ -2753,9 +3129,10 @@ SaAisErrorT saNtfNotificationUnsubscribe
> >>>>>>                goto done;
> >>>>>>        }
> >>>>>>
> >>>>>> -      /**
> >>>>>> -         ** Populate a sync MDS message
> >>>>>> -         **/
> >>>>>> +      if (client_hdl_rec->valid) {
> >>>>>> +              /**
> >>>>>> +               ** Populate a sync MDS message
> >>>>>> +               **/
> >>>>>>                memset(&msg, 0, sizeof(ntfsv_msg_t));
> >>>>>>                msg.type = NTFSV_NTFA_API_MSG;
> >>>>>>                msg.info.api_info.type =
> >>>>>> NTFSV_UNSUBSCRIBE_REQ;
> >>>>>> @@ -2764,13 +3141,6 @@ SaAisErrorT saNtfNotificationUnsubscribe
> >>>>>>                send_param->client_id = client_hdl_rec-
> >>>>>>> ntfs_client_id;
> >>>>>>                send_param->subscriptionId = subscriptionId;
> >>>>>>
> >>>>>> -              /* Check whether NTFS is up or not */
> >>>>>> -              if (!ntfa_cb.ntfs_up) {
> >>>>>> -                      TRACE_1("NTFS down");
> >>>>>> -                      rc = SA_AIS_ERR_TRY_AGAIN;
> >>>>>> -                      goto done_give_hdl;
> >>>>>> -              }
> >>>>>> -
> >>>>>>                /* Send a sync MDS message to obtain a log
> >>>>>> stream id */
> >>>>>>                rc = ntfa_mds_msg_sync_send(&ntfa_cb,
> >>>>>> &msg, &o_msg, timeout);
> >>>>>>                if (rc != NCSCC_RC_SUCCESS) {
> >>>>>> @@ -2785,6 +3155,7 @@ SaAisErrorT saNtfNotificationUnsubscribe
> >>>>>>                        TRACE_1("Bad return status! rc =
> >>>>>> %d", rc);
> >>>>>>                        goto done_give_hdl;
> >>>>>>                }
> >>>>>> +      }
> >>>>>>                subscriberListItemRemove(subscriptionId);
> >>>>>>
> >>>>>>                /*Remove msg for subscriptionId from
> >>>>>> mailbox*/
> >>>>>> @@ -2815,6 +3186,19 @@ SaAisErrorT saNtfNotificationUnsubscribe
> >>>>>>      done_give_hdl:
> >>>>>>        if (o_msg)
> >>>>>>                 ntfa_msg_destroy(o_msg);
> >>>>>> +
> >>>>>> +      if (!client_hdl_rec->valid && getServerState() ==
> >>>>>> NTFA_NTFSV_UP) {
> >>>>>> +              if ((rc = recoverClient(client_hdl_rec)) !=
> >>>>>> SA_AIS_OK) {
> >>>>>> +                      if (rc ==
> >>>>>> SA_AIS_ERR_BAD_HANDLE) {
> >>>>>> +
> >>>>>>        ncshm_give_hdl(ntfHandle);
> >>>>>> +
> >>>>>>        osafassert(pthread_mutex_lock(&ntfa_cb.cb_lock) == 0);
> >>>>>> +
> >>>>>>        ntfa_hdl_rec_force_del(&ntfa_cb.client_list, client_hdl_rec);
> >>>>>> +
> >>>>>>        osafassert(pthread_mutex_unlock(&ntfa_cb.cb_lock) == 0);
> >>>>>> +
> >>>>>>        ntfa_shutdown(false);
> >>>>>> +                              goto done;
> >>>>>> +                      }
> >>>>>> +              }
> >>>>>> +      }
> >>>>>>        ncshm_give_hdl(ntfHandle);
> >>>>>>      done:
> >>>>>>        TRACE_LEAVE();
> >>>>>> @@ -2838,6 +3222,7 @@ SaAisErrorT saNtfNotificationReadInitial
> >>>>>>        ntfsv_reader_init_req_2_t *send_param;
> >>>>>>        uint32_t timeout = NTFS_WAIT_TIME;
> >>>>>>
> >>>>>> +      bool recovery_failed = false;
> >>>>>>        TRACE_ENTER();
> >>>>>>        if (notificationFilterHandles == NULL || readHandle == NULL) {
> >>>>>>                rc = SA_AIS_ERR_INVALID_PARAM;
> >>>>>> @@ -2872,6 +3257,18 @@ SaAisErrorT saNtfNotificationReadInitial
> >>>>>>                goto done_give_client_hdl;
> >>>>>>        }
> >>>>>>
> >>>>>> +      /* Check NTF server availability */
> >>>>>> +      if ((rc = checkNtfServerState()) != SA_AIS_OK)
> >>>>>> +              goto done_give_client_hdl;
> >>>>>> +
> >>>>>> +      /* recovery */
> >>>>>> +      if (client_hdl_rec != NULL && !client_hdl_rec->valid) {
> >>>>>> +              if ((rc = recoverClient(client_hdl_rec)) !=
> >>>>>> SA_AIS_OK) {
> >>>>>> +                      recovery_failed = true;
> >>>>>> +                      goto done_give_client_hdl;
> >>>>>> +              }
> >>>>>> +      }
> >>>>>> +
> >>>>>>         /**
> >>>>>>          ** Populate a sync MDS message
> >>>>>>          **/
> >>>>>> @@ -2884,13 +3281,6 @@ SaAisErrorT saNtfNotificationReadInitial
> >>>>>>        send_param->head.searchCriteria = searchCriteria;
> >>>>>>        send_param->f_rec = filters;
> >>>>>>
> >>>>>> -      /* Check whether NTFS is up or not */
> >>>>>> -      if (!ntfa_cb.ntfs_up) {
> >>>>>> -              TRACE("NTFS down");
> >>>>>> -              rc = SA_AIS_ERR_TRY_AGAIN;
> >>>>>> -              goto done_give_client_hdl;
> >>>>>> -      }
> >>>>>> -
> >>>>>>        /* Send a sync MDS message to obtain a log stream id */
> >>>>>>        rc = ntfa_mds_msg_sync_send(&ntfa_cb, &msg, &o_msg,
> >>>>>> timeout);
> >>>>>>        if (rc != NCSCC_RC_SUCCESS) {
> >>>>>> @@ -2925,12 +3315,16 @@ SaAisErrorT saNtfNotificationReadInitial
> >>>>>>        reader_hdl_rec->ntfHandle = ntfHandle;
> >>>>>>        /* Store the readerId returned from server */
> >>>>>>        reader_hdl_rec->reader_id = o_msg-
> >>>>>>> info.api_resp_info.param.reader_init_rsp.readerId;
> >>>>>> +      memset(&reader_hdl_rec->filters, 0,
> >>>>>> sizeof(ntfsv_filter_ptrs_t));
> >>>>>> +      ntfa_copy_ntf_filter_ptrs(&reader_hdl_rec->filters, &filters);
> >>>>>> +      reader_hdl_rec->searchCriteria = searchCriteria;
> >>>>>>         /**                  UnLock ntfa_CB            **/
> >>>>>>        osafassert(pthread_mutex_unlock(&ntfa_cb.cb_lock) == 0);
> >>>>>>
> >>>>>>     done_give_client_hdl:
> >>>>>>        if (o_msg)
> >>>>>>                ntfa_msg_destroy(o_msg);
> >>>>>> +
> >>>>>>        if (client_hdl_rec)
> >>>>>>                ncshm_give_hdl(client_hdl_rec->local_hdl);
> >>>>>>        if (notificationFilterHandles) {
> >>>>>> @@ -2947,6 +3341,12 @@ done_give_client_hdl:
> >>>>>>        }
> >>>>>>
> >>>>>>        ncshm_give_hdl(notificationFilterHandles-
> >>>>>>> alarmFilterHandle);
> >>>>>> +      if (recovery_failed && rc == SA_AIS_ERR_BAD_HANDLE) {
> >>>>>> +
> >>>>>>        osafassert(pthread_mutex_lock(&ntfa_cb.cb_lock) == 0);
> >>>>>> +              ntfa_hdl_rec_force_del(&ntfa_cb.client_list,
> >>>>>> client_hdl_rec);
> >>>>>> +
> >>>>>>        osafassert(pthread_mutex_unlock(&ntfa_cb.cb_lock) == 0);
> >>>>>> +              ntfa_shutdown(false);
> >>>>>> +      }
> >>>>>>     done:
> >>>>>>        TRACE_LEAVE();
> >>>>>>        return rc;
> >>>>>> @@ -2955,7 +3355,7 @@ done:
> >>>>>>     /*  3.15.4.2       saNtfNotificationReadFinalize()  */
> >>>>>>     SaAisErrorT saNtfNotificationReadFinalize(SaNtfReadHandleT
> >>>> readhandle)
> >>>>>>     {
> >>>>>> -      SaAisErrorT rc = SA_AIS_ERR_NOT_SUPPORTED;
> >>>>>> +      SaAisErrorT rc = SA_AIS_OK;
> >>>>>>        uint32_t oas_rc = NCSCC_RC_FAILURE;
> >>>>>>
> >>>>>>        ntfa_client_hdl_rec_t *client_hdl_rec;
> >>>>>> @@ -2966,6 +3366,12 @@ SaAisErrorT saNtfNotificationReadFinaliz
> >>>>>>        uint32_t timeout = NTFS_WAIT_TIME;
> >>>>>>
> >>>>>>        TRACE_ENTER();
> >>>>>> +      /* Check NTF server availability */
> >>>>>> +      if (getServerState() == NTFA_NTFSV_NO_ACTIVE) {
> >>>>>> +              TRACE("NTFS server is temporarily unavailable");
> >>>>>> +              rc = SA_AIS_ERR_TRY_AGAIN;
> >>>>>> +              goto done;
> >>>>>> +      }
> >>>>>>
> >>>>>>        /* retrieve notification filter hdl rec */
> >>>>>>        reader_hdl_rec = ncshm_take_hdl(NCS_SERVICE_ID_NTFA,
> >>>>>> readhandle);
> >>>>>> @@ -2983,42 +3389,39 @@ SaAisErrorT saNtfNotificationReadFinaliz
> >>>>>>        }
> >>>>>>        TRACE_1("reader_hdl_rec = %u", reader_hdl_rec-
> >>>>>>> reader_hdl);
> >>>>>> -    /**
> >>>>>> -     ** Populate a sync MDS message
> >>>>>> -     **/
> >>>>>> -      memset(&msg, 0, sizeof(ntfsv_msg_t));
> >>>>>> -      msg.type = NTFSV_NTFA_API_MSG;
> >>>>>> -      msg.info.api_info.type = NTFSV_READER_FINALIZE_REQ;
> >>>>>> -      send_param = &msg.info.api_info.param.reader_finalize;
> >>>>>> -      send_param->client_id = client_hdl_rec->ntfs_client_id;
> >>>>>> -      send_param->readerId = reader_hdl_rec->reader_id;
> >>>>>> -
> >>>>>> -      /* Check whether NTFS is up or not */
> >>>>>> -      if (!ntfa_cb.ntfs_up) {
> >>>>>> -              TRACE("NTFS down");
> >>>>>> -              rc = SA_AIS_ERR_TRY_AGAIN;
> >>>>>> -              goto done_give_hdls;
> >>>>>> +      if (client_hdl_rec->valid) {
> >>>>>> +              /**
> >>>>>> +               ** Populate a sync MDS message
> >>>>>> +               **/
> >>>>>> +              memset(&msg, 0, sizeof(ntfsv_msg_t));
> >>>>>> +              msg.type = NTFSV_NTFA_API_MSG;
> >>>>>> +              msg.info.api_info.type =
> >>>>>> NTFSV_READER_FINALIZE_REQ;
> >>>>>> +              send_param =
> >>>>>> &msg.info.api_info.param.reader_finalize;
> >>>>>> +              send_param->client_id = client_hdl_rec-
> >>>>>>> ntfs_client_id;
> >>>>>> +              send_param->readerId = reader_hdl_rec-
> >>>>>>> reader_id;
> >>>>>> +
> >>>>>> +
> >>>>>> +              /* Send a sync MDS message */
> >>>>>> +              rc = ntfa_mds_msg_sync_send(&ntfa_cb,
> >>>>>> &msg, &o_msg, timeout);
> >>>>>> +              if (rc != NCSCC_RC_SUCCESS) {
> >>>>>> +                      rc = SA_AIS_ERR_TRY_AGAIN;
> >>>>>> +                      goto done_give_hdls;
> >>>>>> +              }
> >>>>>> +
> >>>>>> +              osafassert(o_msg != NULL);
> >>>>>> +              if (SA_AIS_OK != o_msg->info.api_resp_info.rc)
> >>>>>> {
> >>>>>> +                      rc = o_msg-
> >>>>>>> info.api_resp_info.rc;
> >>>>>> +                      TRACE("Bad return status!!! rc =
> >>>>>> %d", rc);
> >>>>>> +                      goto done_give_hdls;
> >>>>>> +              }
> >>>>>> +
> >>>>>> +              if (o_msg->info.api_resp_info.type !=
> >>>>>> NTFSV_READER_FINALIZE_RSP) {
> >>>>>> +                      TRACE("msg type (%d) failed",
> >>>>>> (int)o_msg->info.api_resp_info.type);
> >>>>>> +                      rc = SA_AIS_ERR_LIBRARY;
> >>>>>> +                      goto done_give_hdls;
> >>>>>> +              }
> >>>>>>        }
> >>>>>>
> >>>>>> -      /* Send a sync MDS message */
> >>>>>> -      rc = ntfa_mds_msg_sync_send(&ntfa_cb, &msg, &o_msg,
> >>>>>> timeout);
> >>>>>> -      if (rc != NCSCC_RC_SUCCESS) {
> >>>>>> -              rc = SA_AIS_ERR_TRY_AGAIN;
> >>>>>> -              goto done_give_hdls;
> >>>>>> -      }
> >>>>>> -
> >>>>>> -      osafassert(o_msg != NULL);
> >>>>>> -      if (SA_AIS_OK != o_msg->info.api_resp_info.rc) {
> >>>>>> -              rc = o_msg->info.api_resp_info.rc;
> >>>>>> -              TRACE("Bad return status!!! rc = %d", rc);
> >>>>>> -              goto done_give_hdls;
> >>>>>> -      }
> >>>>>> -
> >>>>>> -      if (o_msg->info.api_resp_info.type !=
> >>>>>> NTFSV_READER_FINALIZE_RSP) {
> >>>>>> -              TRACE("msg type (%d) failed", (int)o_msg-
> >>>>>>> info.api_resp_info.type);
> >>>>>> -              rc = SA_AIS_ERR_LIBRARY;
> >>>>>> -              goto done_give_hdls;
> >>>>>> -      }
> >>>>>>        osafassert(pthread_mutex_lock(&ntfa_cb.cb_lock) == 0);
> >>>>>>        oas_rc = ntfa_reader_hdl_rec_del(&client_hdl_rec-
> >>>>>>> reader_list, reader_hdl_rec);
> >>>>>>        if (oas_rc != NCSCC_RC_SUCCESS) {
> >>>>>> @@ -3029,6 +3432,20 @@ SaAisErrorT saNtfNotificationReadFinaliz
> >>>>>>      done_give_hdls:
> >>>>>>        if (o_msg)
> >>>>>>                 ntfa_msg_destroy(o_msg);
> >>>>>> +
> >>>>>> +      if (!client_hdl_rec->valid && getServerState() ==
> >>>>>> NTFA_NTFSV_UP) {
> >>>>>> +              if ((rc = recoverClient(client_hdl_rec)) !=
> >>>>>> SA_AIS_OK) {
> >>>>>> +                      if (rc ==
> >>>>>> SA_AIS_ERR_BAD_HANDLE) {
> >>>>>> +
> >>>>>>        ncshm_give_hdl(client_hdl_rec->local_hdl);
> >>>>>> +
> >>>>>>        ncshm_give_hdl(readhandle);
> >>>>>> +
> >>>>>>        osafassert(pthread_mutex_lock(&ntfa_cb.cb_lock) == 0);
> >>>>>> +
> >>>>>>        ntfa_hdl_rec_force_del(&ntfa_cb.client_list, client_hdl_rec);
> >>>>>> +
> >>>>>>        osafassert(pthread_mutex_unlock(&ntfa_cb.cb_lock) == 0);
> >>>>>> +
> >>>>>>        ntfa_shutdown(false);
> >>>>>> +                              goto done;
> >>>>>> +                      }
> >>>>>> +              }
> >>>>>> +      }
> >>>>>>        ncshm_give_hdl(client_hdl_rec->local_hdl);
> >>>>>>      done_give_read_hdl:
> >>>>>>        ncshm_give_hdl(readhandle);
> >>>>>> @@ -3082,6 +3499,23 @@ SaAisErrorT saNtfNotificationReadNext(Sa
> >>>>>>        }
> >>>>>>        TRACE_1("reader_hdl_rec = %u", reader_hdl_rec-
> >>>>>>> reader_hdl);
> >>>>>> +      /* Check NTF server availability */
> >>>>>> +      if ((rc = checkNtfServerState()) != SA_AIS_OK)
> >>>>>> +              goto done_give_hdls;
> >>>>>> +
> >>>>>> +      if (!client_hdl_rec->valid) {
> >>>>>> +              if ((rc = recoverClient(client_hdl_rec)) !=
> >>>>>> SA_AIS_OK) {
> >>>>>> +                      ncshm_give_hdl(client_hdl_rec-
> >>>>>>> local_hdl);
> >>>>>> +                      ncshm_give_hdl(readHandle);
> >>>>>> +                      if (rc ==
> >>>>>> SA_AIS_ERR_BAD_HANDLE) {
> >>>>>> +
> >>>>>>        osafassert(pthread_mutex_lock(&ntfa_cb.cb_lock) == 0);
> >>>>>> +
> >>>>>>        ntfa_hdl_rec_force_del(&ntfa_cb.client_list, client_hdl_rec);
> >>>>>> +
> >>>>>>        osafassert(pthread_mutex_unlock(&ntfa_cb.cb_lock) == 0);
> >>>>>> +
> >>>>>>        ntfa_shutdown(false);
> >>>>>> +                      }
> >>>>>> +                      goto done;
> >>>>>> +              }
> >>>>>> +      }
> >>>>>>         /**
> >>>>>>          ** Populate a sync MDS message
> >>>>>>          **/
> >>>>>> @@ -3092,12 +3526,6 @@ SaAisErrorT saNtfNotificationReadNext(Sa
> >>>>>>        send_param->client_id = client_hdl_rec->ntfs_client_id;
> >>>>>>        send_param->readerId = reader_hdl_rec->reader_id;
> >>>>>>        send_param->searchDirection = searchDirection;
> >>>>>> -      /* Check whether NTFS is up or not */
> >>>>>> -      if (!ntfa_cb.ntfs_up) {
> >>>>>> -              TRACE("NTFS down");
> >>>>>> -              rc = SA_AIS_ERR_TRY_AGAIN;
> >>>>>> -              goto done_give_hdls;
> >>>>>> -      }
> >>>>>>
> >>>>>>        do {
> >>>>>>                /* Send a sync MDS message */
> >>>>>> diff --git a/osaf/libs/agents/saf/ntfa/ntfa_mds.c
> >>>>>> b/osaf/libs/agents/saf/ntfa/ntfa_mds.c
> >>>>>> --- a/osaf/libs/agents/saf/ntfa/ntfa_mds.c
> >>>>>> +++ b/osaf/libs/agents/saf/ntfa/ntfa_mds.c
> >>>>>> @@ -369,7 +369,12 @@ static uint32_t ntfa_mds_svc_evt(struct
> >>>>>>                        TRACE("NTFS down");
> >>>>>>
> >>>>>>        pthread_mutex_lock(&ntfa_cb.cb_lock);
> >>>>>>
> >>>>>>        memset(&ntfa_cb.ntfs_mds_dest, 0, sizeof(MDS_DEST));
> >>>>>> -                      ntfa_cb.ntfs_up = 0;
> >>>>>> +
> >>>>>> +                      if (mds_cb_info-
> >>>>>>> info.svc_evt.i_change == NCSMDS_NO_ACTIVE) {
> >>>>>> +
> >>>>>>        ntfa_update_ntfsv_state(NTFA_NTFSV_NO_ACTIVE);
> >>>>>> +                      } else
> >>>>>> +
> >>>>>>        ntfa_update_ntfsv_state(NTFA_NTFSV_DOWN);
> >>>>>> +
> >>>>>>
> >>>>>>        pthread_mutex_unlock(&ntfa_cb.cb_lock);
> >>>>>>                }
> >>>>>>                break;
> >>>>>> @@ -382,7 +387,12 @@ static uint32_t ntfa_mds_svc_evt(struct
> >>>>>>                        TRACE_2("MSG from NTFS
> >>>>>> NCSMDS_NEW_ACTIVE/UP");
> >>>>>>
> >>>>>>        pthread_mutex_lock(&ntfa_cb.cb_lock);
> >>>>>>                        ntfa_cb.ntfs_mds_dest =
> >>>>>> mds_cb_info->info.svc_evt.i_dest;
> >>>>>> -                      ntfa_cb.ntfs_up = 1;
> >>>>>> +
> >>>>>> +                      if (mds_cb_info-
> >>>>>>> info.svc_evt.i_change == NCSMDS_NEW_ACTIVE) {
> >>>>>> +
> >>>>>>        ntfa_update_ntfsv_state(NTFA_NTFSV_NEW_ACTIVE);
> >>>>>> +                      } else
> >>>>>> +
> >>>>>>        ntfa_update_ntfsv_state(NTFA_NTFSV_UP);
> >>>>>> +
> >>>>>>                        if (ntfa_cb.ntfs_sync_awaited) {
> >>>>>>                                /* signal waiting
> >>>>>> thread */
> >>>>>>
> >>>>>>        m_NCS_SEL_OBJ_IND(&ntfa_cb.ntfs_sync_sel);
> >>>>>> diff --git a/osaf/libs/agents/saf/ntfa/ntfa_util.c
> >>>>>> b/osaf/libs/agents/saf/ntfa/ntfa_util.c
> >>>>>> --- a/osaf/libs/agents/saf/ntfa/ntfa_util.c
> >>>>>> +++ b/osaf/libs/agents/saf/ntfa/ntfa_util.c
> >>>>>> @@ -49,7 +49,7 @@ static unsigned int ntfa_create(void)
> >>>>>>        }
> >>>>>>
> >>>>>>        /* Block and wait for indication from MDS meaning NTFS is up
> >>>>>> */
> >>>>>> -
> >>>>>>        osaf_poll_one_fd(m_GET_FD_FROM_SEL_OBJ(ntfa_cb.ntfs_s
> >>>>>> ync_sel), 30000);
> >>>>>> +
> >>>>>>        osaf_poll_one_fd(m_GET_FD_FROM_SEL_OBJ(ntfa_cb.ntfs_s
> >>>>>> ync_sel), 10000);
> >>>>>>
> >>>>>>        pthread_mutex_lock(&ntfa_cb.cb_lock);
> >>>>>>        ntfa_cb.ntfs_sync_awaited = 0;
> >>>>>> @@ -108,7 +108,25 @@ static bool ntfa_clear_mbx(NCSCONTEXT ar
> >>>>>>        }
> >>>>>>        return true;
> >>>>>>     }
> >>>>>>
> >>
> +/*********************************************************
> >>>>>> *******************
> >>>>>> +  Name          : ntfa_notification_list_del
> >>>>>>
> >>>>>> +  Description   : This routine free element allocated in list of
> notification
> >>>>>> +
> >>>>>> +  Arguments     : pointer to the list of notification records anchor.
> >>>>>> +
> >>>>>> +  Return Values : None
> >>>>>> +
> >>>>>> +  Notes         :
> >>>>>>
> >>
> +*********************************************************
> >>>>>> *********************/
> >>>>>> +static void ntfa_notification_list_del(ntfa_notification_hdl_rec_t
> >>>>>> **plstr_hdl)
> >>>>>> +{
> >>>>>> +      ntfa_notification_hdl_rec_t *lstr_hdl = *plstr_hdl;
> >>>>>> +      while (lstr_hdl != NULL) {
> >>>>>> +              ntfa_notification_destructor(lstr_hdl);
> >>>>>> +              lstr_hdl = lstr_hdl->next;
> >>>>>> +      }
> >>>>>> +}
> >>>>>>
> >>>>>>
> >>
> /**********************************************************
> >>>>>> ******************
> >>>>>>       Name          : ntfa_notification_hdl_rec_list_del
> >>>>>>
> >>>>>> @@ -130,6 +148,70 @@ static void ntfa_notification_hdl_rec_li
> >>>>>>                lstr_hdl = NULL;
> >>>>>>        }
> >>>>>>     }
> >>>>>>
> >>
> +/*********************************************************
> >>>>>> *******************
> >>>>>> +  Name          : ntfa_filter_list_del
> >>>>>> +
> >>>>>> +  Description   : This routine free element allocated in list of 
> >>>>>> filter
> >>>>>> +
> >>>>>> +  Arguments     : pointer to the list of filters records anchor.
> >>>>>> +
> >>>>>> +  Return Values : None
> >>>>>> +
> >>>>>> +  Notes         :
> >>>>>>
> >>
> +*********************************************************
> >>>>>> *********************/
> >>>>>> +static void ntfa_filter_list_del(ntfa_filter_hdl_rec_t **plstr_hdl)
> >>>>>> +{
> >>>>>> +      ntfa_filter_hdl_rec_t *lstr_hdl = *plstr_hdl;
> >>>>>> +
> >>>>>> +      while (lstr_hdl != NULL) {
> >>>>>> +              ntfa_filter_destructor(lstr_hdl);
> >>>>>> +              lstr_hdl = lstr_hdl->next;
> >>>>>> +      }
> >>>>>> +}
> >>>>>>
> >>
> +/*********************************************************
> >>>>>> *******************
> >>>>>> +  Name          : ntfa_filter_hdl_rec_list_del
> >>>>>> +
> >>>>>> +  Description   : This routine deletes a list of allocated filters
> >>>>>> +
> >>>>>> +  Arguments     : pointer to the list of filters records anchor.
> >>>>>> +
> >>>>>> +  Return Values : None
> >>>>>> +
> >>>>>> +  Notes         :
> >>>>>>
> >>
> +*********************************************************
> >>>>>> *********************/
> >>>>>> +static void ntfa_filter_hdl_rec_list_del(ntfa_filter_hdl_rec_t
> >>>> **plstr_hdl)
> >>>>>> +{
> >>>>>> +      ntfa_filter_hdl_rec_t *lstr_hdl;
> >>>>>> +
> >>>>>> +      while ((lstr_hdl = *plstr_hdl) != NULL) {
> >>>>>> +              *plstr_hdl = lstr_hdl->next;
> >>>>>> +              ncshm_destroy_hdl(NCS_SERVICE_ID_NTFA,
> >>>>>> lstr_hdl->filter_hdl);
> >>>>>> +              free(lstr_hdl);
> >>>>>> +              lstr_hdl = NULL;
> >>>>>> +      }
> >>>>>> +}
> >>>>>>
> >>
> +/*********************************************************
> >>>>>> *******************
> >>>>>> +  Name          : ntfa_reader_hdl_rec_list_del
> >>>>>> +
> >>>>>> +  Description   : This routine deletes a list of allocated readers
> >>>>>> +
> >>>>>> +  Arguments     : pointer to the list of readers records anchor.
> >>>>>> +
> >>>>>> +  Return Values : None
> >>>>>> +
> >>>>>> +  Notes         :
> >>>>>>
> >>
> +*********************************************************
> >>>>>> *********************/
> >>>>>> +static void ntfa_reader_hdl_rec_list_del(ntfa_reader_hdl_rec_t
> >>>>>> **plstr_hdl)
> >>>>>> +{
> >>>>>> +      ntfa_reader_hdl_rec_t *lstr_hdl;
> >>>>>> +      while ((lstr_hdl = *plstr_hdl) != NULL) {
> >>>>>> +              *plstr_hdl = lstr_hdl->next;
> >>>>>> +              ncshm_destroy_hdl(NCS_SERVICE_ID_NTFA,
> >>>>>> lstr_hdl->reader_hdl);
> >>>>>> +              ntfa_del_ntf_filter_ptrs(&lstr_hdl->filters);
> >>>>>> +              free(lstr_hdl);
> >>>>>> +              lstr_hdl = NULL;
> >>>>>> +      }
> >>>>>> +}
> >>>>>>
> >>>>>>     static SaAisErrorT
> ntfa_alloc_callback_notification(SaNtfNotificationsT
> >>>>>> *notification,
> >>>>>>
> >>>>>>            ntfsv_send_not_req_t *not_cbk, ntfa_client_hdl_rec_t
> >>>>>> *hdl_rec)
> >>>>>> @@ -407,6 +489,10 @@ static SaAisErrorT ntfa_hdl_cbk_rec_prc(
> >>>>>>                        free(cbk_info-
> >>>>>>> param.discarded_cbk.discardedNotificationIdentifiers);
> >>>>>>                }
> >>>>>>                break;
> >>>>>> +      case NTFSV_DUMMY_CALLBACK:
> >>>>>> +              TRACE("Do nothing with dummy callback, just
> >>>>>> return OK");
> >>>>>> +              rc = SA_AIS_OK;
> >>>>>> +              break;
> >>>>>>        default:
> >>>>>>                TRACE("unsupported callback type: %d",
> >>>>>> cbk_info->type);
> >>>>>>                rc = SA_AIS_ERR_LIBRARY;
> >>>>>> @@ -544,20 +630,21 @@ unsigned int ntfa_startup(void)
> >>>>>>      *
> >>>>>>      * @return unsigned int
> >>>>>>      */
> >>>>>> -unsigned int ntfa_shutdown(void)
> >>>>>> +unsigned int ntfa_shutdown(bool forced)
> >>>>>>     {
> >>>>>>        unsigned int rc = NCSCC_RC_SUCCESS;
> >>>>>>
> >>>>>> -      TRACE_ENTER2("ntfa_use_count: %u", ntfa_use_count);
> >>>>>> +      TRACE_ENTER2("ntfa_use_count: %u, forced: %u",
> >>>>>> ntfa_use_count, forced);
> >>>>>>        pthread_mutex_lock(&ntfa_lock);
> >>>>>>
> >>>>>> -      if (ntfa_use_count > 1) {
> >>>>>> -              /* Users still exist, just decrement the use count
> >>>>>> */
> >>>>>> -              ntfa_use_count--;
> >>>>>> -      } else if (ntfa_use_count == 1) {
> >>>>>> +      if ((forced && (ntfa_use_count > 0)) || (ntfa_use_count == 1))
> >>>>>> {
> >>>>>>                ntfa_destroy();
> >>>>>>                rc = ncs_agents_shutdown();
> >>>>>>                ntfa_use_count = 0;
> >>>>>> +              ntfa_cb.ntfa_ntfsv_state =
> >>>>>> NTFA_NTFSV_NONE;
> >>>>>> +      } else if (ntfa_use_count > 1) {
> >>>>>> +              /* Users still exist, just decrement the use count
> >>>>>> */
> >>>>>> +              ntfa_use_count--;
> >>>>>>        }
> >>>>>>
> >>>>>>        pthread_mutex_unlock(&ntfa_lock);
> >>>>>> @@ -633,7 +720,27 @@ ntfa_client_hdl_rec_t *ntfa_find_hdl_rec
> >>>>>>
> >>>>>>        return NULL;
> >>>>>>     }
> >>>>>>
> >>
> +/*********************************************************
> >>>>>> *******************
> >>>>>> +  Name          : ntfa_subscriber_list_del
> >>>>>>
> >>>>>> +  Description   : This routine deletes a list of allocated subscribers
> >>>>>> +
> >>>>>> +  Arguments     : pointer to the list of subscribers records anchor.
> >>>>>> +
> >>>>>> +  Return Values : None
> >>>>>> +
> >>>>>> +  Notes         :
> >>>>>>
> >>
> +*********************************************************
> >>>>>> *********************/
> >>>>>> +void ntfa_subscriber_list_del()
> >>>>>> +{
> >>>>>> +      ntfa_subscriber_list_t *listPtr = subscriberNoList;
> >>>>>> +      while (listPtr != NULL) {
> >>>>>> +              ntfa_subscriber_list_t* tmpSub = listPtr;
> >>>>>> +              listPtr = listPtr->next;
> >>>>>> +              free(tmpSub);
> >>>>>> +      }
> >>>>>> +      subscriberNoList = NULL;
> >>>>>> +}
> >>>>>>
> >>>>>>
> >>
> /**********************************************************
> >>>>>> ******************
> >>>>>>       Name          : ntfa_hdl_list_del
> >>>>>>
> >>>>>> @@ -651,15 +758,24 @@ void ntfa_hdl_list_del(ntfa_client_hdl_r
> >>>>>>
> >>>>>>        while ((client_hdl = *p_client_hdl) != NULL) {
> >>>>>>                *p_client_hdl = client_hdl->next;
> >>>>>> +              m_NCS_IPC_DETACH(&client_hdl->mbx,
> >>>>>> ntfa_clear_mbx, NULL);
> >>>>>> +              m_NCS_IPC_RELEASE(&client_hdl->mbx, NULL);
> >>>>>>                ncshm_destroy_hdl(NCS_SERVICE_ID_NTFA,
> >>>>>> client_hdl->local_hdl);
> >>>>>>        /** clean up the channel records for this ntfa-client
> >>>>>>              **/
> >>>>>> +              ntfa_notification_list_del(&client_hdl-
> >>>>>>> notification_list);
> >>>>>>                ntfa_notification_hdl_rec_list_del(&client_hdl-
> >>>>>>> notification_list);
> >>>>>> +
> >>>>>> +              ntfa_filter_list_del(&client_hdl->filter_list);
> >>>>>> +              ntfa_filter_hdl_rec_list_del(&client_hdl-
> >>>>>>> filter_list);
> >>>>>> +
> >>>>>> +              ntfa_reader_hdl_rec_list_del(&client_hdl-
> >>>>>>> reader_list);
> >>>>>>        /** remove the association with hdl-mngr
> >>>>>>              **/
> >>>>>>                free(client_hdl);
> >>>>>>                client_hdl = 0;
> >>>>>>        }
> >>>>>> +      ntfa_subscriber_list_del();
> >>>>>>     }
> >>>>>>
> >>>>>>
> >>>>>>
> >>
> /**********************************************************
> >>>>>> ******************
> >>>>>> @@ -757,10 +873,80 @@ uint32_t ntfa_filter_hdl_rec_del(ntfa_fi
> >>>>>>        TRACE("The node couldn't be deleted");
> >>>>>>        return NCSCC_RC_FAILURE;
> >>>>>>     }
> >>>>>>
> >>
> +/*********************************************************
> >>>>>> *******************
> >>>>>> +  Name          : ntfa_hdl_rec_force_del
> >>>>>>
> >>>>>> +  Description   : This routine deletes all memory allocated to client.
> >>>>>> +
> >>>>>> +  Arguments     : NTFA_CLIENT_HDL_REC **list_head
> >>>>>> +                NTFA_CLIENT_HDL_REC *rm_node
> >>>>>> +
> >>>>>> +  Return Values : None
> >>>>>> +
> >>>>>> +  Notes         :
> >>>>>>
> >>
> +*********************************************************
> >>>>>> *********************/
> >>>>>> +void ntfa_hdl_rec_force_del(ntfa_client_hdl_rec_t **list_head,
> >>>>>> ntfa_client_hdl_rec_t *rm_node)
> >>>>>> +{
> >>>>>> +      ntfa_client_hdl_rec_t *list_iter = *list_head;
> >>>>>> +      TRACE_ENTER();
> >>>>>> +      /* First remove the rm_node out of the list of client */
> >>>>>> +      if (list_iter == rm_node)
> >>>>>> +              *list_head = rm_node->next;
> >>>>>> +      else {
> >>>>>> +              while (list_iter) {
> >>>>>> +                      if (list_iter->next == rm_node) {
> >>>>>> +                              list_iter->next =
> >>>>>> rm_node->next;
> >>>>>> +                              break;
> >>>>>> +                      }
> >>>>>> +                      list_iter = list_iter->next;
> >>>>>> +              }
> >>>>>> +      }
> >>>>>> +      /* Release all msgs in mailbox */
> >>>>>> +      ntfsv_msg_t *cbk_msg;
> >>>>>> +      while((cbk_msg =
> >>>>>> (ntfsv_msg_t*)m_NCS_IPC_NON_BLK_RECEIVE(&rm_node->mbx,
> >>>>>> cbk_msg))
> >>>>>> +              != NULL) {
> >>>>>> +              ntfa_msg_destroy(cbk_msg);
> >>>>>> +      }
> >>>>>> +      /* delete subscriber of this client out of the subcriberNoList*/
> >>>>>> +      ntfa_subscriber_list_t* subscriber_hdl = subscriberNoList;
> >>>>>> +      while (subscriber_hdl != NULL) {
> >>>>>> +              ntfa_subscriber_list_t *rm_subscriber =
> >>>>>> subscriber_hdl;
> >>>>>> +              subscriber_hdl = subscriber_hdl->next;
> >>>>>> +              if (rm_node->local_hdl == rm_subscriber-
> >>>>>>> subscriberListNtfHandle) {
> >>>>>> +                      if (rm_subscriber->next != NULL) {
> >>>>>> +                              rm_subscriber-
> >>>>>>> next->prev = rm_subscriber->prev;
> >>>>>> +                      }
> >>>>>> +
> >>>>>> +                      if (rm_subscriber->prev != NULL) {
> >>>>>> +                              rm_subscriber-
> >>>>>>> prev->next = rm_subscriber->next;
> >>>>>> +                      } else {
> >>>>>> +                              if (rm_subscriber-
> >>>>>>> next != NULL)
> >>>>>> +
> >>>>>>        subscriberNoList = rm_subscriber->next;
> >>>>>> +                              else
> >>>>>> +
> >>>>>>        subscriberNoList = NULL;
> >>>>>> +                      }
> >>>>>> +
> >>>>>>        ntfa_del_ntf_filter_ptrs(&rm_subscriber->filters);
> >>>>>> +                      free(rm_subscriber);
> >>>>>> +              }
> >>>>>> +      }
> >>>>>> +      /* Now delete client */
> >>>>>> +      m_NCS_IPC_DETACH(&rm_node->mbx, ntfa_clear_mbx,
> >>>>>> NULL);
> >>>>>> +      m_NCS_IPC_RELEASE(&rm_node->mbx, NULL);
> >>>>>> +      ncshm_destroy_hdl(NCS_SERVICE_ID_NTFA, rm_node-
> >>>>>>> local_hdl);
> >>>>>> +      ntfa_notification_list_del(&rm_node->notification_list);
> >>>>>> +      ntfa_notification_hdl_rec_list_del(&rm_node-
> >>>>>>> notification_list);
> >>>>>> +
> >>>>>> +      ntfa_filter_list_del(&rm_node->filter_list);
> >>>>>> +      ntfa_filter_hdl_rec_list_del(&rm_node->filter_list);
> >>>>>> +
> >>>>>> +      ntfa_reader_hdl_rec_list_del(&rm_node->reader_list);
> >>>>>> +      free(rm_node);
> >>>>>> +
> >>>>>> +      TRACE_LEAVE();
> >>>>>> +}
> >>>>>>
> >>>>>>
> >>
> /**********************************************************
> >>>>>> ******************
> >>>>>>       Name          : ntfa_hdl_rec_del
> >>>>>> -
> >>>>>> +
> >>>>>>       Description   : This routine deletes the a client handle record 
> >>>>>> from
> >>>>>>                       a list of client hdl records.
> >>>>>>
> >>>>>> @@ -962,7 +1148,7 @@ ntfa_client_hdl_rec_t *ntfa_hdl_rec_add(
> >>>>>>         /** Associate with the client_id obtained from NTFS
> >>>>>>          **/
> >>>>>>        rec->ntfs_client_id = client_id;
> >>>>>> -
> >>>>>> +      rec->valid = true;
> >>>>>>         /** Initialize and attach the IPC/Priority queue
> >>>>>>          **/
> >>>>>>
> >>>>>> @@ -1063,7 +1249,7 @@ static void logtrace_init_constructor(vo
> >>>>>>      *
> >>>>>>      * @param instance
> >>>>>>      */
> >>>>>> -void ntfa_hdl_rec_destructor(ntfa_notification_hdl_rec_t
> *instance)
> >>>>>> +void ntfa_notification_destructor(ntfa_notification_hdl_rec_t
> >>>> *instance)
> >>>>>>     {
> >>>>>>        ntfa_notification_hdl_rec_t *notificationInstance = instance;
> >>>>>>
> >>>>>> @@ -1111,7 +1297,7 @@ void ntfa_hdl_rec_destructor(ntfa_notifi
> >>>>>>      *
> >>>>>>      * @param instance
> >>>>>>      */
> >>>>>> -void ntfa_filter_hdl_rec_destructor(ntfa_filter_hdl_rec_t
> *filter_rec)
> >>>>>> +void ntfa_filter_destructor(ntfa_filter_hdl_rec_t *filter_rec)
> >>>>>>     {
> >>>>>>        switch (filter_rec->ntfType) {
> >>>>>>        case SA_NTF_TYPE_OBJECT_CREATE_DELETE:
> >>>>>> @@ -1202,6 +1388,7 @@ uint32_t ntfa_reader_hdl_rec_del(ntfa_re
> >>>>>>              **/
> >>>>>>                ncshm_give_hdl(rm_node->reader_hdl);
> >>>>>>                ncshm_destroy_hdl(NCS_SERVICE_ID_NTFA,
> >>>>>> rm_node->reader_hdl);
> >>>>>> +              ntfa_del_ntf_filter_ptrs(&rm_node->filters);
> >>>>>>                free(rm_node);
> >>>>>>                return NCSCC_RC_SUCCESS;
> >>>>>>        } else {                /* find the rec */
> >>>>>> @@ -1213,6 +1400,7 @@ uint32_t ntfa_reader_hdl_rec_del(ntfa_re
> >>>>>>                      **/
> >>>>>>
> >>>>>>        ncshm_give_hdl(rm_node->reader_hdl);
> >>>>>>
> >>>>>>        ncshm_destroy_hdl(NCS_SERVICE_ID_NTFA, rm_node-
> >>>>>>> reader_hdl);
> >>>>>> +
> >>>>>>        ntfa_del_ntf_filter_ptrs(&rm_node->filters);
> >>>>>>                                free(rm_node);
> >>>>>>                                return
> >>>>>> NCSCC_RC_SUCCESS;
> >>>>>>                        }
> >>>>>> @@ -1258,3 +1446,258 @@ void
> ntfa_add_to_async_cbk_msg_list(ntfs
> >>>>>>
> >>>>>>        TRACE_LEAVE();
> >>>>>>     }
> >>>>>> +
> >>>>>>
> >>
> +/*********************************************************
> >>>>>> *******************
> >>>>>> +  Name          : ntfa_notify_handle_invalid
> >>>>>> +
> >>>>>> +  Description   : This routine sends a dummy callback msg to client's
> >>>> mailbox
> >>>>>> +                so that the client polls in and calls
> >>>>>> saNtfDispatch.
> >>>>>> +  Arguments     :
> >>>>>> +
> >>>>>> +  Return Values : None
> >>>>>> +
> >>>>>> +  Notes         : None
> >>>>>>
> >>
> +*********************************************************
> >>>>>> *********************/
> >>>>>> +void ntfa_notify_handle_invalid() {
> >>>>>> +      ntfa_client_hdl_rec_t *client_hdl = ntfa_cb.client_list;
> >>>>>> +      TRACE_ENTER();
> >>>>>> +      while (client_hdl != NULL) {
> >>>>>> +              /* Only applicable for subscriber */
> >>>>>> +              if (client_hdl->reg_cbk.saNtfNotificationCallback
> >>>>>> != NULL ||
> >>>>>> +                      client_hdl-
> >>>>>>> reg_cbk.saNtfNotificationDiscardedCallback != NULL) {
> >>>>>> +                      /* Create a dummy msg */
> >>>>>> +                      ntfsv_msg_t *msg =
> >>>>>> malloc(sizeof(ntfsv_msg_t));
> >>>>>> +                      memset(msg, 0,
> >>>>>> sizeof(ntfsv_msg_t));
> >>>>>> +                      msg->info.cbk_info.type =
> >>>>>> NTFSV_DUMMY_CALLBACK;
> >>>>>> +                      /* Send dummy msg to client
> >>>>>> mailbox */
> >>>>>> +                      if
> >>>>>> (m_NCS_IPC_SEND(&client_hdl->mbx, msg,
> >>>> MDS_SEND_PRIORITY_HIGH) !=
> >>>>>> NCSCC_RC_SUCCESS) {
> >>>>>> +
> >>>>>>        TRACE_1("m_NCS_IPC_SEND Failed to client(id:%u)",
> >>>>>> client_hdl->ntfs_client_id);
> >>>>>> +
> >>>>>>        ntfa_msg_destroy(msg);
> >>>>>> +                      }
> >>>>>> +              }
> >>>>>> +
> >>>>>> +              client_hdl = client_hdl->next;
> >>>>>> +      }
> >>>>>> +      TRACE_LEAVE();
> >>>>>> +}
> >>>>>>
> >>
> +/*********************************************************
> >>>>>> *******************
> >>>>>> +  Name          : ntfa_update_ntfsv_state
> >>>>>> +
> >>>>>> +  Description   : Update current NTF Server state by the
> >> @changedState
> >>>>>> indicated
> >>>>>> +                by MDS event
> >>>>>> +  Arguments     : @changedState [IN]: state to be changed of NTF
> >> Server
> >>>>>> +
> >>>>>> +  Return Values : None
> >>>>>> +
> >>>>>> +  Notes         : None
> >>>>>>
> >>
> +*********************************************************
> >>>>>> *********************/
> >>>>>> +void ntfa_update_ntfsv_state(ntfa_ntfsv_state_t changedState)
> >>>>>> +{
> >>>>>> +      TRACE_ENTER();
> >>>>>> +      TRACE_1("Current state: %u, Changed state: %u",
> >>>>>> ntfa_cb.ntfa_ntfsv_state,
> >>>>>> +
> >>>>>>
> >>>>>>                changedState);
> >>>>>> +
> >>>>>> +      ntfa_client_hdl_rec_t *client_hdl = ntfa_cb.client_list;
> >>>>>> +
> >>>>>> +      switch (ntfa_cb.ntfa_ntfsv_state){
> >>>>>> +      case NTFA_NTFSV_NONE:
> >>>>>> +              ntfa_cb.ntfa_ntfsv_state = changedState;
> >>>>>> +              break;
> >>>>>> +      case NTFA_NTFSV_DOWN:
> >>>>>> +              if (changedState == NTFA_NTFSV_NEW_ACTIVE
> >>>>>> ||
> >>>>>> +                      changedState ==
> >>>>>> NTFA_NTFSV_UP) {
> >>>>>> +                      TRACE("Active NTF server has
> >>>>>> been restarted");
> >>>>>> +                      ntfa_cb.ntfa_ntfsv_state =
> >>>>>> NTFA_NTFSV_UP;
> >>>>>> +                      ntfa_notify_handle_invalid();
> >>>>>> +              } else
> >>>>>> +                      TRACE("Unexpected state
> >>>>>> changes");
> >>>>>> +              break;
> >>>>>> +      case NTFA_NTFSV_NO_ACTIVE:
> >>>>>> +              if (changedState ==
> >>>>>> NTFA_NTFSV_NEW_ACTIVE) {
> >>>>>> +                      TRACE("Standby NTF server
> >>>>>> becomes new Active");
> >>>>>> +                      /* NTF server is functioning
> >>>>>> normally */
> >>>>>> +                      ntfa_cb.ntfa_ntfsv_state =
> >>>>>> NTFA_NTFSV_UP;
> >>>>>> +              } else if (changedState == NTFA_NTFSV_DOWN)
> >>>>>> {
> >>>>>> +                      TRACE("Active NTF Server is
> >>>>>> Down");
> >>>>>> +                      ntfa_cb.ntfa_ntfsv_state =
> >>>>>> NTFA_NTFSV_DOWN;
> >>>>>> +                      /* Mark all client handles are
> >>>>>> invalid */
> >>>>>> +                      while (client_hdl != NULL) {
> >>>>>> +                              client_hdl->valid =
> >>>>>> false;
> >>>>>> +                              client_hdl =
> >>>>>> client_hdl->next;
> >>>>>> +                      }
> >>>>>> +              }
> >>>>>> +              break;
> >>>>>> +      case NTFA_NTFSV_NEW_ACTIVE:
> >>>>>> +              TRACE("Unknown");
> >>>>>> +              break;
> >>>>>> +      case NTFA_NTFSV_UP:
> >>>>>> +              if (changedState == NTFA_NTFSV_NO_ACTIVE) {
> >>>>>> +                      TRACE("Active NTF server
> >>>>>> temporarily unavailable");
> >>>>>> +                      /* Failover/Switchover is
> >>>>>> happening
> >>>>>> +                       * Any API calls result in
> >>>>>> TRY_AGAIN
> >>>>>> +                       */
> >>>>>> +                      ntfa_cb.ntfa_ntfsv_state =
> >>>>>> NTFA_NTFSV_NO_ACTIVE;
> >>>>>> +              } else
> >>>>>> +                      TRACE("Unexpected state
> >>>>>> changes");
> >>>>>> +              break;
> >>>>>> +      default:
> >>>>>> +              osafassert(false);
> >>>>>> +      }
> >>>>>> +
> >>>>>> +      TRACE_LEAVE();
> >>>>>> +}
> >>>>>>
> >>
> +/*********************************************************
> >>>>>> *******************
> >>>>>> +  Name          : ntfa_copy_ntf_filter_ptrs
> >>>>>> +
> >>>>>> +  Description   : Copy a list of filter from pSrc to pDes
> >>>>>> +
> >>>>>> +  Arguments     : pDes* [OUT]: list of outcome filter
> >>>>>> +                pSrc* [IN]: list of input filter
> >>>>>> +
> >>>>>> +  Return Values : SA_AIS_OK if succeed, other values as failed
> >>>>>> +
> >>>>>> +  Notes         : None
> >>>>>>
> >>
> +*********************************************************
> >>>>>> *********************/
> >>>>>> +SaAisErrorT ntfa_copy_ntf_filter_ptrs(ntfsv_filter_ptrs_t* pDes,
> >>>>>> +
> >>>>>>                        const ntfsv_filter_ptrs_t* pSrc) {
> >>>>>> +      SaAisErrorT rc = SA_AIS_OK;
> >>>>>> +      SaNtfNotificationFilterHeaderT *des_header;
> >>>>>> +      SaNtfNotificationFilterHeaderT *src_header;
> >>>>>> +      TRACE_ENTER();
> >>>>>> +
> >>>>>> +      if (pSrc->alarm_filter) {
> >>>>>> +              pDes->alarm_filter = calloc(1,
> >>>>>> sizeof(SaNtfAlarmNotificationFilterT));
> >>>>>> +              des_header = &(pDes->alarm_filter-
> >>>>>>> notificationFilterHeader);
> >>>>>> +              src_header = &(pSrc->alarm_filter-
> >>>>>>> notificationFilterHeader);
> >>>>>> +              if ((rc = ntfsv_filter_header_alloc(des_header,
> >>>>>> src_header->numEventTypes,
> >>>>>> +
> >>>>>>
> >>>>>>        src_header->numNotificationObjects,
> >>>>>> +
> >>>>>>
> >>>>>>        src_header->numNotifyingObjects,
> >>>>>> +
> >>>>>>
> >>>>>>        src_header->numNotificationClassIds)) != SA_AIS_OK)
> >>>>>> +                      goto done;
> >>>>>> +              if ((rc = ntfsv_filter_alarm_alloc(pDes-
> >>>>>>> alarm_filter,
> >>>>>> +
> >>>>>>
> >>>>>>        pSrc->alarm_filter->numProbableCauses,
> >>>>>> +
> >>>>>>
> >>>>>>        pSrc->alarm_filter->numPerceivedSeverities,
> >>>>>> +
> >>>>>>
> >>>>>>        pSrc->alarm_filter->numTrends)) != SA_AIS_OK)
> >>>>>> +                      goto done;
> >>>>>> +              if ((rc = ntfsv_copy_ntf_filter_alarm(pDes-
> >>>>>>> alarm_filter,
> >>>>>> +
> >>>>>>
> >>>>>>                pSrc->alarm_filter)) != SA_AIS_OK)
> >>>>>> +                      goto done;
> >>>>>> +      }
> >>>>>> +
> >>>>>> +      if (pSrc->sec_al_filter) {
> >>>>>> +              pDes->sec_al_filter = calloc(1,
> >>>>>> sizeof(SaNtfSecurityAlarmNotificationFilterT));
> >>>>>> +              des_header = &(pDes->sec_al_filter-
> >>>>>>> notificationFilterHeader);
> >>>>>> +              src_header = &(pSrc->sec_al_filter-
> >>>>>>> notificationFilterHeader);
> >>>>>> +              if ((rc = ntfsv_filter_header_alloc(des_header,
> >>>>>> src_header->numEventTypes,
> >>>>>> +
> >>>>>>
> >>>>>>        src_header->numNotificationObjects,
> >>>>>> +
> >>>>>>
> >>>>>>        src_header->numNotifyingObjects,
> >>>>>> +
> >>>>>>
> >>>>>>        src_header->numNotificationClassIds)) != SA_AIS_OK)
> >>>>>> +                      goto done;
> >>>>>> +              if ((rc = ntfsv_filter_sec_alarm_alloc(pDes-
> >>>>>>> sec_al_filter,
> >>>>>> +
> >>>>>>
> >>>>>>        pSrc->sec_al_filter->numProbableCauses,
> >>>>>> +
> >>>>>>
> >>>>>>        pSrc->sec_al_filter->numSeverities,
> >>>>>> +
> >>>>>>
> >>>>>>        pSrc->sec_al_filter->numSecurityAlarmDetectors,
> >>>>>> +
> >>>>>>
> >>>>>>        pSrc->sec_al_filter->numServiceUsers,
> >>>>>> +
> >>>>>>
> >>>>>>        pSrc->sec_al_filter->numServiceProviders)) != SA_AIS_OK)
> >>>>>> +                      goto done;
> >>>>>> +              if ((rc = ntfsv_copy_ntf_filter_sec_alarm(pDes-
> >>>>>>> sec_al_filter,
> >>>>>> +
> >>>>>>
> >>>>>>                pSrc->sec_al_filter)) != SA_AIS_OK)
> >>>>>> +                      goto done;
> >>>>>> +      }
> >>>>>> +
> >>>>>> +      if (pSrc->sta_ch_filter) {
> >>>>>> +              pDes->sta_ch_filter = calloc(1,
> >>>>>> sizeof(SaNtfStateChangeNotificationFilterT));
> >>>>>> +              des_header = &(pDes->sta_ch_filter-
> >>>>>>> notificationFilterHeader);
> >>>>>> +              src_header = &(pSrc->sta_ch_filter-
> >>>>>>> notificationFilterHeader);
> >>>>>> +              if ((rc = ntfsv_filter_header_alloc(des_header,
> >>>>>> src_header->numEventTypes,
> >>>>>> +
> >>>>>>
> >>>>>>        src_header->numNotificationObjects,
> >>>>>> +
> >>>>>>
> >>>>>>        src_header->numNotifyingObjects,
> >>>>>> +
> >>>>>>
> >>>>>>        src_header->numNotificationClassIds)) != SA_AIS_OK)
> >>>>>> +                      goto done;
> >>>>>> +              if ((rc = ntfsv_filter_state_ch_alloc(pDes-
> >>>>>>> sta_ch_filter,
> >>>>>> +
> >>>>>>
> >>>>>>        pSrc->sta_ch_filter->numSourceIndicators,
> >>>>>> +
> >>>>>>
> >>>>>>        pSrc->sta_ch_filter->numStateChanges)) != SA_AIS_OK)
> >>>>>> +                      goto done;
> >>>>>> +              if ((rc = ntfsv_copy_ntf_filter_state_ch(pDes-
> >>>>>>> sta_ch_filter,
> >>>>>> +
> >>>>>>
> >>>>>>                pSrc->sta_ch_filter)) != SA_AIS_OK)
> >>>>>> +                      goto done;
> >>>>>> +      }
> >>>>>> +
> >>>>>> +      if (pSrc->obj_cr_del_filter) {
> >>>>>> +              pDes->obj_cr_del_filter = calloc(1,
> >>>>>> sizeof(SaNtfObjectCreateDeleteNotificationFilterT));
> >>>>>> +              des_header = &(pDes->obj_cr_del_filter-
> >>>>>>> notificationFilterHeader);
> >>>>>> +              src_header = &(pSrc->obj_cr_del_filter-
> >>>>>>> notificationFilterHeader);
> >>>>>> +              if ((rc = ntfsv_filter_header_alloc(des_header,
> >>>>>> src_header->numEventTypes,
> >>>>>> +
> >>>>>>
> >>>>>>        src_header->numNotificationObjects,
> >>>>>> +
> >>>>>>
> >>>>>>        src_header->numNotifyingObjects,
> >>>>>> +
> >>>>>>
> >>>>>>        src_header->numNotificationClassIds)) != SA_AIS_OK)
> >>>>>> +                      goto done;
> >>>>>> +              if ((rc = ntfsv_filter_obj_cr_del_alloc(pDes-
> >>>>>>> obj_cr_del_filter,
> >>>>>> +
> >>>>>>
> >>>>>>        pSrc->obj_cr_del_filter->numSourceIndicators)) !=
> >>>>>> SA_AIS_OK)
> >>>>>> +                      goto done;
> >>>>>> +              if ((rc = ntfsv_copy_ntf_filter_obj_cr_del(pDes-
> >>>>>>> obj_cr_del_filter,
> >>>>>> +
> >>>>>>
> >>>>>>                pSrc->obj_cr_del_filter)) != SA_AIS_OK)
> >>>>>> +                      goto done;
> >>>>>> +      }
> >>>>>> +
> >>>>>> +      if (pSrc->att_ch_filter) {
> >>>>>> +              pDes->att_ch_filter = calloc(1,
> >>>>>> sizeof(SaNtfAttributeChangeNotificationFilterT));
> >>>>>> +              des_header = &(pDes->att_ch_filter-
> >>>>>>> notificationFilterHeader);
> >>>>>> +              src_header = &(pSrc->att_ch_filter-
> >>>>>>> notificationFilterHeader);
> >>>>>> +              if ((rc = ntfsv_filter_header_alloc(des_header,
> >>>>>> src_header->numEventTypes,
> >>>>>> +
> >>>>>>
> >>>>>>        src_header->numNotificationObjects,
> >>>>>> +
> >>>>>>
> >>>>>>        src_header->numNotifyingObjects,
> >>>>>> +
> >>>>>>
> >>>>>>        src_header->numNotificationClassIds)) != SA_AIS_OK)
> >>>>>> +                      goto done;
> >>>>>> +              if ((rc = ntfsv_filter_attr_change_alloc(pDes-
> >>>>>>> att_ch_filter,
> >>>>>> +
> >>>>>>
> >>>>>>        pSrc->att_ch_filter->numSourceIndicators)) != SA_AIS_OK)
> >>>>>> +                      goto done;
> >>>>>> +              if ((rc = ntfsv_copy_ntf_filter_attr_ch(pDes-
> >>>>>>> att_ch_filter,
> >>>>>> +
> >>>>>>
> >>>>>>                pSrc->att_ch_filter)) != SA_AIS_OK)
> >>>>>> +                      goto done;
> >>>>>> +      }
> >>>>>> +done:
> >>>>>> +      TRACE_LEAVE();
> >>>>>> +      return rc;
> >>>>>> +}
> >>>>>> +
> >>>>>>
> >>
> +/*********************************************************
> >>>>>> *******************
> >>>>>> +  Name          : ntfa_del_ntf_filter_ptrs
> >>>>>> +
> >>>>>> +  Description   : Delete the filter pointers
> >>>>>> +
> >>>>>> +  Arguments     : filter_ptrs* [IN/OUT]: filter pointers
> >>>>>> +
> >>>>>> +  Return Values : SA_AIS_OK if succeed, other values as failed
> >>>>>> +
> >>>>>> +  Notes         : None
> >>>>>>
> >>
> +*********************************************************
> >>>>>> *********************/
> >>>>>> +SaAisErrorT ntfa_del_ntf_filter_ptrs(ntfsv_filter_ptrs_t*
> filter_ptrs)
> >>>>>> +{
> >>>>>> +      SaAisErrorT rc = SA_AIS_OK;
> >>>>>> +      if (filter_ptrs->alarm_filter) {
> >>>>>> +              ntfsv_filter_alarm_free(filter_ptrs-
> >>>>>>> alarm_filter, true);
> >>>>>> +              free(filter_ptrs->alarm_filter);
> >>>>>> +      }
> >>>>>> +
> >>>>>> +      if (filter_ptrs->sec_al_filter) {
> >>>>>> +              ntfsv_filter_sec_alarm_free(filter_ptrs-
> >>>>>>> sec_al_filter, true);
> >>>>>> +              free(filter_ptrs->sec_al_filter);
> >>>>>> +      }
> >>>>>> +
> >>>>>> +      if (filter_ptrs->sta_ch_filter) {
> >>>>>> +              ntfsv_filter_state_ch_free(filter_ptrs-
> >>>>>>> sta_ch_filter, true);
> >>>>>> +              free(filter_ptrs->sta_ch_filter);
> >>>>>> +      }
> >>>>>> +
> >>>>>> +      if (filter_ptrs->obj_cr_del_filter) {
> >>>>>> +              ntfsv_filter_obj_cr_del_free(filter_ptrs-
> >>>>>>> obj_cr_del_filter, true);
> >>>>>> +              free(filter_ptrs->obj_cr_del_filter);
> >>>>>> +      }
> >>>>>> +
> >>>>>> +      if (filter_ptrs->att_ch_filter) {
> >>>>>> +              ntfsv_filter_attr_ch_free(filter_ptrs-
> >>>>>>> att_ch_filter, true);
> >>>>>> +              free(filter_ptrs->att_ch_filter);
> >>>>>> +      }
> >>>>>> +      return rc;
> >>>>>> +}
> >


------------------------------------------------------------------------------
Transform Data into Opportunity.
Accelerate data analysis in your applications with
Intel Data Analytics Acceleration Library.
Click to learn more.
http://pubads.g.doubleclick.net/gampad/clk?id=278785231&iu=/4140
_______________________________________________
Opensaf-devel mailing list
Opensaf-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/opensaf-devel

Reply via email to