Hi Neelakanta, Find my comments inline
-----Original Message----- From: reddy.neelaka...@oracle.com [mailto:reddy.neelaka...@oracle.com] Sent: den 27 juli 2016 10:32 To: Zoran Milinkovic; Hung Duc Nguyen Cc: opensaf-devel@lists.sourceforge.net Subject: [PATCH 3 of 5] imm: Checking of Imm limits [#195] osaf/services/saf/immsv/immnd/ImmModel.cc | 322 +++++++++++++++++++++++++++++- osaf/services/saf/immsv/immnd/ImmModel.hh | 5 +- 2 files changed, 324 insertions(+), 3 deletions(-) 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 @@ -1154,6 +1154,13 @@ immModel_protocol50Allowed(IMMND_CB *cb) SA_TRUE : SA_FALSE; } +SaBoolT +immModel_protocol51Allowed(IMMND_CB *cb) +{ + return (ImmModel::instance(&cb->immModel)->protocol51Allowed()) ? + SA_TRUE : SA_FALSE; +} + OsafImmAccessControlModeT immModel_accessControlMode(IMMND_CB *cb) { @@ -3271,6 +3278,21 @@ ImmModel::classCreate(const ImmsvOmClass return SA_AIS_ERR_INVALID_PARAM; } + ObjectMap::iterator oit = sObjectMap.find(immObjectDn); + if(protocol51Allowed() && oit != sObjectMap.end() && !isLoading ){ + std::string immMaxClasses(OPENSAF_IMMSV_MAX_CLASSES); + ObjectInfo* immObject = oit->second; + ImmAttrValueMap::iterator avi = immObject->mAttrValueMap.find(immMaxClasses); + osafassert(avi != immObject->mAttrValueMap.end()); + osafassert(!(avi->second->isMultiValued())); + ImmAttrValue* valuep = avi->second; + unsigned int maxClasses = valuep->getValue_int(); + if( sClassMap.size() >= maxClasses){ + LOG_NO("ERR_NO_RESOURCES: maximum class limit %d has been reched for the cluster", + maxClasses); + return SA_AIS_ERR_NO_RESOURCES; + } + } [Zoran] "std::string immMaxClasses(OPENSAF_IMMSV_MAX_CLASSES);" can be moved to the top of the file with other definition of strings. I would create a common method for finding max number of classes and use it in the block above. The code is not wrong. I'll leave it to you if you want to create a common method. ClassMap::iterator i = sClassMap.find(className); if (i == sClassMap.end()) { /* Class-name is unique case-sensitive. @@ -3597,6 +3619,8 @@ ImmModel::classCreate(const ImmsvOmClass } } + + if(illegal) { if(err == SA_AIS_OK) { LOG_NO("ERR_INVALID_PARAM: Problem with new class '%s'", className.c_str()); @@ -3966,6 +3990,34 @@ ImmModel::protocol50Allowed() return noStdFlags & OPENSAF_IMM_FLAG_PRT50_ALLOW; } + +bool +ImmModel::protocol51Allowed() +{ + //TRACE_ENTER(); + /* Assume that all nodes are running the same version when loading */ + if (sImmNodeState == IMM_NODE_LOADING) { + return true; + } + ObjectMap::iterator oi = sObjectMap.find(immObjectDn); + if(oi == sObjectMap.end()) { + TRACE_LEAVE(); + return false; + } + + ObjectInfo* immObject = oi->second; + ImmAttrValueMap::iterator avi = + immObject->mAttrValueMap.find(immAttrNostFlags); + osafassert(avi != immObject->mAttrValueMap.end()); + osafassert(!(avi->second->isMultiValued())); + ImmAttrValue* valuep = avi->second; + unsigned int noStdFlags = valuep->getValue_int(); + + //TRACE_LEAVE(); + return noStdFlags & OPENSAF_IMM_FLAG_PRT51_ALLOW; +} + + bool ImmModel::protocol41Allowed() { @@ -4114,6 +4166,44 @@ ImmModel::verifySchemaChange(const std:: verifyFailed = notCompatibleAtt(className, newClassInfo, attName, NULL, newAttr, NULL) || verifyFailed; newAttrs[inew->first] = newAttr; + if(!verifyFailed && (className == immClassName)){ + unsigned int val; + if ( attName == OPENSAF_IMMSV_MAX_CLASSES) { [Zoran] Same as in earlier comment. Create a string for OPENSAF_IMMSV_MAX_CLASSES in the top of the file with strings for other attributes. + val = newAttr->mDefaultValue.getValue_int(); + if( sClassMap.size() > val){ + LOG_NO("The Number of classes in the cluster %lu greater than the schema change" + "value %d", sClassMap.size(), val); + verifyFailed = true; + } + } + + if ( !verifyFailed && attName == OPENSAF_IMMSV_MAX_IMPLEMENTERS) { [Zoran] Same here for OPENSAF_IMMSV_MAX_IMPLEMENTERS. + val = newAttr->mDefaultValue.getValue_int(); + if( sImplementerVector.size() > val){ + LOG_NO("The Number of Implementers in the cluster %lu greater than the schema change" + "value %d", sImplementerVector.size(), val); + verifyFailed = true; + } + } + + if ( !verifyFailed && attName == OPENSAF_IMMSV_MAX_ADMINOWNERS) { [Zoran] And here for OPENSAF_IMMSV_MAX_ADMINOWNERS + val = newAttr->mDefaultValue.getValue_int(); + if( sOwnerVector.size() > val){ + LOG_NO("The Number of AdminOwners in the cluster %lu greater than the schema change" + "value %d", sOwnerVector.size(), val); + verifyFailed = true; + } + } + + if ( !verifyFailed && attName == OPENSAF_IMMSV_MAX_CCBS) { [Zoran] And here for OPENSAF_IMMSV_MAX_CCBS + val = newAttr->mDefaultValue.getValue_int(); + if( sCcbVector.size() > val){ + LOG_NO("The Number of Ccbs in the cluster %lu greater than the schema change" + "value %d", sCcbVector.size(), val); + verifyFailed = true; + } + } + } [Zoran] In the upper block, maybe it would be good to add a check that with a schema change, new attribute values cannot be lower than IMMSV_MAX_* values. } else { TRACE_5("Existing attribute %s", attName.c_str()); verifyFailed = notCompatibleAtt(className, newClassInfo, attName, iold->second, newAttr, @@ -4799,6 +4889,8 @@ ImmModel::adminOwnerCreate(const ImmsvOm unsigned int nodeId) { SaAisErrorT err = SA_AIS_OK; + bool isLoading = (sImmNodeState == IMM_NODE_LOADING); + TRACE_ENTER(); if(immNotWritable()) { TRACE_LEAVE(); @@ -4812,7 +4904,24 @@ ImmModel::adminOwnerCreate(const ImmsvOm return SA_AIS_ERR_INVALID_PARAM; } } - + + ObjectMap::iterator oi = sObjectMap.find(immObjectDn ); + if(protocol51Allowed() && oi != sObjectMap.end() && !isLoading ){ + std::string immMaxAdmOwn(OPENSAF_IMMSV_MAX_ADMINOWNERS); [Zoran] Same here for OPENSAF_IMMSV_MAX_ADMINOWNERS + ObjectInfo* immObject = oi->second; + ImmAttrValueMap::iterator avi = immObject->mAttrValueMap.find(immMaxAdmOwn); + osafassert(avi != immObject->mAttrValueMap.end()); + osafassert(!(avi->second->isMultiValued())); + ImmAttrValue* valuep = avi->second; + unsigned int maxAdmOwn= valuep->getValue_int(); + if( sOwnerVector.size() >= maxAdmOwn ){ + LOG_NO("ERR_NO_RESOURCES: maximum AdminOwners limit %d has been reached for the cluster", + maxAdmOwn); + TRACE_LEAVE(); + return SA_AIS_ERR_NO_RESOURCES; + } + } + AdminOwnerInfo* info = new AdminOwnerInfo; info->mId = ownerId; @@ -4899,6 +5008,15 @@ ImmModel::adminOwnerDelete(SaUint32T own immObject->mAttrValueMap.find(immAttrNostFlags); osafassert(avi != immObject->mAttrValueMap.end()); osafassert(!(avi->second->isMultiValued())); + ImmAttrValueMap::iterator avi1 = + immObject->mAttrValueMap.find(OPENSAF_IMMSV_MAX_CLASSES); + ImmAttrValueMap::iterator avi2 = + immObject->mAttrValueMap.find(OPENSAF_IMMSV_MAX_IMPLEMENTERS); + ImmAttrValueMap::iterator avi3 = + immObject->mAttrValueMap.find(OPENSAF_IMMSV_MAX_ADMINOWNERS); + ImmAttrValueMap::iterator avi4 = + immObject->mAttrValueMap.find(OPENSAF_IMMSV_MAX_CCBS); [Zoran] Same string issue for all 4 attribute names + ImmAttrValue* valuep = (ImmAttrValue *) avi->second; unsigned int noStdFlags = valuep->getValue_int(); noStdFlags |= OPENSAF_IMM_FLAG_PRT41_ALLOW; @@ -4907,6 +5025,16 @@ ImmModel::adminOwnerDelete(SaUint32T own noStdFlags |= OPENSAF_IMM_FLAG_PRT46_ALLOW; noStdFlags |= OPENSAF_IMM_FLAG_PRT47_ALLOW; noStdFlags |= OPENSAF_IMM_FLAG_PRT50_ALLOW; + if( (avi1 == immObject->mAttrValueMap.end()) || + (avi2 == immObject->mAttrValueMap.end()) || + (avi3 == immObject->mAttrValueMap.end()) || + (avi4 == immObject->mAttrValueMap.end())){ + LOG_NO("protcol51 is not set for opensafImmNostdFlags because" + "The new OpenSAF 5.1 attributes are not added to OpensafImm class"); + } else { + + noStdFlags |= OPENSAF_IMM_FLAG_PRT51_ALLOW; + } valuep->setValue_int(noStdFlags); LOG_NO("%s changed to: 0x%x", immAttrNostFlags.c_str(), noStdFlags); /* END Temporary code. */ @@ -5174,12 +5302,31 @@ ImmModel::ccbCreate(SaUint32T adminOwner SaUint32T originatingConn) { SaAisErrorT err = SA_AIS_OK; + bool isLoading = (sImmNodeState == IMM_NODE_LOADING); + TRACE_ENTER(); if(immNotWritable()) { TRACE_LEAVE(); return SA_AIS_ERR_TRY_AGAIN; } + + ObjectMap::iterator oi = sObjectMap.find(immObjectDn); + if(protocol51Allowed() && oi != sObjectMap.end() && !isLoading){ + std::string immMaxCcbs(OPENSAF_IMMSV_MAX_CCBS); [Zoran] OPENSAF_IMMSV_MAX_CCBS + ObjectInfo* immObject = oi->second; + ImmAttrValueMap::iterator avi = immObject->mAttrValueMap.find(immMaxCcbs); + osafassert(avi != immObject->mAttrValueMap.end()); + osafassert(!(avi->second->isMultiValued())); + ImmAttrValue* valuep = avi->second; + unsigned int maxCcbs= valuep->getValue_int(); + if (sCcbVector.size() >= maxCcbs){ + LOG_NO("ERR_NO_RESOURCES: maximum Ccbs limit %d has been reached for the cluster", + maxCcbs); + TRACE_LEAVE(); + return SA_AIS_ERR_NO_RESOURCES; + } + } CcbInfo* info = new CcbInfo; info->mId = ccbId; @@ -7422,6 +7569,78 @@ ImmModel::getAllWritableAttributes(const return result; } +SaAisErrorT ImmModel::verifyImmLimits(ObjectInfo* object, + std::string objectName){ + + SaAisErrorT err = SA_AIS_OK; + SaUint32T val; + + TRACE_ENTER(); + osafassert(objectName == immObjectDn); + ImmAttrValueMap::iterator class_avmi = object->mAttrValueMap.find(OPENSAF_IMMSV_MAX_CLASSES); + if( class_avmi != object->mAttrValueMap.end()){ + osafassert(class_avmi->second); + val = (SaUint32T)class_avmi->second->getValue_int(); + } else { + val = IMMSV_MAX_CLASSES; + } + if(sClassMap.size() > val){ + LOG_NO("ERR_NO_RESOURCES: maximum class limit %d has been reched for the cluster", + val); + err = SA_AIS_ERR_NO_RESOURCES; + TRACE_LEAVE(); + return err; + } + + ImmAttrValueMap::iterator impl_avmi = object->mAttrValueMap.find(OPENSAF_IMMSV_MAX_IMPLEMENTERS); + if( impl_avmi != object->mAttrValueMap.end()){ + osafassert(impl_avmi->second); + val = (SaUint32T)impl_avmi->second->getValue_int(); + } else { + val = IMMSV_MAX_IMPLEMENTERS; + } + if(sImplementerVector.size() > val){ + LOG_NO("ERR_NO_RESOURCES: maximum implementers limit %d has been reched for the cluster", + val); + err = SA_AIS_ERR_NO_RESOURCES; + TRACE_LEAVE(); + return err; + } + + ImmAttrValueMap::iterator admi_avmi = object->mAttrValueMap.find(OPENSAF_IMMSV_MAX_ADMINOWNERS); + if( admi_avmi != object->mAttrValueMap.end()){ + osafassert(admi_avmi->second); + val = (SaUint32T)admi_avmi->second->getValue_int(); + } else { + val = IMMSV_MAX_ADMINOWNERS; + } + if(sOwnerVector.size() > val){ + LOG_NO("ERR_NO_RESOURCES: maximum adminownerslimit %d has been reched for the cluster", + val); + err = SA_AIS_ERR_NO_RESOURCES; + TRACE_LEAVE(); + return err; + } + + ImmAttrValueMap::iterator ccb_avmi = object->mAttrValueMap.find(OPENSAF_IMMSV_MAX_CCBS); + if( ccb_avmi != object->mAttrValueMap.end()){ + osafassert(ccb_avmi->second); + val = (SaUint32T)ccb_avmi->second->getValue_int(); + } else { + val = IMMSV_MAX_CCBS; + } + if(sCcbVector.size() > val){ + LOG_NO("ERR_NO_RESOURCES: maximum ccbs limit %d has been reched for the cluster", + val); + err = SA_AIS_ERR_NO_RESOURCES; + TRACE_LEAVE(); + return err; + } [Zoran] It would be good to create new methods for finding max numbers of new attributes. Again the same issue with new attribute names which can be defined in the top of the file + + TRACE_LEAVE(); + return err; +} + /** * Creates an object */ @@ -8342,6 +8561,8 @@ SaAisErrorT ImmModel::ccbObjectCreate(Im */ sIsLongDnLoaded = true; } + err = verifyImmLimits(object, immObjectDn); + setCcbErrorString(ccb, IMM_RESOURCE_ABORT "Verifying of immLimits failed"); } else { setCcbErrorString(ccb, "IMM: ERR_BAD_OPERATION: Imm not allowing creates of instances of class '%s'", @@ -9380,6 +9601,83 @@ ImmModel::ccbObjectModify(const ImmsvOmC } } + /* From OpenSAF 5.1 immObjectDn has added with attributes maxClasses, maxImplementers, + maxAdminowners and maxCcbs */ + + + ImmAttrValueMap::iterator class_avmi = afim->mAttrValueMap.find(OPENSAF_IMMSV_MAX_CLASSES); + ImmAttrValueMap::iterator impl_avmi = afim->mAttrValueMap.find(OPENSAF_IMMSV_MAX_IMPLEMENTERS); + ImmAttrValueMap::iterator admi_avmi = afim->mAttrValueMap.find(OPENSAF_IMMSV_MAX_ADMINOWNERS); + ImmAttrValueMap::iterator ccb_avmi = afim->mAttrValueMap.find(OPENSAF_IMMSV_MAX_CCBS); + + if ( !protocol51Allowed() && class_avmi != afim->mAttrValueMap.end()) { + LOG_WA("ERR_NOT_EXIST: The attribute %s can not be modified. The cluster is not yet upgraded" + "to OpenSAF 5.1", OPENSAF_IMMSV_MAX_CLASSES); + err = SA_AIS_ERR_NOT_EXIST; + goto bypass_impl; + } else if(class_avmi != afim->mAttrValueMap.end()) { + osafassert(class_avmi->second); + SaUint32T val = (SaUint32T)class_avmi->second->getValue_int(); + if(val < IMMSV_MAX_CLASSES){ + LOG_WA("ERR_BAD_OPERATION: The value %d is less than the minimum supported value %d for" + "the attribute %s", val,IMMSV_MAX_CLASSES, OPENSAF_IMMSV_MAX_CLASSES); + err = SA_AIS_ERR_BAD_OPERATION; + goto bypass_impl; + } + } + + if ( !protocol51Allowed() && impl_avmi != afim->mAttrValueMap.end()) { + LOG_WA("ERR_NOT_EXIST: The attribute %s can not be modified. The cluster is not yet upgraded" + "to OpenSAF 5.1", OPENSAF_IMMSV_MAX_IMPLEMENTERS); + err = SA_AIS_ERR_NOT_EXIST; + goto bypass_impl; + + } else if(class_avmi != afim->mAttrValueMap.end()) { + osafassert(impl_avmi->second); + SaUint32T val = (SaUint32T)impl_avmi->second->getValue_int(); + if(val < IMMSV_MAX_IMPLEMENTERS){ + LOG_WA("ERR_BAD_OPERATION: The value %d is less than the minimum supported value %d for" + "the attribute %s", val, IMMSV_MAX_IMPLEMENTERS, OPENSAF_IMMSV_MAX_IMPLEMENTERS); + err = SA_AIS_ERR_BAD_OPERATION; + goto bypass_impl; + } + } + + if ( !protocol51Allowed() && admi_avmi != afim->mAttrValueMap.end()) { + LOG_WA("ERR_NOT_EXIST: The attribute %s can not be modified. The cluster is not yet upgraded" + "to OpenSAF 5.1", OPENSAF_IMMSV_MAX_ADMINOWNERS); + err = SA_AIS_ERR_NOT_EXIST; + goto bypass_impl; + + } else if(admi_avmi != afim->mAttrValueMap.end()) { + osafassert(admi_avmi->second); + SaUint32T val = (SaUint32T)admi_avmi->second->getValue_int(); + if(val < IMMSV_MAX_ADMINOWNERS){ + LOG_WA("ERR_BAD_OPERATION: The value %d is less than the minimum supported value %d for" + "the attribute %s", val, IMMSV_MAX_ADMINOWNERS, OPENSAF_IMMSV_MAX_ADMINOWNERS); + err = SA_AIS_ERR_BAD_OPERATION; + goto bypass_impl; + } + } + + if ( !protocol51Allowed() && ccb_avmi != afim->mAttrValueMap.end()) { + LOG_WA("ERR_NOT_EXIST: The attribute %s can not be modified. The cluster is not yet upgraded" + "to OpenSAF 5.1", OPENSAF_IMMSV_MAX_CCBS); + err = SA_AIS_ERR_NOT_EXIST; + goto bypass_impl; + + } else if(ccb_avmi != afim->mAttrValueMap.end()) { + osafassert(ccb_avmi->second); + SaUint32T val = (SaUint32T)ccb_avmi->second->getValue_int(); + if(val < IMMSV_MAX_CCBS){ + LOG_WA("ERR_BAD_OPERATION: The value %d is less than the minimum supported value %d for" + "the attribute %s", val, IMMSV_MAX_CCBS, OPENSAF_IMMSV_MAX_CCBS); + err = SA_AIS_ERR_BAD_OPERATION; + goto bypass_impl; + } + } + + [Zoran] Make an extra space when breaking LOG message in a next line. Otherwise strings will be concatenated. /* Pre validate any changes. More efficent here than in apply/completed and we need to guard against race on long DN creation allowed. Such long DNs are themselves created in CCBs or RTO creates. @@ -13972,6 +14270,8 @@ ImmModel::implementerSet(const IMMSV_OCT { SaAisErrorT err = SA_AIS_OK; CcbVector::iterator i; + bool isLoading = (sImmNodeState == IMM_NODE_LOADING); + TRACE_ENTER(); *discardImplementer = SA_FALSE; @@ -13997,7 +14297,25 @@ ImmModel::implementerSet(const IMMSV_OCT return err; //This return code not formally allowed here according to IMM standard. } - + + ObjectMap::iterator oi = sObjectMap.find(immObjectDn); + if(protocol51Allowed() && oi != sObjectMap.end() && !isLoading){ + std::string immMaxImp(OPENSAF_IMMSV_MAX_IMPLEMENTERS); [Zoran] Same here with OPENSAF_IMMSV_MAX_IMPLEMENTERS Thanks, Zoran + ObjectInfo* immObject = oi->second; + ImmAttrValueMap::iterator avi = immObject->mAttrValueMap.find(immMaxImp); + osafassert(avi != immObject->mAttrValueMap.end()); + osafassert(!(avi->second->isMultiValued())); + ImmAttrValue* valuep = avi->second; + unsigned int maxImp = valuep->getValue_int(); + if( sImplementerVector.size() >= maxImp){ + LOG_NO("ERR_NO_RESOURCES: maximum Implementers limit %d has been reached for the cluster", + maxImp); + TRACE_LEAVE(); + return SA_AIS_ERR_NO_RESOURCES; + } + } + + bool isApplier = (implName.at(0) == '@'); ImplementerInfo* info = findImplementer(implName); 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 @@ -116,6 +116,7 @@ public: bool protocol46Allowed(); bool protocol47Allowed(); bool protocol50Allowed(); + bool protocol51Allowed(); bool oneSafe2PBEAllowed(); bool purgeSyncRequest(SaUint32T clientId); bool verifySchemaChange(const std::string& className, @@ -661,7 +662,9 @@ public: ObjectInfo* obj, AdminOwnerInfo* adm, bool doIt); - + SaAisErrorT verifyImmLimits( + ObjectInfo* object, + std::string objectName); private: bool checkSubLevel( ------------------------------------------------------------------------------ What NetFlow Analyzer can do for you? Monitors network bandwidth and traffic patterns at an interface-level. Reveals which users, apps, and protocols are consuming the most bandwidth. Provides multi-vendor support for NetFlow, J-Flow, sFlow and other flows. Make informed decisions using capacity planning reports. http://sdm.link/zohodev2dev _______________________________________________ Opensaf-devel mailing list Opensaf-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/opensaf-devel