Hi Zoran,

Please see inline comments below.

Best Regards,

Hùng Nguyễn - DEK Technologies




------------------------------------------------------------------------

*From:* Zoran Milinkovic
*Sent:* Wednesday, September 16, 2015 9:28PM
*To:* Neelakanta Reddy
*Cc:* Opensaf-devel
*Subject:* [devel] [PATCH 1 of 1] imm: classify abort error strings and 
prefix existing error strings [#744]

  osaf/services/saf/immsv/immnd/ImmModel.cc  |  129 +++++++++++++++++++++++-----
  osaf/services/saf/immsv/immnd/ImmModel.hh  |    5 +
  osaf/services/saf/immsv/immnd/immnd_evt.c  |  125 ++++++++++++++++++++++++++-
  osaf/services/saf/immsv/immnd/immnd_init.h |    6 +
  4 files changed, 232 insertions(+), 33 deletions(-)


The patch set prefix "IMM:" to all error string that come from IMM.
Based on CCB abort type (resource or validation abort), error strings are 
prefixed with "IMM: Resource abort:" or "IMM: Validation abort:"

diff --git a/osaf/services/saf/immsv/immnd/ImmModel.cc 
b/osaf/services/saf/immsv/immnd/ImmModel.cc
--- a/osaf/services/saf/immsv/immnd/ImmModel.cc
+++ b/osaf/services/saf/immsv/immnd/ImmModel.cc
@@ -35,6 +35,9 @@
  #define CCB_CRIT_THRESHOLD 8 /* See ImmModel::immNotPbeWritable */
  #define SEARCH_TIMEOUT_SEC 600 /* Search timeout */
  
+// Same strings exists in immnd_evt.c
+#define IMM_VALIDATION_ABORT   "IMM: Validation abort: "
+#define IMM_RESOURCE_ABORT             "IMM: Resource abort: "
  
  struct ContinuationInfo2
  {
@@ -2145,6 +2148,23 @@ immModel_resourceDisplay(IMMND_CB *cb,
          resourceDisplay(reqparams, rparams, searchcount);
  }
  
+void
+immModel_setCcbErrorString(IMMND_CB *cb, SaUint32T ccbId, const char 
*errorString, ...) {
+    CcbVector::iterator cvi;
+    va_list vl;
+
+    cvi = std::find_if(sCcbVector.begin(), sCcbVector.end(), CcbIdIs(ccbId));
+    if (cvi == sCcbVector.end()) {
+        /* Cannot find CCB. Error string will be ignored.
+         * This case should never happen. */
+        return;
+    }
+
+    va_start(vl, errorString);
+    ImmModel::instance(&cb->immModel)->setCcbErrorString(*cvi, errorString, 
vl);
+    va_end(vl);
+}
+
  /*====================================================================*/
  
  ImmModel::ImmModel() :
@@ -5019,6 +5039,8 @@ ImmModel::ccbApply(SaUint32T ccbId,
              LOG_NO("ERR_BAD_HANDLE: Admin owner id %u does not exist",
                  ccb->mAdminOwnerId);
              ccb->mVeto = SA_AIS_ERR_BAD_HANDLE;
+            /* Later in the code, error code will be set to 
SA_AIS_ERR_FAILED_OPERATION */
+            setCcbErrorString(ccb, IMM_RESOURCE_ABORT "Admin owner does not 
exist");
          } else if(ccb->mState > IMM_CCB_READY) {
              if(ccb->mState == IMM_CCB_VALIDATING) {
                  LOG_IN("Ccb <%u> in incorrect state 'CCB_VALIDATING for "
@@ -5040,6 +5062,8 @@ ImmModel::ccbApply(SaUint32T ccbId,
                              /* apply callback needs to be sent to 
implementers. */
                             err = SA_AIS_ERR_INTERRUPT;
                          }
+                    } else if(err == SA_AIS_ERR_FAILED_OPERATION) {
+                        setCcbErrorString(ccb, IMM_VALIDATION_ABORT "Completed 
validation failed");
                      }
                      goto done;
                 }
@@ -5070,9 +5094,11 @@ ImmModel::ccbApply(SaUint32T ccbId,
              }
              err = SA_AIS_ERR_FAILED_OPERATION;
              ccb->mVeto = SA_AIS_ERR_FAILED_OPERATION;
+            setCcbErrorString(ccb, IMM_VALIDATION_ABORT "Parent is missing");
          } else if(!validateNoDanglingRefs(ccb)) {
              err = SA_AIS_ERR_FAILED_OPERATION;
              ccb->mVeto = SA_AIS_ERR_FAILED_OPERATION;
+            setCcbErrorString(ccb, IMM_VALIDATION_ABORT "No dangling 
validation failed");
          } else {
              /* sMissingParents must be empty if err is SA_AIS_OK */
              osafassert(sMissingParents.empty());
@@ -5111,6 +5137,8 @@ ImmModel::ccbApply(SaUint32T ccbId,
                          "refusing apply", impInfo->mImplementerName.c_str());
                      err = SA_AIS_ERR_FAILED_OPERATION;
                      ccb->mVeto = SA_AIS_ERR_FAILED_OPERATION;
+                    setCcbErrorString(ccb,
+                            IMM_RESOURCE_ABORT "Lost connection with 
implementer");
                      break;
                  }
                  //Wait for ack, possibly remote
@@ -5699,7 +5727,7 @@ ImmModel::ccbAbort(SaUint32T ccbId, Conn
             not really any error at all, but mVeto should not be SA_AIS_OK.
          */
          ccb->mVeto = SA_AIS_ERR_NO_RESOURCES;
-        setCcbErrorString(ccb, "Resource Error: CCB abort due to either "
+        setCcbErrorString(ccb, IMM_RESOURCE_ABORT "CCB abort due to either "
              "OI timeout or explicit abort request.");
      }
  
@@ -6087,6 +6115,7 @@ ImmModel::ccbAugmentInit(immsv_oi_ccb_up
             rsp->inv, ccbId);
          if(ccb->mVeto == SA_AIS_OK) {
              ccb->mVeto = SA_AIS_ERR_FAILED_OPERATION;
+            /* Note: This error code is returned to OI. Parent CCB is aborted 
*/
              err = SA_AIS_ERR_BAD_OPERATION;
          }
          goto done;
@@ -6108,6 +6137,7 @@ ImmModel::ccbAugmentInit(immsv_oi_ccb_up
          TRACE("Ccb %u is already in an error state %u, can not accept 
augmentation",
               ccbId, ccb->mVeto);
          err = SA_AIS_ERR_FAILED_OPERATION; /*ccb->mVeto;*/
+        setCcbErrorString(ccb, IMM_RESOURCE_ABORT "CCB is in an error state");
          goto done;
      }
  
@@ -6860,6 +6890,7 @@ SaAisErrorT ImmModel::ccbObjectCreate(Im
          LOG_NO("ERR_FAILED_OPERATION: ccb %u is in an error state "
              "rejecting ccbObjectCreate operation ", ccbId);
          err = SA_AIS_ERR_FAILED_OPERATION;
+        setCcbErrorString(ccb, IMM_RESOURCE_ABORT "CCB is in an error state");
          goto ccbObjectCreateExit;
      }
  
@@ -6867,6 +6898,7 @@ SaAisErrorT ImmModel::ccbObjectCreate(Im
          LOG_NO("ERR_FAILED_OPERATION: ccb %u is not in an expected state:%u "
              "rejecting ccbObjectCreate operation ", ccbId, ccb->mState);
          err = SA_AIS_ERR_FAILED_OPERATION;
+        setCcbErrorString(ccb, IMM_RESOURCE_ABORT "CCB is not in an expected 
state");
          goto ccbObjectCreateExit;
      }
  
@@ -6896,13 +6928,14 @@ SaAisErrorT ImmModel::ccbObjectCreate(Im
              LOG_WA("ERR_FAILED_OPERATION: Inconsistency between Ccb admoId:%u 
and AdminOwner-id:%u",
                  adminOwner->mId, ccb->mAdminOwnerId);
              err = SA_AIS_ERR_FAILED_OPERATION;
+            setCcbErrorString(ccb, IMM_RESOURCE_ABORT "Inconsistency between 
CCB and AdminOwner");
              goto ccbObjectCreateExit;
          }
      }
  
      if (i3 == sClassMap.end()) {
          TRACE_7("ERR_NOT_EXIST: class '%s' does not exist", 
className.c_str());
-        setCcbErrorString(ccb, "ERR_NOT_EXIST: class '%s' does not exist", 
className.c_str());
+        setCcbErrorString(ccb, "IMM: ERR_NOT_EXIST: class '%s' does not 
exist", className.c_str());
          err = SA_AIS_ERR_NOT_EXIST;
          goto ccbObjectCreateExit;
      } else if(sPbeRtMutations.find(className) != sPbeRtMutations.end()) {
@@ -6998,6 +7031,9 @@ SaAisErrorT ImmModel::ccbObjectCreate(Im
      if (i4 == classInfo->mAttrMap.end()) {
          LOG_WA("ERR_FAILED_OPERATION: No RDN attribute found in class!");
          err = SA_AIS_ERR_FAILED_OPERATION;     //Should never happen!
+        // Here IMMND should assert ??? It cannot happen that class does not 
have RDN.
+        // This could happen due to memory corruption or heap overflow
+        setCcbErrorString(ccb, IMM_RESOURCE_ABORT "No RDN found in a class");
          goto ccbObjectCreateExit;
      }
  
@@ -7229,7 +7265,7 @@ SaAisErrorT ImmModel::ccbObjectCreate(Im
              
              if (i6 == object->mAttrValueMap.end()) {
                  TRACE_7("ERR_NOT_EXIST: attr '%s' not defined", 
attrName.c_str());
-                setCcbErrorString(ccb, "ERR_NOT_EXIST: attr '%s' not defined",
+                setCcbErrorString(ccb, "IMM: ERR_NOT_EXIST: attr '%s' not 
defined",
                          attrName.c_str());
                  err = SA_AIS_ERR_NOT_EXIST;
                  break; //out of for-loop
@@ -7530,6 +7566,7 @@ SaAisErrorT ImmModel::ccbObjectCreate(Im
                      ccb->mVeto = err;
                      LOG_WA("ERR_FAILED_OPERATION: Persistent back end is down 
"
                             "ccb %u is aborted", ccbId);
+                    setCcbErrorString(ccb, IMM_RESOURCE_ABORT "PBE is down");
                  } else {
                      /* Pristine ccb can not start because PBE down */
                      TRACE_5("ERR_TRY_AGAIN: Persistent back end is down");
@@ -7611,7 +7648,7 @@ SaAisErrorT ImmModel::ccbObjectCreate(Im
                      }
                  } else {
                      setCcbErrorString(ccb,
-                        "ERR_BAD_OPERATION: Imm not allowing creates of 
instances of class '%s'",
+                        "IMM: ERR_BAD_OPERATION: Imm not allowing creates of 
instances of class '%s'",
                          immMngtClass.c_str());
                      err = SA_AIS_ERR_BAD_OPERATION;
                  }
@@ -7629,10 +7666,12 @@ SaAisErrorT ImmModel::ccbObjectCreate(Im
                                      "but attribute 'longDnsAllowed' is not 
defined in class %s",
                                      immClassName.c_str());
                              err = SA_AIS_ERR_FAILED_OPERATION;
+                            setCcbErrorString(ccb, IMM_RESOURCE_ABORT "Long DN 
is used, but attribute longDnsAllowed in not defined");
                          } else if(!i6->second->getValue_int()) {
                              LOG_WA("ERR_FAILED_OPERATION: Long DN is used 
during the loading initial data, "
                                      "but longDnsAllowed is set to 0");
                              err = SA_AIS_ERR_FAILED_OPERATION;
+                            setCcbErrorString(ccb, IMM_RESOURCE_ABORT "Long DN 
is used when longDnsAllowed is set to 0");
                          }
                      } else {
                          /* 'else' branch is not needed. Only for small 
performance issue.
@@ -7644,7 +7683,7 @@ SaAisErrorT ImmModel::ccbObjectCreate(Im
                      }
                  } else {
                      setCcbErrorString(ccb,
-                        "ERR_BAD_OPERATION: Imm not allowing creates of 
instances of class '%s'",
+                        "IMM: ERR_BAD_OPERATION: Imm not allowing creates of 
instances of class '%s'",
                          immClassName.c_str());
                      err = SA_AIS_ERR_BAD_OPERATION;
                  }
@@ -7658,7 +7697,7 @@ SaAisErrorT ImmModel::ccbObjectCreate(Im
                          "implementer and flag SA_IMM_CCB_REGISTERED_OI is 
set",
                          className.c_str());
                      setCcbErrorString(ccb,
-                            "ERR_NOT_EXIST: class '%s' does not have an "
+                            "IMM: ERR_NOT_EXIST: class '%s' does not have an "
                              "implementer and flag SA_IMM_CCB_REGISTERED_OI is 
set",
                              className.c_str());
                      err = SA_AIS_ERR_NOT_EXIST;
@@ -7987,6 +8026,7 @@ ImmModel::ccbObjectModify(const ImmsvOmC
          LOG_NO("ERR_FAILED_OPERATION: ccb %u is in an error state "
              "rejecting ccbObjectModify operation ", ccbId);
          err = SA_AIS_ERR_FAILED_OPERATION;
+        setCcbErrorString(ccb, IMM_RESOURCE_ABORT "CCB is in an error state");
          goto ccbObjectModifyExit;
      }
      
@@ -7994,6 +8034,7 @@ ImmModel::ccbObjectModify(const ImmsvOmC
          LOG_WA("ERR_FAILED_OPERATION: ccb %u is not in an expected state: %u "
              "rejecting ccbObjectModify operation ", ccbId, ccb->mState);
          err = SA_AIS_ERR_FAILED_OPERATION;
+        setCcbErrorString(ccb, IMM_RESOURCE_ABORT "CCB is not in an expected 
state");
          goto ccbObjectModifyExit;
      }
      
@@ -8012,6 +8053,7 @@ ImmModel::ccbObjectModify(const ImmsvOmC
          LOG_WA("ERR_FAILED_OPERATION: Inconsistency between Ccb-admoId:%u and 
"
              "AdminOwnerId:%u", adminOwner->mId, ccb->mAdminOwnerId);
          err = SA_AIS_ERR_FAILED_OPERATION;
+        setCcbErrorString(ccb, IMM_RESOURCE_ABORT "Inconsistency between CCB 
and AdminOwner");
          goto ccbObjectModifyExit;
      }
      
@@ -8157,7 +8199,7 @@ ImmModel::ccbObjectModify(const ImmsvOmC
              TRACE_7("ERR_BAD_OPERATION: attr '%s' in IMM object %s is not 
supported",
                  attrName.c_str(), objectName.c_str());
              setCcbErrorString(ccb,
-                "ERR_BAD_OPERATION: attr '%s' in IMM object %s is not 
supported",
+                "IMM: ERR_BAD_OPERATION: attr '%s' in IMM object %s is not 
supported",
                  attrName.c_str(), objectName.c_str());
              err = SA_AIS_ERR_BAD_OPERATION;
              break; //out of for-loop
@@ -8167,14 +8209,14 @@ ImmModel::ccbObjectModify(const ImmsvOmC
              /* ENABLE_PBE defined in immnd.h */
              LOG_NO("ERR_BAD_OPERATION:  imm has not been built with 
--enable-imm-pbe");
              setCcbErrorString(ccb,
-                "ERR_BAD_OPERATION:  imm has not been built with 
--enable-imm-pbe");
+                "IMM: ERR_BAD_OPERATION:  imm has not been built with 
--enable-imm-pbe");
              err = SA_AIS_ERR_BAD_OPERATION;
              break;
          }
          
          if(modifiedRim && !pbeFile) {
              LOG_NO("ERR_BAD_OPERATION: PBE file is not configured");
-            setCcbErrorString(ccb, "ERR_BAD_OPERATION: PBE file is not 
configured");
+            setCcbErrorString(ccb, "IMM: ERR_BAD_OPERATION: PBE file is not 
configured");
              err = SA_AIS_ERR_BAD_OPERATION;
              break;
          }
@@ -8184,7 +8226,7 @@ ImmModel::ccbObjectModify(const ImmsvOmC
              TRACE_7("ERR_NOT_EXIST: attr '%s' does not exist in object %s",
                  attrName.c_str(), objectName.c_str());
              setCcbErrorString(ccb,
-                "ERR_NOT_EXIST: attr '%s' does not exist in object %s",
+                "IMM: ERR_NOT_EXIST: attr '%s' does not exist in object %s",
                  attrName.c_str(), objectName.c_str());
              err = SA_AIS_ERR_NOT_EXIST;
              break; //out of for-loop
@@ -8366,7 +8408,7 @@ ImmModel::ccbObjectModify(const ImmsvOmC
                          TRACE_7("ERR_BAD_OPERATION: attr '%s' in IMM object 
%s can not have value %u",
                              attrName.c_str(), objectName.c_str(), newRim);
                          setCcbErrorString(ccb,
-                            "ERR_BAD_OPERATION: attr '%s' in IMM object %s can 
not have value %u",
+                            "IMM: ERR_BAD_OPERATION: attr '%s' in IMM object 
%s can not have value %u",
                              attrName.c_str(), objectName.c_str(), newRim);
                          err = SA_AIS_ERR_BAD_OPERATION;
                          break;
@@ -8429,7 +8471,7 @@ ImmModel::ccbObjectModify(const ImmsvOmC
                      TRACE_7("ERR_BAD_OPERATION: attr '%s' in IMM object %s 
must not be empty",
                          attrName.c_str(), objectName.c_str());
                      setCcbErrorString(ccb,
-                        "ERR_BAD_OPERATION: attr '%s' in IMM object %s must 
not be empty",
+                        "IMM: ERR_BAD_OPERATION: attr '%s' in IMM object %s 
must not be empty",
                          attrName.c_str(), objectName.c_str());
                      err = SA_AIS_ERR_BAD_OPERATION;
                      break;
@@ -8496,6 +8538,7 @@ ImmModel::ccbObjectModify(const ImmsvOmC
                  ccb->mVeto = err;
                  LOG_WA("ERR_FAILED_OPERATION: Persistent back end is down "
                         "ccb %u is aborted", ccbId);
+                setCcbErrorString(ccb, IMM_RESOURCE_ABORT "PBE is down");
              } else {
                  /* Pristine ccb can not start because PBE down */
                  TRACE_5("ERR_TRY_AGAIN: Persistent back end is down");
@@ -8653,9 +8696,9 @@ ImmModel::ccbObjectModify(const ImmsvOmC
              if(longDnsPermitted != longDnsAllowedAfter) {
                  if(ccbIdLongDnGuard) {
                      /* This case should never happen since it is guarded by 
regular ccb handling. */
-                    setCcbErrorString(ccb, "ERR_BUSY: Other Ccb (%u) already 
using %s",
+                    setCcbErrorString(ccb, "IMM: ERR_BUSY: Other Ccb (%u) 
already using %s",
                          ccbIdLongDnGuard, immLongDnsAllowed.c_str());
-                    LOG_IN("ERR_BUSY: Other Ccb (%u) already using %s",
+                    LOG_IN("IMM: ERR_BUSY: Other Ccb (%u) already using %s",
                          ccbIdLongDnGuard, immLongDnsAllowed.c_str());
                      err = SA_AIS_ERR_BUSY;
                  } else {
@@ -8767,6 +8810,7 @@ ImmModel::ccbObjectModify(const ImmsvOmC
                      err = SA_AIS_ERR_FAILED_OPERATION;
                      //Let the timeout handling take care of it on other nodes.
                      //This really needs to be tested! But how ?
+                    setCcbErrorString(ccb, IMM_RESOURCE_ABORT "Lost connection 
with implementer");
                  } else {
                      *continuationId = sLastContinuationId;
                  }
@@ -8788,7 +8832,7 @@ ImmModel::ccbObjectModify(const ImmsvOmC
                      "implementer and flag SA_IMM_CCB_REGISTERED_OI is set",
                      objectName.c_str());
                  setCcbErrorString(ccb,
-                        "ERR_NOT_EXIST: object '%s' exist but "
+                        "IMM: ERR_NOT_EXIST: object '%s' exist but "
                          "no implementer (which is required)",
                          objectName.c_str());
                  err = SA_AIS_ERR_NOT_EXIST;
@@ -8825,6 +8869,7 @@ ImmModel::ccbObjectModify(const ImmsvOmC
          if(chainedOp) {
              err = SA_AIS_ERR_FAILED_OPERATION;
              ccb->mVeto = err; //Corrupted chain => corrupted ccb
+            setCcbErrorString(ccb, IMM_RESOURCE_ABORT "Corrupted CCB");
          } else { //First op on this object => ccb can survive
              if(afim) {
                  //Delete the cloned afim.
@@ -8930,6 +8975,7 @@ ImmModel::ccbObjectDelete(const ImmsvOmC
          LOG_NO("ERR_FAILED_OPERATION: ccb %u is in an error state "
              "rejecting ccbObjectDelete operation ", ccbId);
          err = SA_AIS_ERR_FAILED_OPERATION;
+        setCcbErrorString(ccb, IMM_RESOURCE_ABORT "CCB in error state");
          goto ccbObjectDeleteExit;
      }
      
@@ -8937,6 +8983,7 @@ ImmModel::ccbObjectDelete(const ImmsvOmC
          LOG_WA("ERR_FAILED_OPERATION: ccb %u is not in an expected state:%u "
              "rejecting ccbObjectDelete operation ", ccbId, ccb->mState);
          err = SA_AIS_ERR_FAILED_OPERATION;
+        setCcbErrorString(ccb, IMM_RESOURCE_ABORT "CCB is not in an expected 
state");
          goto ccbObjectDeleteExit;
      }
      
@@ -8960,6 +9007,7 @@ ImmModel::ccbObjectDelete(const ImmsvOmC
      if(adminOwner->mId !=  ccb->mAdminOwnerId) {
          LOG_WA("ERR_FAILED_OPERATION: Inconsistency between Ccb and 
AdminOwner");
          err = SA_AIS_ERR_FAILED_OPERATION;
+        setCcbErrorString(ccb, IMM_RESOURCE_ABORT "Inconsistency between CCB 
and AdminOwner");
          goto ccbObjectDeleteExit;
      }
      
@@ -8993,6 +9041,7 @@ ImmModel::ccbObjectDelete(const ImmsvOmC
                  ccb->mVeto = err;
                  LOG_WA("ERR_FAILED_OPERATION: Persistent back end is down "
                         "ccb %u is aborted", ccbId);
+                setCcbErrorString(ccb, IMM_RESOURCE_ABORT "PBE is down");
              } else {
                  /* Pristine ccb can not start because PBE down */
                  TRACE_5("ERR_TRY_AGAIN: Persistent back end is down");
@@ -9213,7 +9262,7 @@ ImmModel::deleteObject(ObjectMap::iterat
          /* Prevent delete of imm service objects, even when there is no OI 
for them */
          if(oi->first == immManagementDn || oi->first == immObjectDn) {
              setCcbErrorString(ccb,
-                "ERR_BAD_OPERATION: Imm not allowing delete of object '%s'",
+                "IMM: ERR_BAD_OPERATION: Imm not allowing delete of object 
'%s'",
                  oi->first.c_str());
              return SA_AIS_ERR_BAD_OPERATION;
          }
@@ -9228,7 +9277,7 @@ ImmModel::deleteObject(ObjectMap::iterat
                      "and flag SA_IMM_CCB_REGISTERED_OI is set",
                      oi->first.c_str());
                  setCcbErrorString(ccb,
-                        "ERR_NOT_EXIST: object '%s' exist but "
+                        "IMM: ERR_NOT_EXIST: object '%s' exist but "
                          "no implementer (which is required)",
                          oi->first.c_str());
                  return SA_AIS_ERR_NOT_EXIST;
@@ -9401,24 +9450,21 @@ ImmModel::deleteObject(ObjectMap::iterat
  }
  
  void
-ImmModel::setCcbErrorString(CcbInfo *ccb, const char *errorString, ...)
-{
+ImmModel::setCcbErrorString(CcbInfo *ccb, const char *errorString, va_list vl) 
{
      int errLen = strlen(errorString) + 1;
      char *fmtError = (char *)malloc(errLen);
      int len;
-    va_list vl;
-
-    va_start(vl, errorString);
-    len = vsnprintf(fmtError, errLen, errorString, vl);
-    va_end(vl);
+    va_list args;
+
+    va_copy(args, vl);
+    len = vsnprintf(fmtError, errLen, errorString, args);
+    va_end(args);
  
      osafassert(len >= 0);
      len++;     /* Reserve one byte for null-terminated sign '\0' */
      if(len > errLen) {
          fmtError = (char *)realloc(fmtError, len);
-        va_start(vl, errorString);
          osafassert(vsnprintf(fmtError, len, errorString, vl) >= 0);
-        va_end(vl);
      }
  
      unsigned int ix=0;
@@ -9448,6 +9494,16 @@ ImmModel::setCcbErrorString(CcbInfo *ccb
      }
  }
  
+void
+ImmModel::setCcbErrorString(CcbInfo *ccb, const char *errorString, ...)
+{
+    va_list vl;
+
+    va_start(vl, errorString);
+    setCcbErrorString(ccb, errorString, vl);
+    va_end(vl);
+}
+
  bool
  ImmModel::hasLocalClassAppliers(ClassInfo* classInfo)
  {
@@ -9488,6 +9544,9 @@ ImmModel::ccbWaitForDeleteImplAck(SaUint
          TRACE_5("CCb %u terminated during ccbObjectDelete processing, "
              "ccb must be aborted", ccbId);
          *err = SA_AIS_ERR_FAILED_OPERATION;
+        if(i1 != sCcbVector.end()) {
+            setCcbErrorString(*i1, IMM_RESOURCE_ABORT "CCB is terminated 
during ccbObjectDelete processing");
+        }
          return false;
      }
      CcbInfo* ccb = *i1;
@@ -9552,6 +9611,9 @@ ImmModel::ccbWaitForCompletedAck(SaUint3
          TRACE_5("Ccb %u terminated during ccbCompleted processing, "
              "ccb must be aborted", ccbId);
          *err = SA_AIS_ERR_FAILED_OPERATION;
+        if(i1 != sCcbVector.end()) {
+            setCcbErrorString(*i1, IMM_RESOURCE_ABORT "CCB is terminated");
+        }
          return false;
      }
      CcbInfo* ccb = *i1;
@@ -9651,6 +9713,7 @@ ImmModel::ccbWaitForCompletedAck(SaUint3
              *err = ccb->mVeto;
              LOG_WA("ERR_FAILED_OPERATION: Persistent back end is down "
                             "ccb %u is aborted", ccbId);
+            setCcbErrorString(ccb, IMM_RESOURCE_ABORT "PBE is down");
          }
      }
  
@@ -9681,6 +9744,7 @@ ImmModel::ccbObjDelContinuation(immsv_oi
          LOG_WA("Not a proper object name: %s", objectName.c_str());
          if(ccb->mVeto == SA_AIS_OK) {
              ccb->mVeto = SA_AIS_ERR_FAILED_OPERATION;
+            setCcbErrorString(ccb, IMM_VALIDATION_ABORT "Not a proper object 
name");
          }
          return;
      }
@@ -9694,6 +9758,7 @@ ImmModel::ccbObjDelContinuation(immsv_oi
              if((rsp->result == SA_AIS_OK) && ccb->isActive()) {
                  LOG_NO("Vetoing ccb %u with ERR_FAILED_OPERATION", ccbId);
                  ccb->mVeto = SA_AIS_ERR_FAILED_OPERATION;
+                setCcbErrorString(ccb, IMM_RESOURCE_ABORT "CCB is interrupted 
in augmentation");
              }
          }
          ccb->mOriginatingConn = ccb->mAugCcbParent->mOriginatingConn;
@@ -9714,6 +9779,7 @@ ImmModel::ccbObjDelContinuation(immsv_oi
              objectName.c_str());
          if(ccb->mVeto == SA_AIS_OK) {
              ccb->mVeto = SA_AIS_ERR_FAILED_OPERATION;
+            setCcbErrorString(ccb, IMM_VALIDATION_ABORT "Object is not found 
in CCB");
          }
      } else {
          osafassert(omuti->second->mWaitForImplAck);
@@ -9731,6 +9797,7 @@ ImmModel::ccbObjDelContinuation(immsv_oi
                      "implementer returned error, Ccb aborted with error: %u",
                       rsp->result);
                  ccb->mVeto = SA_AIS_ERR_FAILED_OPERATION;
+                setCcbErrorString(ccb, IMM_VALIDATION_ABORT "Implementer 
returned error: ", rsp->result);
                  //TODO: This is perhaps more drastic than the specification
                  //demands. We are here aborting the entire Ccb, whereas the 
spec
                  //seems to allow for a non-ok returnvalue from implementer
@@ -9805,6 +9872,7 @@ ImmModel::ccbCompletedContinuation(immsv
              LOG_WA("Completed continuation: implementer '%u' Not found "
                  "in ccb %u aborting ccb", rsp->implId, ccbId);
              ccb->mVeto = SA_AIS_ERR_FAILED_OPERATION;
+            setCcbErrorString(ccb, IMM_RESOURCE_ABORT "Implementer not found");
          } else {
              LOG_WA("Completed continuation: implementer '%u' Not found "
                  "in ccb %u in state(%u), can not abort", rsp->implId,
@@ -9848,17 +9916,20 @@ ImmModel::ccbCompletedContinuation(immsv
                      case SA_AIS_ERR_BAD_OPERATION:
                          LOG_NO("Validation error (BAD_OPERATION) reported by 
implementer '%s', "
                                 "Ccb %u will be aborted", 
ix->second->mImplementer->mImplementerName.c_str(), ccbId);
+                        setCcbErrorString(ccb, IMM_VALIDATION_ABORT "Completed 
validation fails (ERR_BAD_OPERATION)");
                          break;
  
                      case SA_AIS_ERR_NO_MEMORY:
                      case SA_AIS_ERR_NO_RESOURCES:
                             LOG_NO("Resource error %u reported by implementer 
'%s', Ccb %u will be aborted",
                                 rsp->result, 
ix->second->mImplementer->mImplementerName.c_str(), ccbId);
+                           setCcbErrorString(ccb, IMM_VALIDATION_ABORT 
"Completed validation fails (Error code: %u)", rsp->result);
                          break;
  
                     default:
                             LOG_NO("Invalid error reported implementer '%s', 
Ccb %u will be aborted",
                                 
ix->second->mImplementer->mImplementerName.c_str(), ccbId);
+                           setCcbErrorString(ccb, IMM_VALIDATION_ABORT 
"Completed validation fails (Error code: %u)", rsp->result);
                  }
                  ccb->mVeto = SA_AIS_ERR_FAILED_OPERATION;
              }
@@ -9943,6 +10014,7 @@ ImmModel::ccbObjCreateContinuation(SaUin
              invocation, ccbId);
          if(ccb->mVeto == SA_AIS_OK) {
              ccb->mVeto = SA_AIS_ERR_FAILED_OPERATION;
+            setCcbErrorString(ccb, IMM_RESOURCE_ABORT "Create invocation is 
not found in CCB");
          }
      } else {
          osafassert(omuti->second->mWaitForImplAck);
@@ -9959,6 +10031,7 @@ ImmModel::ccbObjCreateContinuation(SaUin
              if((error == SA_AIS_OK) && ccb->isActive()) {
                  LOG_IN("Vetoing ccb %u with ERR_FAILED_OPERATION", ccbId);
                  error = SA_AIS_ERR_FAILED_OPERATION;
+                setCcbErrorString(ccb, IMM_RESOURCE_ABORT "CCB was interrupted 
in augmentation");
              }
          }
          ccb->mOriginatingConn = ccb->mAugCcbParent->mOriginatingConn;
@@ -9978,6 +10051,7 @@ ImmModel::ccbObjCreateContinuation(SaUin
              "implementer returned error, Ccb aborted with error: %u",
              error);
          ccb->mVeto = SA_AIS_ERR_FAILED_OPERATION;
+        setCcbErrorString(ccb, IMM_VALIDATION_ABORT "Implementer returned 
error: %u", error);
          //TODO: This is perhaps more drastic than the specification demands.
          //We are here aborting the entire Ccb, whereas the spec seems to allow
          //for a non-ok returnvalue from implementer (in this callback) to
@@ -10027,6 +10101,7 @@ ImmModel::ccbObjModifyContinuation(SaUin
              invocation, ccbId);
          if(ccb->mVeto == SA_AIS_OK) {
              ccb->mVeto = SA_AIS_ERR_FAILED_OPERATION;
+            setCcbErrorString(ccb, IMM_RESOURCE_ABORT "Modify invocation is 
not found in CCB");
          }
      } else {
          osafassert(omuti->second->mWaitForImplAck);
@@ -10043,6 +10118,7 @@ ImmModel::ccbObjModifyContinuation(SaUin
              if((error == SA_AIS_OK) && ccb->isActive()) {
                  LOG_IN("Vetoing ccb %u with ERR_FAILED_OPERATION", ccbId);
                  error = SA_AIS_ERR_FAILED_OPERATION;
+                setCcbErrorString(ccb, IMM_RESOURCE_ABORT "CCB was interrupted 
in augmentation");
              }
          }
          ccb->mOriginatingConn = ccb->mAugCcbParent->mOriginatingConn;
@@ -10061,6 +10137,7 @@ ImmModel::ccbObjModifyContinuation(SaUin
          LOG_IN("ImmModel::ccbObjModifyContinuation: "
              "implementer returned error, Ccb aborted with error: %u", error);
          ccb->mVeto = SA_AIS_ERR_FAILED_OPERATION;
+        setCcbErrorString(ccb, IMM_VALIDATION_ABORT "Implementer returned 
error: %u", error);
          //TODO: This is perhaps more drastic than the specification demands.
          //We are here aborting the entire Ccb, whereas the spec seems to allow
          //for a non-ok returnvalue from implementer (in this callback) to
diff --git a/osaf/services/saf/immsv/immnd/ImmModel.hh 
b/osaf/services/saf/immsv/immnd/ImmModel.hh
--- a/osaf/services/saf/immsv/immnd/ImmModel.hh
+++ b/osaf/services/saf/immsv/immnd/ImmModel.hh
@@ -273,6 +273,11 @@ public:
      void                setCcbErrorString(
                                            CcbInfo *ccb,
                                            const char *errorString,
+                                          va_list vl);
+
+    void                setCcbErrorString(
+                                          CcbInfo *ccb,
+                                          const char *errorString,
                                            ...);
  
      bool                hasLocalClassAppliers(ClassInfo* classInfo);
diff --git a/osaf/services/saf/immsv/immnd/immnd_evt.c 
b/osaf/services/saf/immsv/immnd/immnd_evt.c
--- a/osaf/services/saf/immsv/immnd/immnd_evt.c
+++ b/osaf/services/saf/immsv/immnd/immnd_evt.c
@@ -38,6 +38,10 @@
  #define IMMND_SEARCH_BUNDLE_SIZE ((MDS_DIRECT_BUF_MAXSIZE / 100) * 90)
  #define IMMND_MAX_SEARCH_RESULT (IMMND_SEARCH_BUNDLE_SIZE / 300)
  
+// Same strings exists in ImmModel.cc
+#define IMM_VALIDATION_ABORT   "IMM: Validation abort: "
+#define IMM_RESOURCE_ABORT             "IMM: Resource abort: "
+
[Hung] Can we expose these macros to saImmOm_A_2_x.h so that 
applications can use them?


  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);
  static uint32_t immnd_evt_proc_imm_init(IMMND_CB *cb, IMMND_EVT *evt, 
IMMSV_SEND_INFO *sinfo, SaBoolT isOm);
@@ -3600,15 +3604,42 @@ static void immnd_evt_proc_ccb_obj_modif
                send_evt.type = IMMSV_EVT_TYPE_IMMA;
                send_evt.info.imma.type = IMMA_EVT_ND2A_IMM_ERROR;
                IMMSV_ATTR_NAME_LIST strList;
+               IMMSV_ATTR_NAME_LIST errStrList = { { 0 }, NULL };
                
                if (evt->info.ccbUpcallRsp.result != SA_AIS_OK) {
-                       evt->info.ccbUpcallRsp.result = 
SA_AIS_ERR_FAILED_OPERATION;
+                       if(evt->info.ccbUpcallRsp.result != 
SA_AIS_ERR_FAILED_OPERATION) {
+                               char buf[2];
+                               int size;
+
+                               /* Create error string */
+                               size = snprintf(buf, 1,
+                                               IMM_RESOURCE_ABORT "Upcall 
failed with error code: %u",
+                                               evt->info.ccbUpcallRsp.result);
+                               osafassert(size >= 0);
+                               errStrList.name.size = ++size;
+                               errStrList.name.buf = (char *)malloc(size);
+                               errStrList.next = NULL;
+                               size = snprintf(errStrList.name.buf, 
errStrList.name.size,
+                                               IMM_RESOURCE_ABORT "Upcall 
failed with error code: %u",
+                                               evt->info.ccbUpcallRsp.result);
+                               osafassert(size >= 0);
+
+                               evt->info.ccbUpcallRsp.result = 
SA_AIS_ERR_FAILED_OPERATION;
+                       }
                        if (evt->info.ccbUpcallRsp.errorString.size) {
                                osafassert(evt->type == 
IMMND_EVT_A2ND_CCB_OBJ_MODIFY_RSP_2);
-                               strList.next = NULL;
+                               if(errStrList.name.buf) {
+                                       strList.next = &errStrList;
+                               } else {
+                                       strList.next = NULL;
+                               }
                                strList.name = 
evt->info.ccbUpcallRsp.errorString;/*borrow*/
                                send_evt.info.imma.info.errRsp.errStrings = 
&(strList);
                                send_evt.info.imma.type = 
IMMA_EVT_ND2A_IMM_ERROR_2;
+                       } else if(errStrList.name.buf) {
+                               osafassert(evt->type == 
IMMND_EVT_A2ND_CCB_OBJ_MODIFY_RSP_2);
+                               send_evt.info.imma.info.errRsp.errStrings = 
&(errStrList);
+                               send_evt.info.imma.type = 
IMMA_EVT_ND2A_IMM_ERROR_2;
                        }
                }
  
@@ -3619,6 +3650,8 @@ static void immnd_evt_proc_ccb_obj_modif
                if (rc != NCSCC_RC_SUCCESS) {
                        LOG_WA("Failed to send response to agent/client over 
MDS rc:%u", rc);
                }
+
+               free(errStrList.name.buf);
        }
  
        TRACE_LEAVE();
@@ -3670,15 +3703,42 @@ static void immnd_evt_proc_ccb_obj_creat
                send_evt.type = IMMSV_EVT_TYPE_IMMA;
                send_evt.info.imma.type = IMMA_EVT_ND2A_IMM_ERROR;
                IMMSV_ATTR_NAME_LIST strList;
+               IMMSV_ATTR_NAME_LIST errStrList = { { 0 }, NULL };
  
                if (evt->info.ccbUpcallRsp.result != SA_AIS_OK) {
-                       evt->info.ccbUpcallRsp.result = 
SA_AIS_ERR_FAILED_OPERATION;
+                       if(evt->info.ccbUpcallRsp.result != 
SA_AIS_ERR_FAILED_OPERATION) {
+                               char buf[2];
+                               int size;
+
+                               /* Create error string */
+                               size = snprintf(buf, 1,
+                                               IMM_RESOURCE_ABORT "Upcall 
failed with error code: %u",
+                                               evt->info.ccbUpcallRsp.result);
+                               osafassert(size >= 0);
+                               errStrList.name.size = ++size;
+                               errStrList.name.buf = (char *)malloc(size);
+                               errStrList.next = NULL;
+                               size = snprintf(errStrList.name.buf, 
errStrList.name.size,
+                                               IMM_RESOURCE_ABORT "Upcall 
failed with error code: %u",
+                                               evt->info.ccbUpcallRsp.result);
+                               osafassert(size >= 0);
+
+                               evt->info.ccbUpcallRsp.result = 
SA_AIS_ERR_FAILED_OPERATION;
+                       }
                        if (evt->info.ccbUpcallRsp.errorString.size) {
                                osafassert(evt->type == 
IMMND_EVT_A2ND_CCB_OBJ_CREATE_RSP_2);
-                               strList.next = NULL;
+                               if(errStrList.name.buf) {
+                                       strList.next = &errStrList;
+                               } else {
+                                       strList.next = NULL;
+                               }
                                strList.name = 
evt->info.ccbUpcallRsp.errorString;/*borrow*/
                                send_evt.info.imma.info.errRsp.errStrings = 
&(strList);
                                send_evt.info.imma.type = 
IMMA_EVT_ND2A_IMM_ERROR_2;
+                       } else if(errStrList.name.buf) {
+                               osafassert(evt->type == 
IMMND_EVT_A2ND_CCB_OBJ_MODIFY_RSP_2);
+                               send_evt.info.imma.info.errRsp.errStrings = 
&(errStrList);
+                               send_evt.info.imma.type = 
IMMA_EVT_ND2A_IMM_ERROR_2;
                        }
                }
  
@@ -3689,6 +3749,8 @@ static void immnd_evt_proc_ccb_obj_creat
                if (rc != NCSCC_RC_SUCCESS) {
                        LOG_WA("Failed to send response to agent/client over 
MDS rc:%u", rc);
                }
+
+               free(errStrList.name.buf);
        }
  
        TRACE_LEAVE();
@@ -4003,11 +4065,11 @@ static void immnd_evt_proc_ccb_compl_rsp
                                err = SA_AIS_OK;
                                validateOnly = true;
                } else {
-                       errStrings = immModel_ccbGrabErrStrings(cb, 
evt->info.ccbUpcallRsp.ccbId);
                        TRACE("Abort in immnd_evt_proc_ccb_compl_rsp reqConn: 
%u", reqConn);
                        /*err != SA_AIS_OK => generate SaImmOiCcbAbortCallbackT 
upcall
                                   for all local implementers involved in the 
Ccb */
                        immnd_evt_ccb_abort(cb, evt->info.ccbUpcallRsp.ccbId, 
NULL, NULL);
+                       errStrings = immModel_ccbGrabErrStrings(cb, 
evt->info.ccbUpcallRsp.ccbId);
                }
                /* Either commit or abort has been decided. Ccb is now done.
                   If we are at originating request node, then we ALWAYS reply 
here.
@@ -5933,6 +5995,8 @@ static void immnd_evt_proc_object_create
                           should prevent any apply to succeed.
                        */
                        err = SA_AIS_ERR_FAILED_OPERATION;
+                       immModel_setCcbErrorString(cb, 
evt->info.objCreate.ccbId,
+                                       IMM_RESOURCE_ABORT "PBE is down");
                        immnd_proc_global_abort_ccb(cb, 
evt->info.objCreate.ccbId);
                } else {
                        memset(&send_evt, '\0', sizeof(IMMSV_EVT));
@@ -5952,6 +6016,8 @@ static void immnd_evt_proc_object_create
                                LOG_ER("Upcall over MDS for ccbObjectCreate "
                                       "to PBE failed! - aborting");
                                err = SA_AIS_ERR_FAILED_OPERATION;
+                               immModel_setCcbErrorString(cb, 
evt->info.objCreate.ccbId,
+                                               IMM_RESOURCE_ABORT "Upcall over 
MDS to PBE failed");
                                immnd_proc_global_abort_ccb(cb, 
evt->info.objCreate.ccbId);
                        }
                        implHandle = 0LL;
@@ -5973,6 +6039,8 @@ static void immnd_evt_proc_object_create
                                LOG_WA("Client died");
                                err = SA_AIS_ERR_FAILED_OPERATION;
                                delayedReply = SA_FALSE;
+                               immModel_setCcbErrorString(cb, 
evt->info.objCreate.ccbId,
+                                               IMM_RESOURCE_ABORT "Client 
died");
                        } else {
                                memset(&send_evt, '\0', sizeof(IMMSV_EVT));
                                send_evt.type = IMMSV_EVT_TYPE_IMMA;
@@ -5992,6 +6060,8 @@ static void immnd_evt_proc_object_create
                                                       
oi_cl_node->agent_mds_dest, &send_evt) != NCSCC_RC_SUCCESS) {
                                        LOG_ER("Agent upcall over MDS for 
ccbObjectCreate failed");
                                        err = SA_AIS_ERR_FAILED_OPERATION;
+                                       immModel_setCcbErrorString(cb, 
evt->info.objCreate.ccbId,
+                                                       IMM_RESOURCE_ABORT 
"Agent upcall over MDS failed");
                                }
                        }
                }
@@ -6164,6 +6234,8 @@ static void immnd_evt_proc_object_modify
                           should prevent any apply to succeed.
                        */
                        err = SA_AIS_ERR_FAILED_OPERATION;
+                       immModel_setCcbErrorString(cb, 
evt->info.objModify.ccbId,
+                                       IMM_RESOURCE_ABORT "PBE is down");
                        immnd_proc_global_abort_ccb(cb, 
evt->info.objModify.ccbId);
                } else {
                        memset(&send_evt, '\0', sizeof(IMMSV_EVT));
@@ -6184,6 +6256,8 @@ static void immnd_evt_proc_object_modify
                                LOG_ER("Upcall over MDS for ccbObjectModify "
                                        "to PBE failed! - aborting");
                                err = SA_AIS_ERR_FAILED_OPERATION;
+                               immModel_setCcbErrorString(cb, 
evt->info.objModify.ccbId,
+                                               IMM_RESOURCE_ABORT "Upcall over 
MDS to PBE failed");
                                immnd_proc_global_abort_ccb(cb, 
evt->info.objModify.ccbId);
                        }
                        implHandle = 0LL;
@@ -6203,9 +6277,11 @@ static void immnd_evt_proc_object_modify
                        immnd_client_node_get(cb, implHandle, &oi_cl_node);
                        osafassert(oi_cl_node != NULL);
                        if (oi_cl_node->mIsStale) {
-                               LOG_WA("OI Client went down so nod modify 
upcall");
+                               LOG_WA("OI Client went down so no modify 
upcall");
                                err = SA_AIS_ERR_FAILED_OPERATION;
                                delayedReply = SA_FALSE;
+                               immModel_setCcbErrorString(cb, 
evt->info.objModify.ccbId,
+                                               IMM_RESOURCE_ABORT "OI client 
went down");
                        } else {
                                memset(&send_evt, '\0', sizeof(IMMSV_EVT));
                                send_evt.type = IMMSV_EVT_TYPE_IMMA;
@@ -6228,6 +6304,8 @@ static void immnd_evt_proc_object_modify
                                                       
oi_cl_node->agent_mds_dest, &send_evt) != NCSCC_RC_SUCCESS) {
                                        LOG_ER("Agent upcall over MDS for 
ccbObjectModify failed");
                                        err = SA_AIS_ERR_FAILED_OPERATION;
+                                       immModel_setCcbErrorString(cb, 
evt->info.objModify.ccbId,
+                                                       IMM_RESOURCE_ABORT 
"Agent upcall over MDS failed");
                                }
                        }
                }
@@ -6742,6 +6820,10 @@ static void immnd_evt_ccb_abort(IMMND_CB
                        send_evt.info.imma.info.errRsp.error =
                            timeout ? SA_AIS_ERR_TIMEOUT : 
SA_AIS_ERR_FAILED_OPERATION;
  
+                       if(send_evt.info.imma.info.errRsp.error == 
SA_AIS_ERR_FAILED_OPERATION) {
+                               immModel_setCcbErrorString(cb, ccbId, 
IMM_RESOURCE_ABORT);
+                       }
+
                        send_evt.info.imma.info.errRsp.errStrings =
                                immModel_ccbGrabErrStrings(cb, ccbId);
                        if(send_evt.info.imma.info.errRsp.errStrings) {
@@ -6856,6 +6938,8 @@ static void immnd_evt_proc_object_delete
                           should prevent any apply to succeed.
                        */
                        err = SA_AIS_ERR_FAILED_OPERATION;
+                       immModel_setCcbErrorString(cb, 
evt->info.objDelete.ccbId,
+                                       IMM_RESOURCE_ABORT "PBE is down");
                        immnd_proc_global_abort_ccb(cb, 
evt->info.objDelete.ccbId);                     
                } else {
                        /* We have obtained PBE handle & dest info for PBE.
@@ -6881,6 +6965,8 @@ static void immnd_evt_proc_object_delete
                                                "to PBE failed! - aborting ccb 
%u",
                                                evt->info.objDelete.ccbId);
                                        err = SA_AIS_ERR_FAILED_OPERATION;
+                                       immModel_setCcbErrorString(cb, 
evt->info.objDelete.ccbId,
+                                                       IMM_RESOURCE_ABORT 
"Upcall over MDS to PBE failed");
                                        immnd_proc_global_abort_ccb(cb, 
evt->info.objDelete.ccbId);
                                }
                        }
@@ -6916,6 +7002,8 @@ static void immnd_evt_proc_object_delete
                                        /* This should cause the ccb-operation 
to timeout on wait for the reply. */
                                        err = SA_AIS_ERR_FAILED_OPERATION;
                                        delayedReply = SA_FALSE;
+                                       immModel_setCcbErrorString(cb, 
evt->info.objDelete.ccbId,
+                                                       IMM_RESOURCE_ABORT 
"Client went down");
                                } else {
                                        /* Generate an implementer upcall for 
each deleted config object.
                                           No implementer upcalls are generated 
for any runtime objects
@@ -6937,6 +7025,8 @@ static void immnd_evt_proc_object_delete
                                                /* This should cause the 
ccb-operation to timeout. */
                                                err = 
SA_AIS_ERR_FAILED_OPERATION;
                                                delayedReply = SA_FALSE;
+                                               immModel_setCcbErrorString(cb, 
evt->info.objDelete.ccbId,
+                                                               
IMM_RESOURCE_ABORT "Upcall over MDS failed");
                                        }
                                }
                        }       /*for */
@@ -7413,14 +7503,23 @@ static void immnd_evt_proc_ccb_finalize(
                memset(&send_evt, '\0', sizeof(IMMSV_EVT));
  
                send_evt.type = IMMSV_EVT_TYPE_IMMA;
-               send_evt.info.imma.type = IMMA_EVT_ND2A_IMM_ERROR;
                send_evt.info.imma.info.errRsp.error = err;
+               send_evt.info.imma.info.errRsp.errStrings = NULL;
+
+               if(err == SA_AIS_OK) {
+                       send_evt.info.imma.type = IMMA_EVT_ND2A_IMM_ERROR;
+               } else {
+                       send_evt.info.imma.type = IMMA_EVT_ND2A_IMM_ERROR_2;
+                       send_evt.info.imma.info.errRsp.errStrings = 
immModel_ccbGrabErrStrings(cb, evt->info.ccbId);
+               }
[Hung] IMM_ERROR_2 should only be used when there's at least one error 
string. We can't make sure that when err is not SA_AIS_OK, there will be 
at least one error string. Please see immnd_evt_proc_object_create().
  
                TRACE_2("SENDRSP %u", err);
  
                if (immnd_mds_send_rsp(cb, &(cl_node->tmpSinfo), &send_evt) != 
NCSCC_RC_SUCCESS) {
                        LOG_WA("Failed to send response to agent/client over 
MDS");
                }
+
+               
immsv_evt_free_attrNames(send_evt.info.imma.info.errRsp.errStrings);
        }
   done:
        err = immModel_ccbFinalize(cb, evt->info.ccbId);
@@ -7515,6 +7614,8 @@ static void immnd_evt_proc_ccb_apply(IMM
                                        LOG_WA("IMMND - Client went down so no 
response");
                                        err = SA_AIS_ERR_FAILED_OPERATION;
                                        delayedReply = SA_FALSE;
+                                       immModel_setCcbErrorString(cb, 
evt->info.ccbId,
+                                                       IMM_RESOURCE_ABORT 
"Client went down");
                                } else {
                                        send_evt.info.imma.info.ccbCompl.ccbId 
= evt->info.ccbId;
                                        send_evt.info.imma.info.ccbCompl.implId 
= implIdArr[ix];
@@ -7529,6 +7630,8 @@ static void immnd_evt_proc_ccb_apply(IMM
                                                err = 
SA_AIS_ERR_FAILED_OPERATION;
                                                /* should abort the entire ccb 
*/
                                                delayedReply = SA_FALSE;
+                                               immModel_setCcbErrorString(cb, 
evt->info.ccbId,
+                                                               
IMM_RESOURCE_ABORT "Upcall over MDS failed");
                                        } else {
                                                TRACE_2("IMMND UPCALL TO OI, 
SEND SUCCEEDED");
                                        }
@@ -7768,11 +7871,19 @@ static void immnd_evt_proc_ccb_apply(IMM
                                memset(&send_evt, '\0', sizeof(IMMSV_EVT));
                                send_evt.type = IMMSV_EVT_TYPE_IMMA;
                                send_evt.info.imma.info.errRsp.error = err;
+                               send_evt.info.imma.info.errRsp.errStrings = 
NULL;
                                send_evt.info.imma.type = 
IMMA_EVT_ND2A_IMM_ERROR;
  
+                               if(err != SA_AIS_OK) {
+                                       send_evt.info.imma.type = 
IMMA_EVT_ND2A_IMM_ERROR_2;
+                                       
send_evt.info.imma.info.errRsp.errStrings = immModel_ccbGrabErrStrings(cb, 
evt->info.objDelete.ccbId);
+                               }
+
[Hung] The same as immnd_evt_proc_ccb_finalize().

                                if (immnd_mds_send_rsp(cb, 
&(cl_node->tmpSinfo), &send_evt) != NCSCC_RC_SUCCESS) {
                                        LOG_WA("Failed to send result to Agent 
over MDS");
                                }
+
+                               
immsv_evt_free_attrNames(send_evt.info.imma.info.errRsp.errStrings);
                        }
                }
        }
diff --git a/osaf/services/saf/immsv/immnd/immnd_init.h 
b/osaf/services/saf/immsv/immnd/immnd_init.h
--- a/osaf/services/saf/immsv/immnd/immnd_init.h
+++ b/osaf/services/saf/immsv/immnd/immnd_init.h
@@ -425,6 +425,12 @@ extern "C" {
                const struct ImmsvAdminOperationParam *reqparams,
                struct ImmsvAdminOperationParam **rparams);
  
+       void
+       immModel_setCcbErrorString(IMMND_CB *cb,
+               SaUint32T ccbId,
+               const char *errorString,
+               ...);
+
  #ifdef __cplusplus
  }
  #endif

------------------------------------------------------------------------------
Monitor Your Dynamic Infrastructure at Any Scale With Datadog!
Get real-time metrics from all of your servers, apps and tools
in one place.
SourceForge users - Click here to start your Free Trial of Datadog now!
http://pubads.g.doubleclick.net/gampad/clk?id=241902991&iu=/4140
_______________________________________________
Opensaf-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensaf-devel



------------------------------------------------------------------------------
Monitor Your Dynamic Infrastructure at Any Scale With Datadog!
Get real-time metrics from all of your servers, apps and tools
in one place.
SourceForge users - Click here to start your Free Trial of Datadog now!
http://pubads.g.doubleclick.net/gampad/clk?id=241902991&iu=/4140
_______________________________________________
Opensaf-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensaf-devel

Reply via email to