An enhancement for IMM to print out 5 last FEVS events into syslog when IMMND down for any reason. --- src/imm/common/immsv_evt.c | 2 +- src/imm/common/immsv_evt.h | 2 + src/imm/immnd/ImmModel.cc | 285 +++++++++++++++++++++++++++++++++++++++++++++ src/imm/immnd/ImmModel.h | 1 + src/imm/immnd/immnd_evt.c | 34 +++++- src/imm/immnd/immnd_init.h | 2 + 6 files changed, 322 insertions(+), 4 deletions(-)
diff --git a/src/imm/common/immsv_evt.c b/src/imm/common/immsv_evt.c index b0e36d3..03a7f81 100644 --- a/src/imm/common/immsv_evt.c +++ b/src/imm/common/immsv_evt.c @@ -189,7 +189,7 @@ static const char *immnd_evt_names[] = { "IMMND_EVT_D2ND_IMPLDELETE", "undefined (high)"}; -static const char *immsv_get_immnd_evt_name(unsigned int id) +const char *immsv_get_immnd_evt_name(unsigned int id) { if (id < IMMND_EVT_MAX) return immnd_evt_names[id]; diff --git a/src/imm/common/immsv_evt.h b/src/imm/common/immsv_evt.h index 3e96c98..a1dabc5 100644 --- a/src/imm/common/immsv_evt.h +++ b/src/imm/common/immsv_evt.h @@ -689,6 +689,8 @@ void immsv_free_attrdefs_list(IMMSV_ATTR_DEF_LIST *adp); void immsv_evt_free_name_list(IMMSV_OBJ_NAME_LIST *p); void immsv_evt_free_ccbOutcomeList(IMMSV_CCB_OUTCOME_LIST *o); +const char *immsv_get_immnd_evt_name(unsigned int id); + #ifdef __cplusplus } #endif diff --git a/src/imm/immnd/ImmModel.cc b/src/imm/immnd/ImmModel.cc index 21f48ab..80fdf84 100644 --- a/src/imm/immnd/ImmModel.cc +++ b/src/imm/immnd/ImmModel.cc @@ -35,6 +35,7 @@ #define PRT_HIGH_THRESHOLD 4 /* See ImmModel::immNotPbeWritable */ #define CCB_CRIT_THRESHOLD 8 /* See ImmModel::immNotPbeWritable */ #define SEARCH_TIMEOUT_SEC 600 /* Search timeout */ +#define MAX_LENGTH_EVT_DATA 256 struct ContinuationInfo2 { ContinuationInfo2() @@ -20171,3 +20172,287 @@ void ImmModel::isolateThisNode(unsigned int thisNode, bool isAtCoord) { immnd_proc_imma_discard_connection() */ } + + +/********************************************************************** + * An enhancement from ticket #2898 to get more info from events + **********************************************************************/ +static std::string getInfoForObjCreate(const ImmsvOmCcbObjectCreate *req) +{ + std::string additionalInfo = ""; + size_t sz = strnlen(req->className.buf, (size_t)req->className.size); + std::string className((const char*)req->className.buf, sz); + + if (className.empty()) { + additionalInfo.append("No info"); + } else { + additionalInfo.append("Create obj of class ").append(className); + } + + return additionalInfo; +} + +static std::string getInfoForObjModify(const ImmsvOmCcbObjectModify* req) +{ + std::string additionalInfo = ""; + size_t sz = strnlen(req->objectName.buf, (size_t)req->objectName.size); + std::string objName((const char*)req->objectName.buf, sz); + + if (objName.empty()) { + additionalInfo.append("No info"); + } else { + additionalInfo.append(objName); + } + + return additionalInfo; +} + +static std::string getInfoForObjDelete(const ImmsvOmCcbObjectDelete* req) +{ + std::string additionalInfo = ""; + size_t sz = strnlen(req->objectName.buf, (size_t)req->objectName.size); + std::string objName((const char*)req->objectName.buf, sz); + + if (objName.empty()) { + additionalInfo.append("No info"); + } else { + additionalInfo.append(objName); + } + + return additionalInfo; +} + +static std::string getInfoForObjSync(const ImmsvOmObjectSync *req) +{ + std::string additionalInfo = ""; + size_t sz = strnlen(req->objectName.buf, (size_t)req->objectName.size); + std::string objName((const char*)req->objectName.buf, sz); + + if (objName.empty()) { + additionalInfo.append("No info"); + } else { + additionalInfo.append(objName); + } + + return additionalInfo; +} + +static std::string getInfoForAdmOp(const ImmsvOmAdminOperationInvoke* req) +{ + std::string additionalInfo = ""; + size_t sz = strnlen(req->objectName.buf, (size_t)req->objectName.size); + std::string objName((const char*)req->objectName.buf, sz); + std::string opId = std::to_string(req->operationId); + + if (objName.empty()) { + additionalInfo.append("No info"); + } else { + additionalInfo.append(objName).append("(opId:").append(opId); + } + + return additionalInfo; +} + +static std::string getInfoForClassDesc(const ImmsvOmClassDescr *req) +{ + std::string additionalInfo = ""; + size_t sz = strnlen((char*)req->className.buf, (size_t)req->className.size); + std::string className((const char*)req->className.buf, sz); + + if (className.empty()) { + additionalInfo.append("No info"); + } else { + additionalInfo.append(className); + } + + return additionalInfo; +} + +static std::string getInfoForAdmInit(const immsv_d2nd_adminit *req) +{ + std::string additionalInfo = ""; + std::string ownerId = std::to_string(req->globalOwnerId); + std::string ownerName = osaf_extended_name_borrow(&(req->i.adminOwnerName)); + + if (ownerId.empty()) { + additionalInfo.append("No info"); + } else { + additionalInfo.append(ownerId).append("(").append(ownerName).append(")"); + } + + return additionalInfo; +} + +static std::string getInfoForImplSet(const ImmsvOiImplSetReq *req, + bool isSet = false) +{ + std::string additionalInfo = ""; + size_t sz = strnlen((const char*)req->impl_name.buf, req->impl_name.size); + std::string clsOrObjName((const char*)req->impl_name.buf, sz); + + if (clsOrObjName.empty()) { + additionalInfo.append("No info"); + } else { + if (isSet) { + additionalInfo.append("Set impl ") + .append(std::to_string(req->impl_id)) + .append(" to ").append(clsOrObjName); + } else { + additionalInfo.append("Release impl ") + .append(std::to_string(req->impl_id)) + .append(" out of ").append(clsOrObjName); + } + } + + return additionalInfo; +} + +static std::string getInfoForSafeReadLock(const ImmsvOmSearchInit *req) +{ + std::string additionalInfo = ""; + std::string ccbId = std::to_string(req->ccbId); + size_t sz = strnlen(req->rootName.buf, (size_t)req->rootName.size); + std::string objName((const char*)req->rootName.buf, sz); + + additionalInfo.append("CCB ").append(ccbId).append(" lock ").append(objName); + return additionalInfo; +} + +void immModel_getEvtData(IMMND_CB *cb, IMMND_EVT *evt, char* evt_data) +{ + std::string additionalInfo = ""; + std::string eventName(immsv_get_immnd_evt_name(evt->type)); + + switch (evt->type) { + case IMMND_EVT_A2ND_OBJ_CREATE: + case IMMND_EVT_A2ND_OBJ_CREATE_2: + case IMMND_EVT_A2ND_OI_OBJ_CREATE: + case IMMND_EVT_A2ND_OI_OBJ_CREATE_2: + additionalInfo = getInfoForObjCreate(&(evt->info.objCreate)); + break; + + case IMMND_EVT_A2ND_OBJ_MODIFY: + case IMMND_EVT_A2ND_OI_OBJ_MODIFY: + additionalInfo = getInfoForObjModify(&(evt->info.objModify)); + break; + + case IMMND_EVT_A2ND_OBJ_DELETE: + case IMMND_EVT_A2ND_OI_OBJ_DELETE: + additionalInfo = getInfoForObjDelete(&(evt->info.objDelete)); + break; + + case IMMND_EVT_A2ND_OBJ_SYNC: + case IMMND_EVT_A2ND_OBJ_SYNC_2: + additionalInfo = getInfoForObjSync(&(evt->info.obj_sync)); + break; + + case IMMND_EVT_A2ND_IMM_ADMOP: + case IMMND_EVT_A2ND_IMM_ADMOP_ASYNC: + additionalInfo = getInfoForAdmOp(&(evt->info.admOpReq)); + break; + + case IMMND_EVT_A2ND_CLASS_CREATE: + case IMMND_EVT_A2ND_CLASS_DELETE: + additionalInfo = getInfoForClassDesc(&(evt->info.classDescr)); + break; + + case IMMND_EVT_D2ND_DISCARD_IMPL: + case IMMND_EVT_D2ND_IMPLSET_RSP: + case IMMND_EVT_D2ND_IMPLSET_RSP_2: + case IMMND_EVT_A2ND_OI_IMPL_CLR: + additionalInfo.append("impl_id:") + .append(std::to_string(evt->info.implSet.impl_id)); + break; + + case IMMND_EVT_D2ND_ADMINIT: + additionalInfo = getInfoForAdmInit(&(evt->info.adminitGlobal)); + break; + + case IMMND_EVT_D2ND_CCBINIT: + additionalInfo.append("ccbId:") + .append(std::to_string(evt->info.ccbinitGlobal.globalCcbId)); + break; + + case IMMND_EVT_A2ND_AUG_ADMO: + additionalInfo.append("Add admo_id ") + .append(std::to_string(evt->info.objDelete.adminOwnerId)) + .append(" to CCB ") + .append(std::to_string(evt->info.objDelete.ccbId)); + break; + + case IMMND_EVT_A2ND_OI_CL_IMPL_SET: + case IMMND_EVT_A2ND_OI_OBJ_IMPL_SET: + additionalInfo = getInfoForImplSet(&(evt->info.implSet), true); + break; + + case IMMND_EVT_A2ND_OI_CL_IMPL_REL: + case IMMND_EVT_A2ND_OI_OBJ_IMPL_REL: + additionalInfo = getInfoForImplSet(&(evt->info.implSet)); + break; + + case IMMND_EVT_A2ND_ADMO_FINALIZE: + case IMMND_EVT_D2ND_ADMO_HARD_FINALIZE: + case IMMND_EVT_A2ND_ADMO_SET: + case IMMND_EVT_A2ND_ADMO_RELEASE: + case IMMND_EVT_A2ND_ADMO_CLEAR: + additionalInfo.append("admo_id:") + .append(std::to_string(evt->info.admFinReq.adm_owner_id)); + break; + + case IMMND_EVT_A2ND_OI_CCB_AUG_INIT: + case IMMND_EVT_A2ND_CCB_COMPLETED_RSP: + case IMMND_EVT_A2ND_CCB_COMPLETED_RSP_2: + case IMMND_EVT_A2ND_CCB_OBJ_CREATE_RSP: + case IMMND_EVT_A2ND_CCB_OBJ_CREATE_RSP_2: + case IMMND_EVT_A2ND_CCB_OBJ_MODIFY_RSP: + case IMMND_EVT_A2ND_CCB_OBJ_MODIFY_RSP_2: + case IMMND_EVT_A2ND_CCB_OBJ_DELETE_RSP: + case IMMND_EVT_A2ND_CCB_OBJ_DELETE_RSP_2: + additionalInfo.append("ccbId:") + .append(std::to_string(evt->info.ccbUpcallRsp.ccbId)); + break; + + case IMMND_EVT_A2ND_CCB_APPLY: + case IMMND_EVT_A2ND_CCB_VALIDATE: + case IMMND_EVT_A2ND_CCB_FINALIZE: + case IMMND_EVT_D2ND_ABORT_CCB: + additionalInfo.append("ccbId:") + .append(std::to_string(evt->info.ccbId)); + break; + + case IMMND_EVT_A2ND_PBE_ADMOP_RSP: + additionalInfo.append("admop result:") + .append(std::to_string(evt->info.admOpRsp.result)); + break; + + case IMMND_EVT_D2ND_SYNC_FEVS_BASE: + additionalInfo.append("sync fevs base:") + .append(std::to_string(evt->info.syncFevsBase)); + break; + + case IMMND_EVT_A2ND_OBJ_SAFE_READ: + additionalInfo = getInfoForSafeReadLock(&(evt->info.searchInit)); + break; + + case IMMND_EVT_D2ND_IMPLDELETE: + additionalInfo.append("Delete ") + .append(std::to_string(evt->info.impl_delete.size)) + .append(" implementer(s)."); + break; + + case IMMND_EVT_D2ND_DISCARD_NODE: + additionalInfo.append("nodeId: ") + .append(std::to_string(evt->info.ctrl.nodeId)); + break; + default: + additionalInfo = ""; + break; + } + + if (additionalInfo.empty()) { + snprintf(evt_data, MAX_LENGTH_EVT_DATA, "%s", eventName.c_str()); + } else { + snprintf(evt_data, MAX_LENGTH_EVT_DATA, + "%s -> %s", eventName.c_str(), additionalInfo.c_str()); + } +} diff --git a/src/imm/immnd/ImmModel.h b/src/imm/immnd/ImmModel.h index c8b0f4e..23b3692 100644 --- a/src/imm/immnd/ImmModel.h +++ b/src/imm/immnd/ImmModel.h @@ -60,6 +60,7 @@ struct ImmOiRtObjectCreate; struct immsv_oi_ccb_upcall_rsp; struct immsv_attr_values_list; struct immsv_attr_mods_list; +struct immsv_d2nd_adminit; struct ImmsvOmRspSearchNext; diff --git a/src/imm/immnd/immnd_evt.c b/src/imm/immnd/immnd_evt.c index 730c490..db94036 100644 --- a/src/imm/immnd/immnd_evt.c +++ b/src/imm/immnd/immnd_evt.c @@ -39,6 +39,20 @@ #define IMMND_SEARCH_BUNDLE_SIZE ((MDS_DIRECT_BUF_MAXSIZE / 100) * 90) #define IMMND_MAX_SEARCH_RESULT (IMMND_SEARCH_BUNDLE_SIZE / 300) +#define MAX_INDEX_FEVS_MSG 5 +#define MAX_LENGTH_FEVS_MSG 256 + +static char latest_fevs[MAX_INDEX_FEVS_MSG][MAX_LENGTH_FEVS_MSG] = { + "(none)", "(none)", "(none)", "(none)", "(none)" +}; + +static void syslog_recent_fevs() +{ + for (int i = 0; i < MAX_INDEX_FEVS_MSG; i++) { + LOG_NO("Recent fevs: %s", latest_fevs[i]); + } +} + static SaAisErrorT immnd_fevs_local_checks(IMMND_CB *cb, IMMSV_FEVS *fevsReq, const IMMSV_SEND_INFO *sinfo); static uint32_t immnd_evt_proc_cb_dump(IMMND_CB *cb); @@ -9601,7 +9615,8 @@ static uint32_t immnd_restricted_ok(IMMND_CB *cb, uint32_t id) static SaAisErrorT immnd_evt_proc_fevs_dispatch(IMMND_CB *cb, IMMSV_OCTET_STRING *msg, bool originatedAtThisNd, SaImmHandleT clnt_hdl, - MDS_DEST reply_dest, SaUint64T msgNo) + MDS_DEST reply_dest, SaUint64T msgNo, + char* evt_data) { SaAisErrorT error = SA_AIS_OK; IMMSV_EVT frwrd_evt; @@ -9665,7 +9680,7 @@ immnd_evt_proc_fevs_dispatch(IMMND_CB *cb, IMMSV_OCTET_STRING *msg, /*Dispatch the unpacked FEVS message */ immsv_msg_trace_rec(frwrd_evt.sinfo.dest, &frwrd_evt); - + immModel_getEvtData(immnd_cb, &frwrd_evt.info.immnd, evt_data); switch (frwrd_evt.info.immnd.type) { case IMMND_EVT_A2ND_OBJ_CREATE: case IMMND_EVT_A2ND_OBJ_CREATE_2: @@ -10735,7 +10750,11 @@ static uint32_t immnd_evt_proc_fevs_rcv(IMMND_CB *cb, IMMND_EVT *evt, bool isObjSync = (evt->type == IMMND_EVT_D2ND_GLOB_FEVS_REQ_2) ? evt->info.fevsReq.isObjSync : false; + static int index = 0; + char evt_data[MAX_LENGTH_FEVS_MSG]; + TRACE_ENTER(); + memset(evt_data, 0, sizeof(evt_data)); if (cb->highestProcessed >= msgNo) { /*We have already received this message, discard it. */ @@ -10784,6 +10803,7 @@ static uint32_t immnd_evt_proc_fevs_rcv(IMMND_CB *cb, IMMND_EVT *evt, LOG_ER( "MESSAGE:%llu OUT OF ORDER my highest processed:%llu - exiting", msgNo, cb->highestProcessed); + syslog_recent_fevs(); immnd_ackToNid(NCSCC_RC_FAILURE); exit(1); } else if (cb @@ -10792,6 +10812,7 @@ static uint32_t immnd_evt_proc_fevs_rcv(IMMND_CB *cb, IMMND_EVT *evt, LOG_ER( "Sync MESSAGE:%llu OUT OF ORDER my highest processed:%llu - exiting", msgNo, cb->highestProcessed); + syslog_recent_fevs(); immnd_ackToNid(NCSCC_RC_FAILURE); exit(1); } else if (cb->mState < IMM_SERVER_LOADING_PENDING) { @@ -10816,7 +10837,8 @@ static uint32_t immnd_evt_proc_fevs_rcv(IMMND_CB *cb, IMMND_EVT *evt, TRACE("Coord discards object sync message"); } else { err = immnd_evt_proc_fevs_dispatch(cb, msg, originatedAtThisNd, - clnt_hdl, reply_dest, msgNo); + clnt_hdl, reply_dest, + msgNo, evt_data); } if (err != SA_AIS_OK) { @@ -10826,7 +10848,11 @@ static uint32_t immnd_evt_proc_fevs_rcv(IMMND_CB *cb, IMMND_EVT *evt, LOG_ER("PROBLEM %u WITH msg no:%llu", err, msgNo); } } + memset(latest_fevs[index], 0, MAX_LENGTH_FEVS_MSG); + snprintf(latest_fevs[index], MAX_LENGTH_FEVS_MSG, + "<%llu>[%s]", msgNo, evt_data); + if (++index > MAX_INDEX_FEVS_MSG - 1) index = 0; done: cb->highestProcessed++; dequeue_outgoing(cb); @@ -10912,6 +10938,8 @@ static void immnd_evt_proc_discard_node(IMMND_CB *cb, IMMND_EVT *evt, cb->node_id); exit(1); } + + syslog_recent_fevs(); LOG_NO("Global discard node received for nodeId:%x pid:%u", evt->info.ctrl.nodeId, evt->info.ctrl.ndExecPid); /* We should remember the nodeId/pid pair to avoid a redundant message diff --git a/src/imm/immnd/immnd_init.h b/src/imm/immnd/immnd_init.h index 1d0126e..b626df9 100644 --- a/src/imm/immnd/immnd_init.h +++ b/src/imm/immnd/immnd_init.h @@ -485,6 +485,8 @@ void immModel_sendSyncAbortAt(IMMND_CB *cb, struct timespec time); void immModel_getSyncAbortRsp(IMMND_CB *cb); +void immModel_getEvtData(IMMND_CB *cb, IMMND_EVT *evt, char* evt_data); + bool is_regular_name(const char* name, bool strict); bool is_valid_schema_name(const char* name); -- 2.7.4 ------------------------------------------------------------------------------ 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