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: " + 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); + } 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); + } + 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 Opensaf-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/opensaf-devel