When there are no more log client in log agent, unregister mds and shutdown log agent. --- src/log/agent/lga_agent.cc | 33 +++++++++++++++++++++----- src/log/agent/lga_agent.h | 3 +++ src/log/agent/lga_mds.cc | 28 +++++++++++++++++++++++ src/log/agent/lga_mds.h | 1 + src/log/agent/lga_state.cc | 2 +- src/log/agent/lga_state.h | 1 + src/log/agent/lga_util.cc | 47 ++++++++++++++++++++++++++++++++++++++ src/log/agent/lga_util.h | 1 + 8 files changed, 109 insertions(+), 7 deletions(-)
diff --git a/src/log/agent/lga_agent.cc b/src/log/agent/lga_agent.cc index b61d82a03..393993f05 100644 --- a/src/log/agent/lga_agent.cc +++ b/src/log/agent/lga_agent.cc @@ -625,6 +625,11 @@ SaAisErrorT LogAgent::saLogDispatch(SaLogHandleT logHandle, return ais_rc; } +size_t LogAgent::CountClient() { + ScopeLock scopeLock(mutex_); + return client_list_.size(); +} + SaAisErrorT LogAgent::SendFinalizeMsg(uint32_t client_id) { uint32_t mds_rc; lgsv_msg_t msg, *o_msg = nullptr; @@ -671,6 +676,7 @@ SaAisErrorT LogAgent::saLogFinalize(SaLogHandleT logHandle) { bool updated = false; bool is_locked = false; SaAisErrorT ais_rc = SA_AIS_OK; + int rc; TRACE_ENTER(); @@ -689,20 +695,20 @@ SaAisErrorT LogAgent::saLogFinalize(SaLogHandleT logHandle) { if (client == nullptr) { TRACE("No log client with such handle"); ais_rc = SA_AIS_ERR_BAD_HANDLE; - return ais_rc; + goto done; } if (client->FetchAndDecreaseRefCounter(__func__, &updated) != 0) { // DO NOT delete this @client as it is being used by somewhere (>0) // Or it is being deleted by other thread (=-1) ais_rc = SA_AIS_ERR_TRY_AGAIN; - return ais_rc; + goto done; } } // end critical section if (client->HaveLogStreamInUse() == true) { ais_rc = SA_AIS_ERR_TRY_AGAIN; - return ais_rc; + goto done; } // No LOG server. No service is provided. @@ -710,7 +716,7 @@ SaAisErrorT LogAgent::saLogFinalize(SaLogHandleT logHandle) { // We have a server but it is temporary unavailable. Client may try again TRACE("%s lgs_state = LGS no active", __func__); ais_rc = SA_AIS_ERR_TRY_AGAIN; - return ais_rc; + goto done; } // Avoid the recovery thread block operation on done-recovery client @@ -722,7 +728,7 @@ SaAisErrorT LogAgent::saLogFinalize(SaLogHandleT logHandle) { // The client may try again TRACE("%s lga_state = LGA auto recovery ongoing (2)", __func__); ais_rc = SA_AIS_ERR_TRY_AGAIN; - return ais_rc; + goto done; } if (is_lga_recovery_state(RecoveryState::kRecovery1)) { @@ -734,7 +740,7 @@ SaAisErrorT LogAgent::saLogFinalize(SaLogHandleT logHandle) { TRACE("\t Client is not initialized. Remove it from database"); ScopeLock critical_section(get_delete_obj_sync_mutex_); RemoveLogClient(&client); - return ais_rc; + goto done; } TRACE("\t Client is initialized"); } @@ -751,6 +757,21 @@ SaAisErrorT LogAgent::saLogFinalize(SaLogHandleT logHandle) { } } +done: + if (CountClient() == 0) { + // Stop recovery thread if it's running + stop_recovery2_thread(); + // Shutdown the agent + rc = lga_shutdown(); + if (rc != NCSCC_RC_SUCCESS) { + TRACE("lga_shutdown FAILED"); + ais_rc = SA_AIS_ERR_LIBRARY; + } + m_NCS_SEL_OBJ_RMV_IND(&init_clm_status_sel_, true, false); + m_NCS_SEL_OBJ_RMV_IND(&log_server_up_sel_, true, false); + atomic_data_.waiting_log_server_up = true; + } + TRACE_LEAVE2("ais_rc = %s", saf_error(ais_rc)); return ais_rc; } diff --git a/src/log/agent/lga_agent.h b/src/log/agent/lga_agent.h index 957adc716..55632684a 100644 --- a/src/log/agent/lga_agent.h +++ b/src/log/agent/lga_agent.h @@ -198,6 +198,9 @@ class LogAgent { // True if there is no LOG server at all (headless) bool is_no_log_server() const; + // Count number of clients in agent + size_t CountClient(); + // Form finalize Msg and send to MDS SaAisErrorT SendFinalizeMsg(uint32_t client_id); diff --git a/src/log/agent/lga_mds.cc b/src/log/agent/lga_mds.cc index 838eca5e1..2836ce2ed 100644 --- a/src/log/agent/lga_mds.cc +++ b/src/log/agent/lga_mds.cc @@ -1329,6 +1329,34 @@ uint32_t lga_mds_init() { return rc; } +/**************************************************************************** + Name : lga_mds_deinit + + Description : This routine unregisters the LGA Service in MDS. + + Return Values : NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE + + Notes : None. +******************************************************************************/ +uint32_t lga_mds_deinit() { + NCSMDS_INFO mds_info; + uint32_t rc = NCSCC_RC_SUCCESS; + std::atomic<MDS_HDL> &mds_hdl = LogAgent::instance()->atomic_get_mds_hdl(); + TRACE_ENTER(); + + memset(&mds_info, 0, sizeof(NCSMDS_INFO)); + mds_info.i_mds_hdl = mds_hdl.load(); + mds_info.i_svc_id = NCSMDS_SVC_ID_LGA; + mds_info.i_op = MDS_UNINSTALL; + if ((rc = ncsmds_api(&mds_info)) != NCSCC_RC_SUCCESS) { + TRACE("mds api call failed"); + return NCSCC_RC_FAILURE; + } + + TRACE_LEAVE(); + return rc; +} + /**************************************************************************** Name : lga_mds_msg_sync_send diff --git a/src/log/agent/lga_mds.h b/src/log/agent/lga_mds.h index 2fbe906e3..af5608849 100644 --- a/src/log/agent/lga_mds.h +++ b/src/log/agent/lga_mds.h @@ -25,6 +25,7 @@ struct lga_cb_t; struct lgsv_msg_t; uint32_t lga_mds_init(); +uint32_t lga_mds_deinit(); void lga_msg_destroy(lgsv_msg_t *msg); uint32_t lga_mds_msg_sync_send(lgsv_msg_t *i_msg, lgsv_msg_t **o_msg, diff --git a/src/log/agent/lga_state.cc b/src/log/agent/lga_state.cc index 970fe27d2..cdf692749 100644 --- a/src/log/agent/lga_state.cc +++ b/src/log/agent/lga_state.cc @@ -153,7 +153,7 @@ done: * Stops the recovery 2 thread * It is safe to call this function also if the thread is not running */ -static void stop_recovery2_thread(void) { +void stop_recovery2_thread(void) { uint32_t ncs_rc = 0; int rc = 0; diff --git a/src/log/agent/lga_state.h b/src/log/agent/lga_state.h index 32f49da40..5bfbd976d 100644 --- a/src/log/agent/lga_state.h +++ b/src/log/agent/lga_state.h @@ -37,6 +37,7 @@ void lga_recovery2_lock(); void lga_recovery2_unlock(); bool is_lga_recovery_state(RecoveryState state); +void stop_recovery2_thread(); void recovery2_lock(bool *is_locked); void recovery2_unlock(bool *is_locked); diff --git a/src/log/agent/lga_util.cc b/src/log/agent/lga_util.cc index d64496839..2a3347a76 100644 --- a/src/log/agent/lga_util.cc +++ b/src/log/agent/lga_util.cc @@ -54,12 +54,32 @@ static unsigned int lga_create() { TRACE("WaitLogServerUp FAILED"); // Delete the lga init instances LogAgent::instance()->RemoveAllLogClients(); + // Unregister MDS + lga_mds_deinit(); return rc; } return rc; } +/** + * Delete log agent + * + * @return unsigned int + */ +static unsigned int lga_delete() { + unsigned int rc = NCSCC_RC_SUCCESS; + + // Unregister in MDS + rc = lga_mds_deinit(); + if (rc != NCSCC_RC_SUCCESS) { + TRACE("lga_mds_deinit FAILED"); + rc = NCSCC_RC_FAILURE; + } + + return rc; +} + /** * Initiate the agent when first used. * Start NCS service @@ -92,6 +112,33 @@ done: return rc; } +/** + * Shutdown the agent when not in use + * Stop NCS service and unregister MDS + * + * @return unsigned int + */ +unsigned int lga_shutdown() { + unsigned int rc = NCSCC_RC_SUCCESS; + ScopeLock lock(init_lock); + std::atomic<MDS_HDL>& mds_hdl = LogAgent::instance()->atomic_get_mds_hdl(); + TRACE_ENTER(); + + if (mds_hdl) { + rc = lga_delete(); + if (rc != NCSCC_RC_SUCCESS) { + TRACE("lga_delete FAILED"); + goto done; + } + ncs_agents_shutdown(); + mds_hdl = 0; + } + +done: + TRACE_LEAVE2("rc: %u", rc); + return rc; +} + /** * Increase user counter * The function help to trace number of clients diff --git a/src/log/agent/lga_util.h b/src/log/agent/lga_util.h index 81175dd22..179c6ae9d 100644 --- a/src/log/agent/lga_util.h +++ b/src/log/agent/lga_util.h @@ -23,6 +23,7 @@ #include <saLog.h> unsigned int lga_startup(); +unsigned int lga_shutdown(); void lga_increase_user_counter(void); void lga_decrease_user_counter(void); -- 2.17.1 _______________________________________________ Opensaf-devel mailing list Opensaf-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/opensaf-devel