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

Reply via email to