Hi Canh I have answered your comments. See attached patch. I have also done some reviewing myself and found some issues. I will submit a new review where all comments are handled including from Vu and myself
Thanks Lennart > -----Original Message----- > From: Canh Van Truong [mailto:canh.v.tru...@dektech.com.au] > Sent: den 29 mars 2018 13:47 > To: Lennart Lund <lennart.l...@ericsson.com>; Vu Minh Nguyen > <vu.m.ngu...@dektech.com.au> > Cc: opensaf-devel@lists.sourceforge.net > Subject: RE: [PATCH 1/1] log: Handling of IMM OI BAD HANDLE in log server is > incorrect [#2799] > > Hi Lennart, > > Please see my comments in the attached diff file. > > Thanks > Canh > > -----Original Message----- > From: Lennart Lund [mailto:lennart.l...@ericsson.com] > Sent: Wednesday, March 28, 2018 9:34 PM > To: vu.m.ngu...@dektech.com.au; canh.v.tru...@dektech.com.au > Cc: opensaf-devel@lists.sourceforge.net; Lennart Lund > <lennart.l...@ericsson.com> > Subject: [PATCH 1/1] log: Handling of IMM OI BAD HANDLE in log server is > incorrect [#2799] > > Recovery of OI handle shall be started in all places where BAD HANDLE > can be returned. Creation of OI must be done in background thread. > Ongoing creation must be possible to stop e.g if server is becoming > standby > --- > src/log/Makefile.am | 3 + > src/log/logd/lgs.h | 24 --- > src/log/logd/lgs_amf.cc | 26 ++- > src/log/logd/lgs_cb.h | 3 - > src/log/logd/lgs_config.cc | 22 ++- > src/log/logd/lgs_config.h | 5 +- > src/log/logd/lgs_evt.cc | 60 +++--- > src/log/logd/lgs_imm.cc | 312 +++-------------------------- > src/log/logd/lgs_imm.h | 53 +++++ > src/log/logd/lgs_main.cc | 116 ++++------- > src/log/logd/lgs_mbcsv_v2.cc | 7 +- > src/log/logd/lgs_mbcsv_v3.cc | 7 +- > src/log/logd/lgs_mbcsv_v5.cc | 3 +- > src/log/logd/lgs_oi_admin.cc | 461 > +++++++++++++++++++++++++++++++++++++++++++ > src/log/logd/lgs_oi_admin.h | 105 ++++++++++ > src/log/logd/lgs_recov.cc | 4 +- > src/log/logd/lgs_stream.cc | 85 ++++++-- > 17 files changed, 837 insertions(+), 459 deletions(-) > create mode 100644 src/log/logd/lgs_imm.h > create mode 100644 src/log/logd/lgs_oi_admin.cc > create mode 100644 src/log/logd/lgs_oi_admin.h > > diff --git a/src/log/Makefile.am b/src/log/Makefile.am > index 3d951eb5d..5d33d355b 100644 > --- a/src/log/Makefile.am > +++ b/src/log/Makefile.am > @@ -79,6 +79,7 @@ noinst_HEADERS += \ > src/log/logd/lgs_file.h \ > src/log/logd/lgs_filehdl.h \ > src/log/logd/lgs_fmt.h \ > + src/log/logd/lgs_imm.h \ > src/log/logd/lgs_imm_gcfg.h \ > src/log/logd/lgs_mbcsv.h \ > src/log/logd/lgs_mbcsv_v1.h \ > @@ -86,6 +87,7 @@ noinst_HEADERS += \ > src/log/logd/lgs_mbcsv_v3.h \ > src/log/logd/lgs_mbcsv_v5.h \ > src/log/logd/lgs_mbcsv_v6.h \ > + src/log/logd/lgs_oi_admin.h \ > src/log/logd/lgs_recov.h \ > src/log/logd/lgs_stream.h \ > src/log/logd/lgs_util.h \ > @@ -139,6 +141,7 @@ bin_osaflogd_SOURCES = \ > src/log/logd/lgs_mbcsv_v5.cc \ > src/log/logd/lgs_mbcsv_v6.cc \ > src/log/logd/lgs_mds.cc \ > + src/log/logd/lgs_oi_admin.cc \ > src/log/logd/lgs_recov.cc \ > src/log/logd/lgs_stream.cc \ > src/log/logd/lgs_util.cc \ > diff --git a/src/log/logd/lgs.h b/src/log/logd/lgs.h > index 18e6d9281..b1d773375 100644 > --- a/src/log/logd/lgs.h > +++ b/src/log/logd/lgs.h > @@ -95,7 +95,6 @@ extern uint32_t mbox_msgs[NCS_IPC_PRIORITY_MAX]; > extern bool mbox_full[NCS_IPC_PRIORITY_MAX]; > extern uint32_t mbox_low[NCS_IPC_PRIORITY_MAX]; > extern pthread_mutex_t lgs_mbox_init_mutex; > -extern pthread_mutex_t lgs_OI_init_mutex; > > extern uint32_t initialize_for_assignment(lgs_cb_t *cb, SaAmfHAStateT > ha_state); > > @@ -108,27 +107,4 @@ extern uint32_t lgs_mds_msg_send(lgs_cb_t *cb, > lgsv_msg_t *msg, MDS_DEST *dest, > MDS_SYNC_SND_CTXT *mds_ctxt, > MDS_SEND_PRIORITY_TYPE prio); > > -extern SaAisErrorT lgs_imm_create_configStream(lgs_cb_t *cb); > -extern void logRootDirectory_filemove(const std::string > &new_logRootDirectory, > - const std::string > &old_logRootDirectory, > - time_t *cur_time_in); > -extern void logDataGroupname_fileown(const char > *new_logDataGroupname); > - > -extern void lgs_imm_impl_reinit_nonblocking(lgs_cb_t *cb); > -extern void lgs_imm_init_OI_handle(SaImmOiHandleT *immOiHandle, > - SaSelectionObjectT *immSelectionObject); > -extern void lgs_imm_impl_set(SaImmOiHandleT *immOiHandle, > - SaSelectionObjectT *immSelectionObject); > -extern SaAisErrorT lgs_imm_init_configStreams(lgs_cb_t *cb); > - > -// Functions for recovery handling > -void lgs_cleanup_abandoned_streams(); > -void lgs_delete_one_stream_object(const std::string &name_str); > -void lgs_search_stream_objects(); > -SaUint32T *lgs_get_scAbsenceAllowed_attr(SaUint32T *attr_val); > -int lgs_get_streamobj_attr(SaImmAttrValuesT_2 ***attrib_out, > - const std::string &object_name, > - SaImmHandleT *immOmHandle); > -int lgs_free_streamobj_attr(SaImmHandleT immHandle); > - > #endif // LOG_LOGD_LGS_H_ > diff --git a/src/log/logd/lgs_amf.cc b/src/log/logd/lgs_amf.cc > index 6fa044ff2..3f0de8c1c 100644 > --- a/src/log/logd/lgs_amf.cc > +++ b/src/log/logd/lgs_amf.cc > @@ -23,6 +23,7 @@ > #include "osaf/immutil/immutil.h" > #include "log/logd/lgs.h" > #include "log/logd/lgs_config.h" > +#include "log/logd/lgs_oi_admin.h" > > static void close_all_files() { > log_stream_t *stream; > @@ -63,8 +64,7 @@ static SaAisErrorT amf_active_state_handler(lgs_cb_t > *cb, > goto done; > } > > - lgs_imm_impl_set(&cb->immOiHandle, &cb->immSelectionObject); > - conf_runtime_obj_create(cb->immOiHandle); > + lgsOiStart(); > lgs_start_gcfg_applier(); > > // Iterate all existing log streams in cluster. > @@ -127,12 +127,8 @@ static SaAisErrorT > amf_quiescing_state_handler(lgs_cb_t > *cb, > TRACE_ENTER2("HA QUIESCING request"); > close_all_files(); > > - /* Give up our IMM OI implementer role */ > - SaAisErrorT ais_rc = immutil_saImmOiImplementerClear(cb- > >immOiHandle); > - if (ais_rc != SA_AIS_OK) { > - LOG_WA("immutil_saImmOiImplementerClear failed: %s", > saf_error(ais_rc)); > - } > - > + // Give up our IMM OI implementer role and the OpensafConfig class > applier > + lgsOiStop(); > lgs_stop_gcfg_applier(); > > return saAmfCSIQuiescingComplete(cb->amf_hdl, invocation, SA_AIS_OK); > @@ -158,11 +154,7 @@ static SaAisErrorT > amf_quiesced_state_handler(lgs_cb_t > *cb, > close_all_files(); > > /* Give up our IMM OI implementer role */ > - SaAisErrorT rc = immutil_saImmOiImplementerClear(cb->immOiHandle); > - if (rc != SA_AIS_OK) { > - LOG_WA("immutil_saImmOiImplementerClear failed: %s", saf_error(rc)); > - } > - > + lgsOiStop(); > lgs_stop_gcfg_applier(); > > /* > @@ -171,11 +163,13 @@ static SaAisErrorT > amf_quiesced_state_handler(lgs_cb_t > *cb, > ** cb->ha_state now. > */ > > + > mds_role = cb->mds_role; > cb->mds_role = V_DEST_RL_QUIESCED; > + SaAisErrorT ais_rc = SA_AIS_OK; > if (lgs_mds_change_role(cb) != NCSCC_RC_SUCCESS) { > LOG_ER("lgs_mds_change_role FAILED"); > - rc = SA_AIS_ERR_FAILED_OPERATION; > + ais_rc = SA_AIS_ERR_FAILED_OPERATION; > cb->mds_role = mds_role; > goto done; > } > @@ -183,8 +177,9 @@ static SaAisErrorT > amf_quiesced_state_handler(lgs_cb_t > *cb, > cb->amf_invocation_id = invocation; > cb->is_quiesced_set = true; > done: > - return rc; > + return ais_rc; > } > + > > /********************************************************** > ***************** > * > * Name : amf_health_chk_callback > * > @@ -207,6 +202,7 @@ static void amf_health_chk_callback(SaInvocationT > invocation, > SaAmfHealthcheckKeyT *checkType) { > saAmfResponse(lgs_cb->amf_hdl, invocation, SA_AIS_OK); > } > + > > /********************************************************** > ***************** > * > * Name : amf_csi_set_callback > * > diff --git a/src/log/logd/lgs_cb.h b/src/log/logd/lgs_cb.h > index f2602c2d8..1b1a67d9c 100644 > --- a/src/log/logd/lgs_cb.h > +++ b/src/log/logd/lgs_cb.h > @@ -81,9 +81,6 @@ typedef struct lgs_cb { > SaInvocationT > amf_invocation_id; /* AMF InvocationID - needed to handle Quiesed > state */ > bool is_quiesced_set; > - SaImmOiHandleT immOiHandle; /* IMM OI handle */ > - SaSelectionObjectT > - immSelectionObject; /* Selection Object to wait for IMM events */ > SaSelectionObjectT > clmSelectionObject; /* Selection Object to wait for clms events */ > SaClmHandleT clm_hdl; /* CLM handle, obtained through CLM init > */ > diff --git a/src/log/logd/lgs_config.cc b/src/log/logd/lgs_config.cc > index 4190e3048..7be92a6fa 100644 > --- a/src/log/logd/lgs_config.cc > +++ b/src/log/logd/lgs_config.cc > @@ -41,6 +41,7 @@ > #include "log/logd/lgs_file.h" > #include "log/logd/lgs.h" > #include "log/logd/lgs_common.h" > +#include "log/logd/lgs_oi_admin.h" > > > /* Mutex for making read and write of configuration data thread safe */ > @@ -1338,8 +1339,8 @@ static void read_log_config_environ_var_2() { > * Public functions for handling configuration information > > ********************************************************** > ****************** > **/ > > -void lgs_cfg_init(SaImmOiHandleT immOiHandle, SaAmfHAStateT ha_state) > { > - TRACE_ENTER2("immOiHandle = %lld", immOiHandle); > +void lgs_cfg_init() { > + TRACE_ENTER(); > > /* Read configuration step 1 > * Read all values from the log service configuration object > @@ -1585,6 +1586,10 @@ void conf_runtime_obj_create(SaImmOiHandleT > immOiHandle) { > > if (rc == SA_AIS_ERR_EXIST) { > TRACE("Server runtime configuration object already exist"); > + } else if (rc == SA_AIS_ERR_BAD_HANDLE) { > + LOG_NO("%s: saImmOiRtObjectCreate_2 BAD_HANDLE, start re-create", > + __FUNCTION__); > + lgsOiCreateBackground(); > } else if (rc != SA_AIS_OK) { > LOG_NO("%s: Cannot create config runtime object %s", __FUNCTION__, > saf_error(rc)); > @@ -1667,6 +1672,14 @@ static SaAisErrorT update_runtime_attrValues( > attrMod.modAttr.attrValueType = attrValueType; > attrMod.modAttr.attrValues = values_array; > ais_rc = immutil_saImmOiRtObjectUpdate_2(immOiHandle, &objectName, > attrMods); > + if (ais_rc == SA_AIS_ERR_BAD_HANDLE) { > + LOG_NO("%s: saImmOiRtObjectUpdate_2() Fail, %s", __FUNCTION__, > + saf_error(ais_rc)); > + lgsOiCreateBackground(); > + } else if (ais_rc != SA_AIS_OK) { > + LOG_NO("%s: saImmOiRtObjectUpdate_2() Fail, %s", __FUNCTION__, > + saf_error(ais_rc)); > + } > free(values_array); > TRACE_LEAVE(); > return ais_rc; > @@ -1692,8 +1705,7 @@ static SaAisErrorT > update_lgs_cfg_runtime_multivalue( > immOiHandle, LGS_CFG_RUNTIME_OBJECT, attributeName, valueType, > attrValuesNumber, attrValues); > if (ais_rc != SA_AIS_OK) { > - LOG_NO("%s: update_runtime_attrValues Fail %s", __FUNCTION__, > - saf_error(ais_rc)); > + LOG_NO("%s: update_runtime_attrValues Fail", __FUNCTION__); > } > > // Free the memory allocated by vector_of_strings_to_attrValues() > @@ -1712,7 +1724,7 @@ static SaAisErrorT > update_lgs_cfg_runtime_multivalue( > * @param immOiHandle[in] > * @param attributeNames[in] > */ > -void conf_runtime_obj_hdl(SaImmOiHandleT immOiHandle, > +void conf_runtime_obj_handler(SaImmOiHandleT immOiHandle, > const SaImmAttrNameT *attributeNames) { > SaImmAttrNameT attributeName; > int i = 0; > diff --git a/src/log/logd/lgs_config.h b/src/log/logd/lgs_config.h > index 6885271a4..3f1b05e51 100644 > --- a/src/log/logd/lgs_config.h > +++ b/src/log/logd/lgs_config.h > @@ -135,7 +135,7 @@ typedef struct config_chkpt { > * Read the log service configuration data verify and update configuration > * data structure > */ > -void lgs_cfg_init(SaImmOiHandleT immOiHandle, SaAmfHAStateT ha_state); > +void lgs_cfg_init(); > > /** > * Get value of log service configuration parameter from the configuration > data > @@ -316,8 +316,9 @@ void lgs_groupnameconf_set(const char > *data_groupname_str); > * Handle runtime object for showing actual configuration and configuration > * related information > */ > + > void conf_runtime_obj_create(SaImmOiHandleT immOiHandle); > -void conf_runtime_obj_hdl(SaImmOiHandleT immOiHandle, > +void conf_runtime_obj_handler(SaImmOiHandleT immOiHandle, > const SaImmAttrNameT *attributeNames); > > /* > diff --git a/src/log/logd/lgs_evt.cc b/src/log/logd/lgs_evt.cc > index 4b735875d..d0c3161a4 100644 > --- a/src/log/logd/lgs_evt.cc > +++ b/src/log/logd/lgs_evt.cc > @@ -31,6 +31,7 @@ > #include "log/logd/lgs_imm_gcfg.h" > #include "log/logd/lgs_clm.h" > #include "log/logd/lgs_dest.h" > +#include "log/logd/lgs_oi_admin.h" > > void *client_db = nullptr; /* used for C++ STL map */ > > @@ -569,7 +570,7 @@ static uint32_t proc_rda_cb_msg(lgsv_lgs_evt_t *evt) > { > } > > /* fail over, become implementer */ > - lgs_imm_impl_set(&lgs_cb->immOiHandle, &lgs_cb- > >immSelectionObject); > + lgsOiCreateBackground(); > lgs_start_gcfg_applier(); > > /* Agent down list has to be processed first */ > @@ -613,7 +614,6 @@ uint32_t lgs_cb_init(lgs_cb_t *lgs_cb) { > > lgs_cb->fully_initialized = false; > lgs_cb->amfSelectionObject = -1; > - lgs_cb->immSelectionObject = -1; > lgs_cb->mbcsv_sel_obj = -1; > lgs_cb->clm_hdl = 0; > lgs_cb->clmSelectionObject = -1; > @@ -835,7 +835,7 @@ snd_rsp: > */ > SaAisErrorT create_new_app_stream(lgsv_stream_open_req_t > *open_sync_param, > log_stream_t **o_stream) { > - SaAisErrorT rc = SA_AIS_OK; > + SaAisErrorT ais_rc = SA_AIS_OK; > log_stream_t *stream; > SaBoolT twelveHourModeFlag; > SaUint32T logMaxLogrecsize_conf = 0; > @@ -848,13 +848,13 @@ SaAisErrorT > create_new_app_stream(lgsv_stream_open_req_t *open_sync_param, > > if (lgs_is_extended_name_valid(&open_sync_param->lstr_name) == false) > { > TRACE("SaNameT is invalid"); > - rc = SA_AIS_ERR_INVALID_PARAM; > + ais_rc = SA_AIS_ERR_INVALID_PARAM; > goto done; > } > > if (open_sync_param->logFileFullAction != > SA_LOG_FILE_FULL_ACTION_ROTATE) > { > TRACE("Unsupported logFileFullAction"); > - rc = SA_AIS_ERR_NOT_SUPPORTED; > + ais_rc = SA_AIS_ERR_NOT_SUPPORTED; > goto done; > } > > @@ -864,7 +864,7 @@ SaAisErrorT > create_new_app_stream(lgsv_stream_open_req_t > *open_sync_param, > ((open_sync_param->maxFilesRotated < 1) || > (open_sync_param->maxFilesRotated > 127))) { > TRACE("Invalid maxFilesRotated. Valid Range = [1-127]"); > - rc = SA_AIS_ERR_INVALID_PARAM; > + ais_rc = SA_AIS_ERR_INVALID_PARAM; > goto done; > } > > @@ -880,21 +880,21 @@ SaAisErrorT > create_new_app_stream(lgsv_stream_open_req_t *open_sync_param, > STREAM_TYPE_APPLICATION_RT, > &twelveHourModeFlag)) { > TRACE("format expression failure"); > - rc = SA_AIS_ERR_INVALID_PARAM; > + ais_rc = SA_AIS_ERR_INVALID_PARAM; > goto done; > } > > /* Verify if there is any special character in logFileName */ > if (lgs_has_special_char(open_sync_param->logFileName) == true) { > TRACE("Invalid logFileName - %s", open_sync_param->logFileName); > - rc = SA_AIS_ERR_INVALID_PARAM; > + ais_rc = SA_AIS_ERR_INVALID_PARAM; > goto done; > } > > /* Verify if logFileName length is valid */ > if (lgs_is_valid_filelength(open_sync_param->logFileName) == false) { > TRACE("logFileName is invalid"); > - rc = SA_AIS_ERR_INVALID_PARAM; > + ais_rc = SA_AIS_ERR_INVALID_PARAM; > goto done; > } > > @@ -902,7 +902,7 @@ SaAisErrorT > create_new_app_stream(lgsv_stream_open_req_t > *open_sync_param, > if (lgs_is_valid_pathlength(open_sync_param->logFilePathName, > open_sync_param->logFileName) == false) { > TRACE("logFilePathName is invalid"); > - rc = SA_AIS_ERR_INVALID_PARAM; > + ais_rc = SA_AIS_ERR_INVALID_PARAM; > goto done; > } > > @@ -913,7 +913,7 @@ SaAisErrorT > create_new_app_stream(lgsv_stream_open_req_t > *open_sync_param, > if ((stream->fileName == open_sync_param->logFileName) && > (stream->pathName == open_sync_param->logFilePathName)) { > TRACE("pathname already exist"); > - rc = SA_AIS_ERR_INVALID_PARAM; > + ais_rc = SA_AIS_ERR_INVALID_PARAM; > goto done; > } > } > @@ -922,7 +922,7 @@ SaAisErrorT > create_new_app_stream(lgsv_stream_open_req_t > *open_sync_param, > str_name = osaf_extended_name_borrow(&open_sync_param- > >lstr_name); > if (strncmp(dnPrefix, str_name, strlen(dnPrefix)) != 0) { > TRACE("'%s' is not a valid stream name => invalid param", str_name); > - rc = SA_AIS_ERR_INVALID_PARAM; > + ais_rc = SA_AIS_ERR_INVALID_PARAM; > goto done; > } > > @@ -933,13 +933,13 @@ SaAisErrorT > create_new_app_stream(lgsv_stream_open_req_t *open_sync_param, > ((open_sync_param->maxLogRecordSize < SA_LOG_MIN_RECORD_SIZE) > || > (open_sync_param->maxLogRecordSize > logMaxLogrecsize_conf))) { > TRACE("maxLogRecordSize is invalid"); > - rc = SA_AIS_ERR_INVALID_PARAM; > + ais_rc = SA_AIS_ERR_INVALID_PARAM; > goto done; > } > > *o_stream = log_stream_new(str_name, STREAM_NEW); > if (*o_stream == nullptr) { > - rc = SA_AIS_ERR_NO_MEMORY; > + ais_rc = SA_AIS_ERR_NO_MEMORY; > goto done; > } > > @@ -951,16 +951,23 @@ SaAisErrorT > create_new_app_stream(lgsv_stream_open_req_t *open_sync_param, > twelveHourModeFlag, 0, *o_stream); // output > if (err == -1) { > log_stream_delete(o_stream); > - rc = SA_AIS_ERR_NO_MEMORY; > + ais_rc = SA_AIS_ERR_NO_MEMORY; > goto done; > } > > - rc = lgs_create_appstream_rt_object(*o_stream); > - if (rc != SA_AIS_OK) log_stream_delete(o_stream); > + ais_rc = lgs_create_appstream_rt_object(*o_stream); > + if (ais_rc != SA_AIS_OK) log_stream_delete(o_stream); > + > + TRACE("%s: lgs_create_appstream_rt_object return, %s", > + __FUNCTION__, saf_error(ais_rc)); > + > + if (ais_rc == SA_AIS_ERR_BAD_HANDLE) { > + lgsOiCreateBackground(); > + } > > done: > TRACE_LEAVE(); > - return rc; > + return ais_rc; > } > > /** > @@ -1069,15 +1076,7 @@ static uint32_t proc_stream_open_msg(lgs_cb_t > *cb, > lgsv_lgs_evt_t *evt) { > } > } > } else { > - /* Stream does not exist */ > - > - // This check is to avoid the client getting SA_AIS_BAD_OPERATION > - // as there is no IMM OI implementer set. > - if (cb->immOiHandle == 0) { > - TRACE("IMM service unavailable, open stream failed"); > - ais_rv = SA_AIS_ERR_TRY_AGAIN; > - goto snd_rsp; > - } > + /* Stream does not exist. Create a new stream */ > > /* > * Check if the stream is in the list of stream objects > @@ -1125,6 +1124,11 @@ static uint32_t proc_stream_open_msg(lgs_cb_t > *cb, > lgsv_lgs_evt_t *evt) { > if (ais_rv != SA_AIS_OK) { > TRACE("%s create_new_app_stream Fail \"%s\"", __FUNCTION__, > saf_error(ais_rv)); > + if (ais_rv == SA_AIS_ERR_BAD_HANDLE) { > + // This means that the stream RT object could not be created > because > + // of a bad OI handle. Change to TRY AGAIN in the reply to the > agent > + ais_rv = SA_AIS_ERR_TRY_AGAIN; > + } > goto snd_rsp; > } > } > @@ -1218,7 +1222,7 @@ static uint32_t proc_stream_close_msg(lgs_cb_t > *cb, > lgsv_lgs_evt_t *evt) { > // This check is to avoid the client getting SA_AIS_BAD_OPERATION > // as there is no IMM OI implementer set. > if ((stream->streamType == STREAM_TYPE_APPLICATION_RT) && > - (cb->immOiHandle == 0)) { > + (lgsGetOiHandle() == 0)) { > TRACE("IMM service unavailable, close stream failed"); > ais_rc = SA_AIS_ERR_TRY_AGAIN; > goto snd_rsp; > diff --git a/src/log/logd/lgs_imm.cc b/src/log/logd/lgs_imm.cc > index 60870fa17..d23862172 100644 > --- a/src/log/logd/lgs_imm.cc > +++ b/src/log/logd/lgs_imm.cc > @@ -31,6 +31,8 @@ > #define _GNU_SOURCE > #endif > > +#include "log/logd/lgs_imm.h" > + > #include <stdio.h> > #include <errno.h> > #include <string.h> > @@ -46,6 +48,7 @@ > #include "log/logd/lgs_recov.h" > #include "log/logd/lgs_config.h" > #include "log/logd/lgs_dest.h" > +#include "log/logd/lgs_oi_admin.h" > #include "base/saf_error.h" > > #include "lgs_mbcsv_v1.h" > @@ -58,11 +61,6 @@ > * ---------------- > */ > > -/* Used for protecting global imm OI handle and selection object during > - * initialize of OI > - */ > -pthread_mutex_t lgs_OI_init_mutex = PTHREAD_MUTEX_INITIALIZER; > - > /* Used for checkpointing time when files are closed */ > static time_t chkp_file_close_time = 0; > > @@ -75,13 +73,6 @@ static const char *log_file_format[] = { > DEFAULT_ALM_NOT_FORMAT_EXP, DEFAULT_ALM_NOT_FORMAT_EXP, > DEFAULT_APP_SYS_FORMAT_EXP, DEFAULT_APP_SYS_FORMAT_EXP}; > > -static const SaImmOiImplementerNameT implementerName = > - const_cast<SaImmOiImplementerNameT>("safLogService"); > -static const SaImmClassNameT logConfig_str = > - const_cast<SaImmClassNameT>("OpenSafLogConfig"); > -static const SaImmClassNameT streamConfig_str = > - const_cast<SaImmClassNameT>("SaLogStreamConfig"); > - > // The list contains path-file names when validating its name in CCB > completed > // callback. This help for log service prevents that creating any streams > // in same CCB with duplicated log path-file name > @@ -2375,7 +2366,7 @@ static SaAisErrorT stream_create_and_configure1( > > /* Update creation timestamp */ > rc = immutil_update_one_rattr( > - lgs_cb->immOiHandle, objectName.c_str(), > + lgsGetOiHandle(), objectName.c_str(), > const_cast<SaImmAttrNameT>("saLogStreamCreationTimestamp"), > SA_IMM_ATTR_SATIMET, &(*stream)->creationTimeStamp); > if (rc != SA_AIS_OK) { > @@ -2702,7 +2693,7 @@ static SaAisErrorT > rtAttrUpdateCallback(SaImmOiHandleT > immOiHandle, > /* Handle configuration runtime object */ > if (strncmp(objName, LGS_CFG_RUNTIME_OBJECT, strlen(objName)) == 0) > { > /* Handle Runtome configuration object */ > - conf_runtime_obj_hdl(immOiHandle, attributeNames); > + conf_runtime_obj_handler(immOiHandle, attributeNames); > } else { > /* Handle stream object if valid > */ > @@ -2889,11 +2880,15 @@ static const SaImmOiCallbacksT_2 callbacks = { > .saImmOiCcbObjectModifyCallback = ccbObjectModifyCallback, > .saImmOiRtAttrUpdateCallback = rtAttrUpdateCallback}; > > +// Export the callback structure. OI init is done in lgs_oi_admin > +const SaImmOiCallbacksT_2* getImmOiCallbacks(void) { > + return &callbacks; > +} > + > /** > * Retrieve the LOG stream configuration from IMM using the > * IMM-OM interface and initialize the corresponding information > - * in the LOG control block. Initialize the LOG IMM-OI > - * interface. Become class implementer. > + * in the LOG control block. > * > * @param cb[in] control block > * @return > @@ -2987,20 +2982,6 @@ SaAisErrorT lgs_imm_init_configStreams(lgs_cb_t > *cb) > { > } > } > > - /* 1.Become implementer > - * 2.Update creation timestamp for all configure object, must be object > - * implementer first 3.Open all streams Config file and log file will be > - * created. If this fails we give up without returning any error. A new > - * attempt to create the files will be done when trying to write a log > - * record to the stream. > - */ > - ais_rc = > - immutil_saImmOiClassImplementerSet(cb->immOiHandle, > "SaLogStreamConfig"); > - if (ais_rc != SA_AIS_OK) { > - LOG_ER("immutil_saImmOiClassImplementerSet failed %s", > saf_error(ais_rc)); > - osaf_abort(0); > - } > - > // Iterate all existing log streams in cluster. > while ((stream = iterate_all_streams(endloop, jstart)) && !endloop) { > jstart = SA_FALSE; > @@ -3021,7 +3002,7 @@ SaAisErrorT lgs_imm_init_configStreams(lgs_cb_t > *cb) { > } > > ais_rc = immutil_update_one_rattr( > - cb->immOiHandle, stream->name.c_str(), > + lgsGetOiHandle(), stream->name.c_str(), > const_cast<SaImmAttrNameT>("saLogStreamCreationTimestamp"), > SA_IMM_ATTR_SATIMET, &stream->creationTimeStamp); > if (ais_rc != SA_AIS_OK) { > @@ -3046,255 +3027,6 @@ done: > return ais_rc; > } > > -/** > - * Initialize the OI interface and get a selection object. > - * Become OI for safLogService if Active > - * > - * @param immOiHandle[out] > - * @param immSelectionObject[out] > - */ > -void lgs_imm_init_OI_handle(SaImmOiHandleT *immOiHandle, > - SaSelectionObjectT *immSelectionObject) { > - SaAisErrorT rc; > - uint32_t msecs_waited = 0; > - > - TRACE_ENTER(); > - > - /* Initialize IMM OI service */ > - SaVersionT imm_version = kImmVersion; > - rc = saImmOiInitialize_2(immOiHandle, &callbacks, &imm_version); > - while ((rc == SA_AIS_ERR_TRY_AGAIN) && > - (msecs_waited < max_waiting_time_60s)) { > - usleep(sleep_delay_ms * 1000); > - msecs_waited += sleep_delay_ms; > - imm_version = kImmVersion; > - rc = saImmOiInitialize_2(immOiHandle, &callbacks, &imm_version); > - } > - if (rc != SA_AIS_OK) { > - lgs_exit("saImmOiInitialize_2 failed", SA_AMF_COMPONENT_RESTART); > - } > - > - /* Get selection object for event handling */ > - msecs_waited = 0; > - rc = saImmOiSelectionObjectGet(*immOiHandle, immSelectionObject); > - while ((rc == SA_AIS_ERR_TRY_AGAIN) && > - (msecs_waited < max_waiting_time_10s)) { > - usleep(sleep_delay_ms * 1000); > - msecs_waited += sleep_delay_ms; > - rc = saImmOiSelectionObjectGet(*immOiHandle, immSelectionObject); > - } > - if (rc != SA_AIS_OK) { > - lgs_exit("saImmOiSelectionObjectGet failed", > SA_AMF_COMPONENT_RESTART); > - } > - > - TRACE_LEAVE2("rc: %s", saf_error(rc)); > -} > - > -/** > - * Does the sequence of setting an implementer name and class > implementer > - * > - * @param immOiHandle[in] > - * @return SaAisErrorT > - */ > -static SaAisErrorT imm_impl_set_sequence( > - SaImmOiHandleT *immOiHandle, SaSelectionObjectT > *immSelectionObject) { > - SaAisErrorT rc = SA_AIS_OK; > - uint32_t msecs_waited = 0; > - > - TRACE_ENTER(); > - > - for (;;) { > - if (msecs_waited >= max_waiting_time_60s) { > - TRACE("Timeout in imm_impl_set_sequence"); > - goto done; > - } > - > - /* Become object implementer > - */ > - rc = saImmOiImplementerSet(*immOiHandle, implementerName); > - while (((rc == SA_AIS_ERR_TRY_AGAIN) || (rc == SA_AIS_ERR_EXIST)) && > - (msecs_waited < max_waiting_time_60s)) { > - usleep(sleep_delay_ms * 1000); > - msecs_waited += sleep_delay_ms; > - rc = saImmOiImplementerSet(*immOiHandle, implementerName); > - } > - if (rc == SA_AIS_ERR_BAD_HANDLE || rc == SA_AIS_ERR_TIMEOUT) { > - LOG_WA("saImmOiImplementerSet returned %s", saf_error(rc)); > - usleep(sleep_delay_ms * 1000); > - msecs_waited += sleep_delay_ms; > - saImmOiFinalize(*immOiHandle); > - *immOiHandle = 0; > - *immSelectionObject = -1; > - lgs_imm_init_OI_handle(immOiHandle, immSelectionObject); > - continue; > - } > - if (rc != SA_AIS_OK) { > - TRACE("saImmOiImplementerSet failed %s", saf_error(rc)); > - goto done; > - } > - > - /* > - * Become class implementer for the OpenSafLogConfig class if it exists > - * Become class implementer for the SaLogStreamConfig class > - */ > - if (true == *static_cast<const bool *>( > - > lgs_cfg_get(LGS_IMM_LOG_OPENSAFLOGCONFIG_CLASS_EXIST))) > { > - rc = saImmOiClassImplementerSet(*immOiHandle, logConfig_str); > - while (((rc == SA_AIS_ERR_TRY_AGAIN) || (rc == SA_AIS_ERR_EXIST)) > && > - (msecs_waited < max_waiting_time_60s)) { > - usleep(sleep_delay_ms * 1000); > - msecs_waited += sleep_delay_ms; > - rc = saImmOiClassImplementerSet(*immOiHandle, logConfig_str); > - } > - if (rc == SA_AIS_ERR_BAD_HANDLE || rc == SA_AIS_ERR_TIMEOUT) { > - LOG_WA("saImmOiClassImplementerSet returned %s", saf_error(rc)); > - usleep(sleep_delay_ms * 1000); > - msecs_waited += sleep_delay_ms; > - saImmOiFinalize(*immOiHandle); > - *immOiHandle = 0; > - *immSelectionObject = -1; > - lgs_imm_init_OI_handle(immOiHandle, immSelectionObject); > - continue; > - } > - if (rc != SA_AIS_OK) { > - TRACE("saImmOiClassImplementerSet OpenSafLogConfig failed %s", > - saf_error(rc)); > - goto done; > - } > - } > - > - rc = saImmOiClassImplementerSet(*immOiHandle, streamConfig_str); > - while (((rc == SA_AIS_ERR_TRY_AGAIN) || (rc == SA_AIS_ERR_EXIST)) && > - (msecs_waited < max_waiting_time_60s)) { > - usleep(sleep_delay_ms * 1000); > - msecs_waited += sleep_delay_ms; > - rc = saImmOiClassImplementerSet(*immOiHandle, streamConfig_str); > - } > - if (rc == SA_AIS_ERR_BAD_HANDLE || rc == SA_AIS_ERR_TIMEOUT) { > - LOG_WA("saImmOiClassImplementerSet returned %s", saf_error(rc)); > - usleep(sleep_delay_ms * 1000); > - msecs_waited += sleep_delay_ms; > - saImmOiFinalize(*immOiHandle); > - *immOiHandle = 0; > - *immSelectionObject = -1; > - lgs_imm_init_OI_handle(immOiHandle, immSelectionObject); > - continue; > - } > - if (rc != SA_AIS_OK) { > - TRACE("saImmOiClassImplementerSet SaLogStreamConfig failed %s", > - saf_error(rc)); > - goto done; > - } > - break; > - } > - > -done: > - TRACE_LEAVE2("rc: %s", saf_error(rc)); > - return rc; > -} > - > -/** > - * Set implementer name and become class implementer. > - * This function will block until done. > - * > - * @param cb > - */ > -void lgs_imm_impl_set(SaImmOiHandleT *immOiHandle, > - SaSelectionObjectT *immSelectionObject) { > - SaAisErrorT rc = SA_AIS_OK; > - > - TRACE_ENTER(); > - > - rc = imm_impl_set_sequence(immOiHandle, immSelectionObject); > - if (rc != SA_AIS_OK) { > - lgs_exit("Becoming OI implementer failed", > SA_AMF_COMPONENT_RESTART); > - } > - > - TRACE_LEAVE(); > -} > - > -/** > - * Thread > - * Restore object and class implementer/applier. > - * > - * @param _cb[in] > - */ > -static void *imm_impl_init_thread(void *_cb) { > - lgs_cb_t *cb = static_cast<lgs_cb_t *>(_cb); > - SaSelectionObjectT immSelectionObject = 0; > - SaImmOiHandleT immOiHandle = 0; > - SaAisErrorT rc = SA_AIS_OK; > - > - TRACE_ENTER(); > - > - /* Initialize handles and become implementer */ > - lgs_imm_init_OI_handle(&immOiHandle, &immSelectionObject); > - rc = imm_impl_set_sequence(&immOiHandle, &immSelectionObject); > - if (rc != SA_AIS_OK) { > - lgs_exit("Becoming OI implementer failed", > SA_AMF_COMPONENT_RESTART); > - } > - > - /* Store handle and selection object. > - * Protect if the poll loop in main is released during the storage > - * sequence. > - */ > - osaf_mutex_lock_ordie(&lgs_OI_init_mutex); > - cb->immSelectionObject = immSelectionObject; > - cb->immOiHandle = immOiHandle; > - osaf_mutex_unlock_ordie(&lgs_OI_init_mutex); > - > - /* Activate the poll loop in main() > - * This will reinstall IMM poll event handling > - */ > - lgsv_lgs_evt_t *lgsv_evt; > - lgsv_evt = static_cast<lgsv_lgs_evt_t *>(calloc(1, > sizeof(lgsv_lgs_evt_t))); > - osafassert(lgsv_evt); > - lgsv_evt->evt_type = LGSV_EVT_NO_OP; > - if (m_NCS_IPC_SEND(&lgs_mbx, lgsv_evt, LGS_IPC_PRIO_CTRL_MSGS) != > - NCSCC_RC_SUCCESS) { > - LOG_WA("imm_reinit_thread failed to send IPC message to main > thread"); > - /* > - * Se no reason why this would happen. But if it does at least there > - * is something in the syslog. The main thread should still pick up > - * the new imm FD when there is a healthcheck, but it could take > - *minutes. > - */ > - free(lgsv_evt); > - } > - > - TRACE_LEAVE(); > - return NULL; > -} > - > -/** > - * In a separate thread: > - * Initiate IMM OI handle and selection object > - * Create imm implementer for log IMM objects > - * When complete: > - * Store the new handle and selection object in the cb store. > - * Activate the poll loop in main() by sending an empty mailbox message > - * > - * @param cb[out] > - */ > -void lgs_imm_impl_reinit_nonblocking(lgs_cb_t *cb) { > - pthread_t thread; > - pthread_attr_t attr; > - > - TRACE_ENTER(); > - > - pthread_attr_init(&attr); > - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); > - > - if (pthread_create(&thread, &attr, imm_impl_init_thread, cb) != 0) { > - LOG_ER("pthread_create FAILED: %s", strerror(errno)); > - exit(EXIT_FAILURE); > - } > - > - pthread_attr_destroy(&attr); > - > - TRACE_LEAVE(); > -} > - > > /********************************************************** > ***************** > *** > * Functions used for recovery handling > > ********************************************************** > ****************** > **/ > @@ -3403,12 +3135,16 @@ void lgs_delete_one_stream_object(const > std::string > &name_str) { > osaf_extended_name_lend(name_str.c_str(), &object_name); > > /* and delete the object */ > - ais_rc = immutil_saImmOiRtObjectDelete(lgs_cb->immOiHandle, > &object_name); > + ais_rc = immutil_saImmOiRtObjectDelete(lgsGetOiHandle(), > &object_name); > if (ais_rc == SA_AIS_OK) { > TRACE("%s Object \"%s\" deleted", __FUNCTION__, name_str.c_str()); > + } else if (ais_rc == SA_AIS_ERR_BAD_HANDLE) { > + LOG_NO("%s: saImmOiRtObjectDelete() Fail, %s", __FUNCTION__, > + saf_error(ais_rc)); > + lgsOiCreateBackground(); > } else { > - LOG_WA("%s saImmOiRtObjectDelete for \"%s\" FAILED %d", > __FUNCTION__, > - name_str.c_str(), ais_rc); > + LOG_WA("%s saImmOiRtObjectDelete for \"%s\" FAILED %s", > __FUNCTION__, > + name_str.c_str(), saf_error(ais_rc)); > } > } > > @@ -3444,12 +3180,16 @@ void lgs_cleanup_abandoned_streams() { > /* Copy name to a SaNameT */ > osaf_extended_name_lend(name_str, &object_name); > /* and delete the object */ > - ais_rc = immutil_saImmOiRtObjectDelete(lgs_cb->immOiHandle, > &object_name); > + ais_rc = immutil_saImmOiRtObjectDelete(lgsGetOiHandle(), > &object_name); > if (ais_rc == SA_AIS_OK) { > TRACE("\tObject \"%s\" deleted", name_str); > + } else if (ais_rc == SA_AIS_ERR_BAD_HANDLE) { > + LOG_WA("%s saImmOiRtObjectDelete for \"%s\" FAILED %s", > __FUNCTION__, > + name_str, saf_error(ais_rc)); > + lgsOiCreateBackground(); > } else { > - LOG_WA("%s saImmOiRtObjectDelete for \"%s\" FAILED %d", > __FUNCTION__, > - name_str, ais_rc); > + LOG_WA("%s saImmOiRtObjectDelete for \"%s\" FAILED %s", > __FUNCTION__, > + name_str, saf_error(ais_rc)); > } > } else { > /* Should never happen! */ > diff --git a/src/log/logd/lgs_imm.h b/src/log/logd/lgs_imm.h > new file mode 100644 > index 000000000..195d09380 > --- /dev/null > +++ b/src/log/logd/lgs_imm.h > @@ -0,0 +1,53 @@ > +/* -*- OpenSAF -*- > + * > + * (C) Copyright 2008 The OpenSAF Foundation > + * Copyright Ericsson AB 2008, 2018 - All Rights Reserved. > + * > + * This program is distributed in the hope that it will be useful, but > + * WITHOUT ANY WARRANTY; without even the implied warranty of > MERCHANTABILITY > + * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are > licensed > + * under the GNU Lesser General Public License Version 2.1, February 1999. > + * The complete license can be accessed from the following location: > + * http://opensource.org/licenses/lgpl-license.php > + * See the Copying file included with the OpenSAF distribution for full > + * licensing terms. > + * > + * Author(s): Ericsson AB > + * > + */ > + > +#ifndef LGS_IMM_H > +#define LGS_IMM_H > + > +#include <time.h> > +#include <string> > + > +#include "ais/include/saImmOi.h" > +#include "ais/include/saImmOm.h" > + > +#include "log/logd/lgs_cb.h" > + > +// Get the callback structure used when initializing an OI handle > +const SaImmOiCallbacksT_2* getImmOiCallbacks(void); > + > +void logRootDirectory_filemove(const std::string &new_logRootDirectory, > + const std::string > &old_logRootDirectory, > + time_t *cur_time_in); > +void logDataGroupname_fileown(const char *new_logDataGroupname); > + > +SaAisErrorT lgs_imm_init_configStreams(lgs_cb_t *cb); > + > +// Functions for recovery handling > +void lgs_cleanup_abandoned_streams(); > +void lgs_delete_one_stream_object(const std::string &name_str); > +void lgs_search_stream_objects(); > +SaUint32T *lgs_get_scAbsenceAllowed_attr(SaUint32T *attr_val); > +int lgs_get_streamobj_attr(SaImmAttrValuesT_2 ***attrib_out, > + const std::string &object_name, > + SaImmHandleT *immOmHandle); > +int lgs_free_streamobj_attr(SaImmHandleT immHandle); > + > + > + > +#endif /* LGS_IMM_H */ > + > diff --git a/src/log/logd/lgs_main.cc b/src/log/logd/lgs_main.cc > index 988ebdd78..9767fe00d 100644 > --- a/src/log/logd/lgs_main.cc > +++ b/src/log/logd/lgs_main.cc > @@ -33,16 +33,18 @@ > #include "nid/agent/nid_api.h" > #include "base/ncs_main_papi.h" > #include "base/osaf_time.h" > - > -#include "log/logd/lgs.h" > -#include "log/logd/lgs_file.h" > #include "base/osaf_utility.h" > #include "base/hash.h" > -#include "lgs_recov.h" > #include "osaf/immutil/immutil.h" > + > +#include "log/logd/lgs.h" > +#include "log/logd/lgs_file.h" > +#include "log/logd/lgs_recov.h" > #include "lgs_clm.h" > #include "log/logd/lgs_dest.h" > #include "log/logd/lgs_amf.h" > +#include "log/logd/lgs_oi_admin.h" > +#include "log/logd/lgs_imm.h" > > > /* > ========================================================== > ============== > @@ -383,26 +385,21 @@ uint32_t initialize_for_assignment(lgs_cb_t *cb, > SaAmfHAStateT ha_state) { > if (cb->fully_initialized || ha_state == SA_AMF_HA_QUIESCED) goto done; > cb->ha_state = ha_state; > > - /* Initialize IMM OI handle and selection object */ > - lgs_imm_init_OI_handle(&cb->immOiHandle, &cb->immSelectionObject); > - > - TRACE("IMM init done: cb->immOiHandle = %lld", cb->immOiHandle); > - > /* Initialize log configuration > * Must be done after IMM OI is initialized > */ > - lgs_cfg_init(cb->immOiHandle, cb->ha_state); > + lgs_cfg_init(); > lgs_trace_config(); /* Show all configuration in TRACE */ > > - /* Show some configurtion info in sysylog */ > - logsv_root_dir = > - static_cast<const char > *>(lgs_cfg_get(LGS_IMM_LOG_ROOT_DIRECTORY)); > - logsv_data_groupname = > - static_cast<const char *>(lgs_cfg_get(LGS_IMM_DATA_GROUPNAME)); > + /* Show some configuration info in sysylog */ > + logsv_root_dir = static_cast<const char *> > + (lgs_cfg_get(LGS_IMM_LOG_ROOT_DIRECTORY)); > + logsv_data_groupname = static_cast<const char *> > + (lgs_cfg_get(LGS_IMM_DATA_GROUPNAME)); > LOG_NO("LOG root directory is: \"%s\"", logsv_root_dir); > LOG_NO("LOG data group is: \"%s\"", logsv_data_groupname); > - vdest = reinterpret_cast<const std::vector<std::string> *>( > - > lgs_cfg_get(LGS_IMM_LOG_RECORD_DESTINATION_CONFIGURATION)); > + vdest = reinterpret_cast<const std::vector<std::string> *> > + > (lgs_cfg_get(LGS_IMM_LOG_RECORD_DESTINATION_CONFIGURATION)); > osafassert(vdest != nullptr); > if (vdest->size() > 0) { > CfgDestination(*vdest, ModifyType::kAdd); > @@ -445,20 +442,15 @@ uint32_t initialize_for_assignment(lgs_cb_t *cb, > SaAmfHAStateT ha_state) { > } > > if (ha_state == SA_AMF_HA_ACTIVE) { > - /* Become OI. We will be blocked here until done */ > - lgs_imm_impl_set(&cb->immOiHandle, &cb->immSelectionObject); > - conf_runtime_obj_create(cb->immOiHandle); > + // Request an Object Implementer, a configuration object handler and > + // an applier for opensafNetworkName change surveillance > + lgsOiCreateSynchronous(); > + conf_runtime_obj_create(lgsGetOiHandle()); > lgs_start_gcfg_applier(); > > - /* Create streams that has configuration objects and become > - * class implementer for the SaLogStreamConfig class > - */ > - > - /* Note1: cb->immOiHandle is set in lgs_imm_init() > - * Note2: cb->logsv_root_dir must be set > - */ > + // Create streams that has configuration objects > if (lgs_imm_init_configStreams(cb) != SA_AIS_OK) { > - LOG_ER("lgs_imm_create_configStream FAILED"); > + LOG_ER("lgs_imm_create_configStreams FAILED"); > rc = NCSCC_RC_FAILURE; > goto done; > } > @@ -479,7 +471,7 @@ done: > */ > int main(int argc, char *argv[]) { > NCS_SEL_OBJ mbx_fd; > - SaAisErrorT error = SA_AIS_OK; > + SaAisErrorT ais_rc = SA_AIS_OK; > uint32_t rc; > int term_fd; > > @@ -519,7 +511,7 @@ int main(int argc, char *argv[]) { > fds[FD_AMF].events = POLLIN; > fds[FD_MBX].fd = mbx_fd.rmv_obj; > fds[FD_MBX].events = POLLIN; > - fds[FD_IMM].fd = lgs_cb->immSelectionObject; > + fds[FD_IMM].fd = lgsGetOiSelectionObject(); > fds[FD_IMM].events = POLLIN; > > lgs_cb->clmSelectionObject = lgs_cb->clm_init_sel_obj.rmv_obj; > @@ -539,18 +531,16 @@ int main(int argc, char *argv[]) { > fds[FD_CLM].fd = lgs_cb->clmSelectionObject; > fds[FD_CLM].events = POLLIN; > > - /* Protect since the reinit thread may be in the process of > - * changing the values > - */ > - osaf_mutex_lock_ordie(&lgs_OI_init_mutex); > - if (lgs_cb->immOiHandle != 0) { > - fds[FD_IMM].fd = lgs_cb->immSelectionObject; > + // Adds or removes the IMM fd depending on if there is an OI or not > + SaImmOiHandleT oi_handle; > + SaSelectionObjectT oi_selection_object = > lgsGetOiFdsParams(&oi_handle); > + if (oi_handle != 0) { > + fds[FD_IMM].fd = oi_selection_object; > fds[FD_IMM].events = POLLIN; > nfds = FD_IMM + 1; > } else { > nfds = FD_IMM; > } > - osaf_mutex_unlock_ordie(&lgs_OI_init_mutex); > > int ret = poll(fds, nfds, -1); > > @@ -567,9 +557,9 @@ int main(int argc, char *argv[]) { > > if (fds[FD_AMF].revents & POLLIN) { > if (lgs_cb->amf_hdl != 0) { > - if ((error = saAmfDispatch(lgs_cb->amf_hdl, SA_DISPATCH_ALL)) != > + if ((ais_rc = saAmfDispatch(lgs_cb->amf_hdl, SA_DISPATCH_ALL)) != > SA_AIS_OK) { > - LOG_ER("saAmfDispatch failed: %u", error); > + LOG_ER("saAmfDispatch failed: %u", ais_rc); > break; > } > } else { > @@ -593,9 +583,9 @@ int main(int argc, char *argv[]) { > > if (fds[FD_CLM].revents & POLLIN) { > if (lgs_cb->clm_hdl != 0) { > - if ((error = saClmDispatch(lgs_cb->clm_hdl, SA_DISPATCH_ALL)) != > + if ((ais_rc = saClmDispatch(lgs_cb->clm_hdl, SA_DISPATCH_ALL)) != > SA_AIS_OK) { > - LOG_ER("saClmDispatch failed: %u", error); > + LOG_ER("saClmDispatch failed: %u", ais_rc); > break; > } > } else { > @@ -629,40 +619,16 @@ int main(int argc, char *argv[]) { > > if (fds[FD_MBX].revents & POLLIN) lgs_process_mbx(&lgs_mbx); > > - if (lgs_cb->immOiHandle && fds[FD_IMM].revents & POLLIN) { > - error = saImmOiDispatch(lgs_cb->immOiHandle, SA_DISPATCH_ALL); > - > - /* > - * BAD_HANDLE is interpreted as an IMM service restart. Try > - * reinitialize the IMM OI API in a background thread and let > - * this thread do business as usual especially handling write > - * requests. > - * > - * All other errors are treated as non-recoverable (fatal) and will > - * cause an exit of the process. > - */ > - if (error == SA_AIS_ERR_BAD_HANDLE) { > - TRACE("saImmOiDispatch returned BAD_HANDLE"); > - > - /* > - * Invalidate the IMM OI handle, this info is used in other > - * locations. E.g. giving TRY_AGAIN responses to a create and > - * close app stream requests. That is needed since the IMM OI > - * is used in context of these functions. > - * > - * Also closing the handle. Finalize is ok with a bad handle > - * that is bad because it is stale and this actually clears > - * the handle from internal agent structures. In any case > - * we ignore the return value from Finalize here. > - */ > - saImmOiFinalize(lgs_cb->immOiHandle); > - lgs_cb->immOiHandle = 0; > - lgs_cb->immSelectionObject = -1; > - > - /* Initiate IMM reinitializtion in the background */ > - lgs_imm_impl_reinit_nonblocking(lgs_cb); > - } else if (error != SA_AIS_OK) { > - LOG_ER("saImmOiDispatch FAILED: %u", error); > + if (fds[FD_IMM].revents & POLLIN) { > + ais_rc = saImmOiDispatch(lgsGetOiHandle(), SA_DISPATCH_ALL); > + > + if (ais_rc == SA_AIS_ERR_BAD_HANDLE) { > + LOG_NO("saImmOiDispatch returned BAD_HANDLE"); > + > + // Request creation of a new OI > + lgsOiCreateBackground(); > + } else if (ais_rc != SA_AIS_OK) { > + LOG_ER("saImmOiDispatch FAILED: %u", ais_rc); > break; > } > } > diff --git a/src/log/logd/lgs_mbcsv_v2.cc b/src/log/logd/lgs_mbcsv_v2.cc > index 9afc30155..63807e1b7 100644 > --- a/src/log/logd/lgs_mbcsv_v2.cc > +++ b/src/log/logd/lgs_mbcsv_v2.cc > @@ -21,9 +21,10 @@ > * version 2 check-pointing. See also lgs_mbcsv_v2.h > */ > > -#include "lgs_config.h" > -#include "lgs_mbcsv_v2.h" > -#include "lgs_mbcsv.h" > +#include "log/logd/lgs_config.h" > +#include "log/logd/lgs_imm.h" > +#include "log/logd/lgs_mbcsv_v2.h" > +#include "log/logd/lgs_mbcsv.h" > > > /********************************************************** > ***************** > * > * Name : ckpt_proc_lgs_cfg > diff --git a/src/log/logd/lgs_mbcsv_v3.cc b/src/log/logd/lgs_mbcsv_v3.cc > index f9836c8af..75fd98dba 100644 > --- a/src/log/logd/lgs_mbcsv_v3.cc > +++ b/src/log/logd/lgs_mbcsv_v3.cc > @@ -21,9 +21,10 @@ > * version 3 check-pointing. See also lgs_mbcsv_v3.h > */ > > -#include "lgs_mbcsv_v3.h" > -#include "lgs_mbcsv_v2.h" > -#include "lgs_mbcsv.h" > +#include "log/logd/lgs_imm.h" > +#include "log/logd/lgs_mbcsv_v3.h" > +#include "log/logd/lgs_mbcsv_v2.h" > +#include "log/logd/lgs_mbcsv.h" > > > /********************************************************** > ***************** > * > * Name : ckpt_proc_lgs_cfg > diff --git a/src/log/logd/lgs_mbcsv_v5.cc b/src/log/logd/lgs_mbcsv_v5.cc > index 75d627688..d219f8a5b 100644 > --- a/src/log/logd/lgs_mbcsv_v5.cc > +++ b/src/log/logd/lgs_mbcsv_v5.cc > @@ -22,8 +22,9 @@ > * V5 applies to log server configuration check-pointing > */ > > -#include "lgs_mbcsv_v5.h" > #include "log/logd/lgs_dest.h" > +#include "log/logd/lgs_imm.h" > +#include "log/logd/lgs_mbcsv_v5.h" > > > /********************************************************** > ***************** > * > * Name : ckpt_proc_lgs_cfg > diff --git a/src/log/logd/lgs_oi_admin.cc b/src/log/logd/lgs_oi_admin.cc > new file mode 100644 > index 000000000..abd74c816 > --- /dev/null > +++ b/src/log/logd/lgs_oi_admin.cc > @@ -0,0 +1,461 @@ > +/* -*- OpenSAF -*- > + * > + * (C) Copyright 2008 The OpenSAF Foundation > + * Copyright Ericsson AB 2008, 2018 - All Rights Reserved. > + * > + * This program is distributed in the hope that it will be useful, but > + * WITHOUT ANY WARRANTY; without even the implied warranty of > MERCHANTABILITY > + * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are > licensed > + * under the GNU Lesser General Public License Version 2.1, February 1999. > + * The complete license can be accessed from the following location: > + * http://opensource.org/licenses/lgpl-license.php > + * See the Copying file included with the OpenSAF distribution for full > + * licensing terms. > + * > + * Author(s): Ericsson AB > + * > + */ > + > +#include "log/logd/lgs_oi_admin.h" > + > +#include <atomic> > +#include <thread> > + > +#include "ais/include/saAis.h" > +#include "ais/include/saImmOi.h" > +#include "base/logtrace.h" > +#include "base/mutex.h" > +#include "base/saf_error.h" > +#include "base/time.h" > + > +#include "log/logd/lgs.h" > +#include "log/logd/lgs_imm.h" > +#include "log/logd/lgs_config.h" > +#include "log/logd/lgs_util.h" > + > +// Note: Always use the set and get function with these varibales > +static base::Mutex lgs_OI_init_mutex; > +static SaImmOiHandleT oi_handle_ = 0; > +static SaSelectionObjectT oi_selection_object_ = -1; > + > +static const SaImmOiImplementerNameT kImplementerName = > + const_cast<SaImmOiImplementerNameT>("safLogService"); > +// The log server is OI for the following configuration classes > +static const SaImmClassNameT kLogConfigurationClass = > + const_cast<SaImmClassNameT>("OpenSafLogConfig"); > +static const SaImmClassNameT kLogStreamClass = > + const_cast<SaImmClassNameT>("SaLogStreamConfig"); > + > +static const uint64_t kOiCreationTimeout = 90000; // 1.5 minutes > +static const uint64_t kOiHandleRequestTimeout = 60000; // 1 minute > +static const uint64_t kOiRequestTimeout = 10000; // 10 sec generic timeout > +static const timespec kOiTryAgainDelay = base::kOneHundredMilliseconds; > + > +// Internal help functions > +// --------------------------------- > + > +static void setProtectedGlobals(SaImmOiHandleT oi_handle, > + SaSelectionObjectT oi_selction_object) { > + TRACE_ENTER(); > + base::Lock protect_globals(lgs_OI_init_mutex); > + oi_handle_ = oi_handle; > + oi_selection_object_ = oi_selction_object; > +} > + > +static SaAisErrorT finalizeOi(SaImmOiHandleT oi_handle) { > + TRACE_ENTER(); > + SaAisErrorT ais_rc = SA_AIS_OK; > + base::Timer try_again_timer(kOiRequestTimeout); > + while (try_again_timer.is_timeout() == false) { > + ais_rc = saImmOiFinalize(oi_handle); > + if (ais_rc == SA_AIS_ERR_TRY_AGAIN) { > + base::Sleep(kOiTryAgainDelay); > + continue; > + } > + if (ais_rc != SA_AIS_OK) { > + TRACE("%s: saImmOiFinalize() Fail, %s", __FUNCTION__, > saf_error(ais_rc)); > + } > + break; > + } > + if ((try_again_timer.is_timeout() == true) && > + (ais_rc == SA_AIS_ERR_TRY_AGAIN)) { > + LOG_NO("%s: saImmOiFinalize() Fail, TRY AGAIN timeout", > __FUNCTION__); > + } > + > + return ais_rc; > +} > + > +// IMM API help function used in the OI creation thread > +// Communication flag read in OI thread and set by the lgs_OI_delete() and > +// create functions. When this flag is true the thread shall stop and > return > +// as soon as possible > +// Note: All of these functions will stop internal loops and return if > +// the global atomic flag oi_stop == true > +static std::atomic<bool> stop_oi_create(false); > + > +// Output: out_oi_handle. Set to 0 if fail > +static SaAisErrorT initOiHandle(SaImmOiHandleT *out_oi_handle) { > + TRACE_ENTER(); > + SaAisErrorT ais_rc = SA_AIS_OK; > + const SaImmOiCallbacksT_2 *callbacks = getImmOiCallbacks(); > + base::Timer try_again_timer(kOiHandleRequestTimeout); > + while (try_again_timer.is_timeout() == false) { > + if (stop_oi_create) { > + ais_rc = SA_AIS_OK; > + break; > + } > + SaVersionT imm_version = kImmVersion; > + ais_rc = saImmOiInitialize_2(out_oi_handle, callbacks, &imm_version); > + if (ais_rc == SA_AIS_ERR_TRY_AGAIN) { > + base::Sleep(kOiTryAgainDelay); > + continue; > + } > + if (ais_rc != SA_AIS_OK) { > + LOG_WA("%s: saImmOiInitialize_2() Fail, %s", __FUNCTION__, > + saf_error(ais_rc)); > + *out_oi_handle = 0; > + } > + break; > + } > + if ((try_again_timer.is_timeout() == true) && > + (ais_rc == SA_AIS_ERR_TRY_AGAIN)) { > + LOG_WA("%s: saImmOiInitialize_2() Fail, TRY AGAIN timeout", > __FUNCTION__); > + *out_oi_handle = 0; > + } > + > + return ais_rc; > +} > + > +// Return -1 if Fail > +// out_ais_rc is set to return code from saImmOiSelectionObjectGet() > +static SaSelectionObjectT requestOiSelectionObject(SaImmOiHandleT > oi_handle, > + SaAisErrorT* out_ais_rc) > { > + TRACE_ENTER(); > + SaSelectionObjectT oi_selection_object = -1; > + SaAisErrorT ais_rc = SA_AIS_OK; > + base::Timer try_again_timer(kOiRequestTimeout); > + while (try_again_timer.is_timeout() == false) { > + if (stop_oi_create) { > + oi_selection_object = -1; > + break; > + } > + ais_rc = saImmOiSelectionObjectGet(oi_handle, &oi_selection_object); > + if (ais_rc == SA_AIS_ERR_TRY_AGAIN) { > + base::Sleep(kOiTryAgainDelay); > + continue; > + } > + if (ais_rc != SA_AIS_OK) { > + LOG_WA("%s: saImmOiSelectionObjectGet() Fail, %s", __FUNCTION__, > + saf_error(ais_rc)); > + oi_selection_object = -1; > + } > + break; > + } > + if ((try_again_timer.is_timeout() == true) && > + (ais_rc == SA_AIS_ERR_TRY_AGAIN)) { > + LOG_WA("%s: saImmOiSelectionObjectGet() Fail, TRY AGAIN timeout", > + __FUNCTION__); > + oi_selection_object = -1; > + } > + > + *out_ais_rc = ais_rc; > + return oi_selection_object; > +} > + > +// Set implementer name in kImplementerName > +static SaAisErrorT setOiImplementerName(SaImmOiHandleT oi_handle) { > + TRACE_ENTER(); > + SaAisErrorT ais_rc = SA_AIS_OK; > + base::Timer try_again_timer(kOiRequestTimeout); > + while (try_again_timer.is_timeout() == false) { > + if (stop_oi_create) { > + ais_rc = SA_AIS_OK; > + break; > + } > + ais_rc = saImmOiImplementerSet(oi_handle, kImplementerName); > + if (ais_rc == SA_AIS_ERR_TRY_AGAIN) { > + base::Sleep(kOiTryAgainDelay); > + continue; > + } > + if (ais_rc == SA_AIS_ERR_EXIST) { > + // Means that we already have the implementer name registered which > is Ok > + TRACE("%s saImmOiImplementerSet() Fail %s. Ignore", > + __FUNCTION__, saf_error(ais_rc)); > + ais_rc = SA_AIS_OK; > + break; > + } else if (ais_rc != SA_AIS_OK) { > + LOG_WA("%s: saImmOiImplementerSet() Fail, %s", __FUNCTION__, > + saf_error(ais_rc)); > + } > + break; > + } > + if ((try_again_timer.is_timeout() == true) && > + (ais_rc == SA_AIS_ERR_TRY_AGAIN)) { > + LOG_WA("%s: saImmOiImplementerSet() Fail, TRY AGAIN timeout", > + __FUNCTION__); > + } > + > + TRACE_LEAVE2("ais_rc = %s", saf_error(ais_rc)); > + return ais_rc; > +} > + > +static SaAisErrorT setClassImplementer(SaImmOiHandleT oi_handle, > + const SaImmClassNameT class_name) { > + SaAisErrorT ais_rc = SA_AIS_OK; > + base::Timer try_again_timer(kOiRequestTimeout); > + while (try_again_timer.is_timeout() == false) { > + if (stop_oi_create) { > + ais_rc = SA_AIS_OK; > + break; > + } > + ais_rc = saImmOiClassImplementerSet(oi_handle, class_name); > + if (ais_rc == SA_AIS_ERR_TRY_AGAIN) { > + base::Sleep(kOiTryAgainDelay); > + continue; > + } > + if (ais_rc != SA_AIS_OK) { > + LOG_WA("%s: saImmOiClassImplementerSet() Fail, %s", > __FUNCTION__, > + saf_error(ais_rc)); > + } > + break; > + } > + if ((try_again_timer.is_timeout() == true) && > + (ais_rc == SA_AIS_ERR_TRY_AGAIN)) { > + LOG_WA("%s: saImmOiClassImplementerSet() Fail, TRY AGAIN timeout", > + __FUNCTION__); > + } > + > + return ais_rc; > +} > + > +// Activate the poll loop in main() > +// This will reinstall IMM poll event handling > +static void sendOiCreatedMessageToMainThread() { > + TRACE_ENTER(); > + // Note: lgsv_evt must be allocated C style since it will be freed in > other > + // part of the code with free() > + lgsv_lgs_evt_t *lgsv_evt; > + lgsv_evt = static_cast<lgsv_lgs_evt_t *>(calloc(1, > sizeof(lgsv_lgs_evt_t))); > + osafassert(lgsv_evt); > + > + lgsv_evt->evt_type = LGSV_EVT_NO_OP; > + if (m_NCS_IPC_SEND(&lgs_mbx, lgsv_evt, LGS_IPC_PRIO_CTRL_MSGS) != > + NCSCC_RC_SUCCESS) { > + LOG_WA("imm_reinit_thread failed to send IPC message to main > thread"); > + /* > + * Se no reason why this would happen. But if it does at least there > + * is something in the syslog. The main thread should still pick up > + * the new imm FD when there is a healthcheck, but it could take > + *minutes. > + */ > + free(lgsv_evt); > + } > +} > + > +// Creates the log service OI > +// stop_oi_create: Used to stop thread execution as soon as possible > +// Will stop the thread when set to true. > +static SaAisErrorT createLogServerOi() { > + TRACE_ENTER(); > + SaAisErrorT ais_rc = SA_AIS_OK; > + SaImmOiHandleT oi_handle = 0; > + SaSelectionObjectT oi_selection_object = -1; > + base::Timer io_create_timeout(kOiCreationTimeout); > + > + while (io_create_timeout.is_timeout() == false) { > + // OI init sequence > + > + // Init OI handle > + if (stop_oi_create) break; > + ais_rc = initOiHandle(&oi_handle); > + if (ais_rc != SA_AIS_OK) { > + LOG_NO("%s: initOiHandle() Fail", __FUNCTION__); > + oi_handle = 0; > + break; > + } > + > + // Set OI implementer name > + if (stop_oi_create) break; > + ais_rc = setOiImplementerName(oi_handle); > + if (ais_rc == SA_AIS_ERR_BAD_HANDLE) { > + TRACE("%s: setOiImplementerName() Fail %s. Try to recover", > + __FUNCTION__, saf_error(ais_rc)); > + continue; > + } else if (ais_rc != SA_AIS_OK) { > + LOG_NO("%s: setOiImplementerName() Fail", __FUNCTION__); > + break; > + } > + > + // Become class implementer for log config class > + if (stop_oi_create) break; > + ais_rc = setClassImplementer(oi_handle, kLogConfigurationClass); > + if (ais_rc == SA_AIS_ERR_BAD_HANDLE) { > + TRACE("%s: setClassImplementer(LogConfigurationClass) Fail %s. " > + "Try to recover", __FUNCTION__, saf_error(ais_rc)); > + continue; > + } else if (ais_rc != SA_AIS_OK) { > + LOG_NO("%s: setClassImplementer(LogConfigurationClass) Fail", > + __FUNCTION__); > + break; > + } > + > + // Become class implementer for stream config class > + if (stop_oi_create) break; > + ais_rc = setClassImplementer(oi_handle, kLogStreamClass); > + if (ais_rc == SA_AIS_ERR_BAD_HANDLE) { > + TRACE("%s: setClassImplementer(kLogStreamClass) Fail %s. " > + "Try to recover", __FUNCTION__, saf_error(ais_rc)); > + continue; > + } else if (ais_rc != SA_AIS_OK) { > + LOG_NO("%s: setClassImplementer(kLogStreamClass) Fail", > __FUNCTION__); > + break; > + } else { > + // Get the selection object > + oi_selection_object = requestOiSelectionObject(oi_handle, &ais_rc); > + if (ais_rc == SA_AIS_ERR_BAD_HANDLE) { > + TRACE("%s: requestOiSelectionObject() Fail", __FUNCTION__); > + } > + break; > + } > + } > + > + // Creation is done, has failed or is stopped. > + if (stop_oi_create) { > + TRACE("%s: OI create is stopped", __FUNCTION__); > + oi_handle = 0; > + oi_selection_object = -1; > + ais_rc = SA_AIS_ERR_NO_OP; // Dummy. Must not be SA_AIS_OK > + } else if ((io_create_timeout.is_timeout() == true) && > + (ais_rc != SA_AIS_OK)) { > + LOG_WA("%s: Fail, OI creation timeout", __FUNCTION__); > +#if 0 // Note: The following is needed if some other recovery than restart > + oi_handle = 0; > + oi_selection_object = -1; > +#endif > + // The legacy behavior is to exit log service in this case > + lgs_exit("saImmOiInitialize_2 failed", SA_AMF_COMPONENT_RESTART); > + } else if (ais_rc != SA_AIS_OK) { > + LOG_WA("%s: Fail, OI creation error", __FUNCTION__); > +#if 0 // Note: The following is needed if some other recovery than restart > + oi_handle = 0; > + oi_selection_object = -1; > +#endif > + // The legacy behavior is to exit log service in this case > + lgs_exit("saImmOiInitialize_2 failed", SA_AMF_COMPONENT_RESTART); > + } > + > + // Save OI handle and selection object > + setProtectedGlobals(oi_handle, oi_selection_object); > + > + return ais_rc; > +} > + > +// The thread function for creating a log server OI > +// stop_oi_create: Used to stop thread execution as soon as possible > +// Will stop the thread when set to true. > +static void oiCreationThread() { > + TRACE_ENTER(); > + SaAisErrorT ais_rc = createLogServerOi(); > + > + if (ais_rc == SA_AIS_OK) { > + // An object implementer was successfully created > + // Send a message to the main thread. IMM events shall be polled again > + sendOiCreatedMessageToMainThread(); > + } > + > + return; > +} > + > +// Public functions > +//----------------- > +// Make the thread class available for create and delete > +static std::thread oiCreationThread_ {}; > + > + > +SaImmOiHandleT lgsGetOiHandle() { > + base::Lock protect_globals(lgs_OI_init_mutex); > + return oi_handle_; > +} > + > +SaSelectionObjectT lgsGetOiSelectionObject() { > + base::Lock protect_globals(lgs_OI_init_mutex); > + return oi_selection_object_; > +} > + > +SaSelectionObjectT lgsGetOiFdsParams(SaImmOiHandleT* out_oi_handle) > { > + base::Lock protect_globals(lgs_OI_init_mutex); > + *out_oi_handle = oi_handle_; > + return oi_selection_object_; > +} > + > +void lgsOiCreateBackground() { > + TRACE_ENTER(); > + if ((oiCreationThread_.joinable() == true) || (stop_oi_create == true)) { > + // Thread is executing. Do nothing > + return; > + } > + > + // Make sure that the OI is finalized before creating a new one > + // Note: oi_handle_ can be use unprotected here since we know that > there > is > + // no running oiCreationThread > + finalizeOi(oi_handle_); > + oi_handle_ = 0; > + oi_selection_object_ = -1; > + > + // Start a OI creation thread > + // Note: Throws an exception if "The system is unable to start a new > thread" > + // Should never happen so it is not handled here (will cause node > restart) > + oiCreationThread_ = std::thread {&oiCreationThread}; > +} > + > +void lgsOiCreateSynchronous() { > + TRACE_ENTER(); > + // Note: oi_handle_ can be use unprotected here since we know that > there > is > + // no running oiCreationThread > + // There is no meaning to vall finalizeOI() since this function only > shall be > + // used for the first creation of an OI handle during initialization of > the > + // log service > + oi_handle_ = 0; > + oi_selection_object_ = -1; > + > + SaAisErrorT ais_rc = createLogServerOi(); > + LOG_NO("%s: createLogServerOi() %s", __FUNCTION__, > saf_error(ais_rc)); > +} > + > +// Note: In this version this is just call lgsOiCreateBackground(). The > reason > +// for having this function is to have a place where an implementer set can > +// be done instead of creating an OI if the lgsOiStop function is changed > +// to just clear the OI. Note that if set fail the OI must be created > anyway > +// > +// This function shall be used only when changing HA state from standby to > +// active > +void lgsOiStart() { > + TRACE_ENTER(); > + lgsOiCreateBackground(); > +} > + > +// Note: oi_handle_ and oi_selection_object_ is always set in thread also > if > +// thread is stopped. Is set to 0 and -1 respectively in all cases except > when > +// an OI is successfully created > +// > +// Note: This version will completely finalize the OI. This is probably > good > +// enough. Clear / Set handling may be a bit faster but Stop / Start > of > +// OI should be rare. > +// If optimization is needed we can do implementer clear here > +void lgsOiStop() { > + TRACE_ENTER(); > + stop_oi_create = true; > + > + // Handle thread if it exist > + if (oiCreationThread_.joinable() == true) { > + // Wait for thread to stop > + oiCreationThread_.join(); > + } > + > + // Note: oi_handle_ can be use unprotected here since we know that > there > is > + // no running oiCreationThread > + finalizeOi(oi_handle_); > + oi_handle_ = 0; > + oi_selection_object_ = -1; > + stop_oi_create = false; > +} > diff --git a/src/log/logd/lgs_oi_admin.h b/src/log/logd/lgs_oi_admin.h > new file mode 100644 > index 000000000..8502e30e7 > --- /dev/null > +++ b/src/log/logd/lgs_oi_admin.h > @@ -0,0 +1,105 @@ > +/* -*- OpenSAF -*- > + * > + * (C) Copyright 2008 The OpenSAF Foundation > + * Copyright Ericsson AB 2008, 2018 - All Rights Reserved. > + * > + * This program is distributed in the hope that it will be useful, but > + * WITHOUT ANY WARRANTY; without even the implied warranty of > MERCHANTABILITY > + * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are > licensed > + * under the GNU Lesser General Public License Version 2.1, February 1999. > + * The complete license can be accessed from the following location: > + * http://opensource.org/licenses/lgpl-license.php > + * See the Copying file included with the OpenSAF distribution for full > + * licensing terms. > + * > + * Author(s): Ericsson AB > + * > + */ > + > +#include "ais/include/saImmOi.h" > + > +// Contains administrative handling of the lgs main object implementer (OI) > +// Implements functions for initializing an OI in a background thread, > +// finalizing the OI and stop an ongoing initialization > +// The reason for using a background thread is to not block the log server. > +// An initialize request may take up to 1 minute. > +// When stopping the OI a running OI initializing thread is stopped and the > OI > +// is finalized. > +// > +// Examples of situations when the functions are used: > +// Starting log server: OI shall be intialized. This should be done in > +// background so that start of log server is not > blocked. > +// > +// Switch/fail over: The to become standby; must give up the OI. The > chosen > +// way of doing that is to finalize the OI. An > alternative > +// is to only clear the OI which is no longer used > here. > +// The to become active; must initialize an OI. An > +// alternative is to keep the OI handle and just use > the > +// set API > +// > +// BAD HANDLE: IMM may return bad handle when synchronous > operations > +// are called including the dispatch function. If this > +// happen the OI shall be initialized again except in > a > +// switch/fail over situation where the server shall > become > +// standby > +// > +// Note1: The background thread puts a no-operation message in the > mailbox > +// handled by the main poll loop when OI initialize is done. This is > +// needed to handle installing of the IMM fd in the poll loop. > +// > +// Note2: The previous global immOiHandle and immSelectionObject > variables > in > +// cb struct are removed. Values can be fetched using thread safe > get > +// functions > + > +#ifndef LGS_OI_ADMIN_H > +#define LGS_OI_ADMIN_H > + > +// Creates a new OI. Return false if fail. > +// Note1: If there is an existing OI it will be deleted and a new is > created. > +// This means calling IMM finalize, setting oi_handle = 0, > +// oi_selection_object = -1 and starting the OI creation thread. The > +// OI creation thread will update oi_handle and oi_selection_object > with > +// new values when creation is done. > +// Nothing will be done if OI creation is already ongoing when this > +// function is called > +// Note2: lgsOiCreateBackground() shall not be used when log server is > starting. > +// During initialization configuration streams are created. > +// When creating a configuration stream cached Rt attributes has to > be > +// written and this requires a valid OI handle > +// Instead use lgsOiCreateSyncronous() > +// > +// This function shall also be used to restore the OI in case of a BAD > HANDLE > +// return code when using the OI handle with an OI IMM operation. > +void lgsOiCreateBackground(); > + > +// Note3: This function shall only be called once and only when the log > server > +// is initializing > +// This function is not thread safe > +void lgsOiCreateSynchronous(); > + > +// Start an OI. > +// Shall be used when this server shall become an OI. > +// For example when becoming active > +void lgsOiStart(); > + > +// Stop an existing OI > +// To be used when this server no longer shall be an OI. > +// For example becoming standby > +void lgsOiStop(); > + > +// Get both OI handle and selection object. Guarantees that we get a pair > +// that is created together. Return -1 if there is no selection object and > +// the value of out_oi_handle will be 0 > +// Is thread safe > +SaSelectionObjectT lgsGetOiFdsParams(SaImmOiHandleT* out_oi_handle); > + > +// Returns the created OI selection object or -1 if there is none > +// Is thread safe > +SaSelectionObjectT lgsGetOiSelectionObject(); > + > +// Returns the created OI handle or 0 if there is no handle > +// Is thread safe > +SaImmOiHandleT lgsGetOiHandle(); > + > +#endif /* LGS_OI_ADMIN_H */ > + > diff --git a/src/log/logd/lgs_recov.cc b/src/log/logd/lgs_recov.cc > index dcaad188d..7c0197b7f 100644 > --- a/src/log/logd/lgs_recov.cc > +++ b/src/log/logd/lgs_recov.cc > @@ -15,9 +15,11 @@ > * > */ > > -#include "lgs_recov.h" > +#include "log/logd/lgs_recov.h" > + > #include "log/logd/lgs_file.h" > #include "log/logd/lgs_filehdl.h" > +#include "log/logd/lgs_imm.h" > > /*** > * The following functions are used to handle a list of runtime stream > objects > diff --git a/src/log/logd/lgs_stream.cc b/src/log/logd/lgs_stream.cc > index 0c83e305b..4f50f5a98 100644 > --- a/src/log/logd/lgs_stream.cc > +++ b/src/log/logd/lgs_stream.cc > @@ -30,14 +30,16 @@ > #include "log/logd/lgs_stream.h" > #include <algorithm> > > +#include "base/osaf_time.h" > +#include "osaf/immutil/immutil.h" > + > #include "log/logd/lgs.h" > #include "log/logd/lgs_config.h" > #include "log/logd/lgs_file.h" > #include "log/logd/lgs_filehdl.h" > #include "log/logd/lgs_mbcsv_v1.h" > #include "log/logd/lgs_mbcsv_v2.h" > -#include "base/osaf_time.h" > -#include "osaf/immutil/immutil.h" > +#include "log/logd/lgs_oi_admin.h" > > #define DEFAULT_NUM_APP_LOG_STREAMS 64 > > @@ -444,15 +446,18 @@ void log_stream_delete(log_stream_t **s) { > > if (lgs_cb->ha_state == SA_AMF_HA_ACTIVE) { > if (stream->isRtStream == SA_TRUE) { > - SaAisErrorT rv; > + SaAisErrorT ais_rc; > TRACE("Stream is closed, I am HA active so remove IMM object"); > SaNameT objectName; > osaf_extended_name_lend(stream->name.c_str(), &objectName); > - rv = saImmOiRtObjectDelete(lgs_cb->immOiHandle, &objectName); > - if (rv != SA_AIS_OK) { > + ais_rc = saImmOiRtObjectDelete(lgsGetOiHandle(), &objectName); > + if (ais_rc != SA_AIS_OK) { > + if (ais_rc == SA_AIS_ERR_BAD_HANDLE) { > + lgsOiCreateBackground(); > + } > /* no retry; avoid blocking LOG service #1886 */ > - LOG_WA("saImmOiRtObjectDelete returned %u for %s", rv, > - stream->name.c_str()); > + LOG_WA("%s: saImmOiRtObjectDelete returned %s for %s", > + __FUNCTION__, saf_error(ais_rc), stream->name.c_str()); > } > } > } > @@ -514,6 +519,53 @@ int lgs_populate_log_stream( > return rc; > } > > +// Wrap creation of a runtime object. Handle try again ERR_EXIST > +// If the object already exist it is deleted and then the new object is > created > +// Note: This is a help function to be used in createRtObject() only > +// Note: immutil is used > +// The first 4 parameters are the same as for > immutil_saImmOiRtObjectCreate_2 > +// The last parameter is the same as object name used with > +// immutil_saImmOiRtObjectDelete() > +static SaAisErrorT createRtObject(const SaImmOiHandleT oi_handle, > + const SaImmClassNameT class_name, > + const SaNameT* parent_name, > + const SaImmAttrValuesT_2** > attribute_values, > + const SaNameT *object_name) { > +SaAisErrorT ais_rc = SA_AIS_OK; > + > + for (int i = 0; i <= 2; i++) { > + ais_rc = immutil_saImmOiRtObjectCreate_2(oi_handle, > + class_name, > + parent_name, > + attribute_values); > + if (ais_rc == SA_AIS_ERR_EXIST) { > + SaAisErrorT del_rc = immutil_saImmOiRtObjectDelete(oi_handle, > object_name); > + if (del_rc == SA_AIS_ERR_BAD_HANDLE) { > + LOG_NO("%s: saImmOiRtObjectDelete() Fail, %s", __FUNCTION__, > + saf_error(del_rc)); > + lgsOiCreateBackground(); > + } else if (del_rc != SA_AIS_OK) { > + LOG_NO("%s: saImmOiRtObjectDelete() Fail, %s", __FUNCTION__, > + saf_error(del_rc)); > + break; > + } else { > + // The existing object is deleted. Try again to create a new one > + continue; > + } > + } else if (ais_rc == SA_AIS_ERR_BAD_HANDLE) { > + LOG_NO("%s: saImmOiRtObjectCreate_2() Fail, %s", > + __FUNCTION__, saf_error(ais_rc)); > + lgsOiCreateBackground(); > + break; > + } else { > + break; > + } > + } > + > + // saImmOiRtObjectCreate_2() return code > + return ais_rc; > +} > + > /** > * Create a new rt app stream object. > * > @@ -536,8 +588,9 @@ SaAisErrorT > lgs_create_appstream_rt_object(log_stream_t > *const stream) { > parent_name++; /* FIX, vulnerable for malformed DNs */ > parentName = &parent; > osaf_extended_name_lend(parent_name, &parent); > - } else > + } else { > rdnstr = const_cast<char *>(stream->name.c_str()); > + } > > void *arr1[] = {&rdnstr}; > const SaImmAttrValuesT_2 attr_safLgStr = { > @@ -622,14 +675,20 @@ SaAisErrorT > lgs_create_appstream_rt_object(log_stream_t *const stream) { > &attr_saLogStreamCreationTimestamp, > NULL}; > > - rc = immutil_saImmOiRtObjectCreate_2( > - lgs_cb->immOiHandle, > const_cast<SaImmClassNameT>("SaLogStream"), > - parentName, attrValues); > + SaNameT object_name; > + osaf_extended_name_lend(stream->name.c_str(), &object_name); > + SaImmOiHandleT oi_handle = lgsGetOiHandle(); > + rc = createRtObject(oi_handle, > + const_cast<SaImmClassNameT>("SaLogStream"), > + parentName, > + attrValues, > + &object_name); > free(dndup); > > if (rc != SA_AIS_OK) { > - LOG_WA("saImmOiRtObjectCreate_2 returned %u for %s, parent %s", > rc, > - stream->name.c_str(), parent_name); > + LOG_WA("%s: createRtObject() returned %s for %s, " > + "parent %s", __FUNCTION__, saf_error(rc), > stream->name.c_str(), > + parent_name); > } > } > > -- > 2.16.2
Canh_Lennart_comments_2799.diff
Description: Canh_Lennart_comments_2799.diff
------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________ Opensaf-devel mailing list Opensaf-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/opensaf-devel