osaf/services/saf/immsv/immnd/ImmModel.cc | 85 +++++++++++++++++++++--
osaf/services/saf/immsv/immnd/ImmModel.hh | 2 +-
osaf/services/saf/immsv/immpbed/immpbe_daemon.cc | 13 +---
3 files changed, 80 insertions(+), 20 deletions(-)
The OpenSAF IMM service object 'opensafImm=opensafImm,safApp=safImmService'
currently has two writable config attributes:
- opensafImmSyncBatchSize
- longDnsAllowed
Changes to these attributes required the PBE to be disabled. This because the
PBE
is both regular-OI and PBE-OI for this special object. The PBE used to reject
all
such requests. This ticket changes the PBE to accept modifications to this
config
object. This would result in the PBE getting a second (duplicate) callback, the
first one as regular OI and the second one as PBE, resulting in the derailing
and
abort of the CCB. So this changeset also fixes so that modifications to the
special
OpenSAF IMM service object will only generate one modify callback to the PBE.
The
regular OI callback is discarded for this special case.
The ticket also mentions that validation should be done. But there is no
validation
of substance to perform for the above two config attributes.
The 'opensafImmSyncBatchSize' can be set to whatever value the deployer thinks
is
appropriate. The 'longDnsAllowed' attribute is managed by logic that only cares
if
the value is 0/zero or not, corresponding to longDNs disallowed or allowed. So
the
PBE simply accepts whatever modification is proposed for these attributes.
Creates or deletes of instances of the class OpensafImm are still rejected by
the
PBE (not changed by this changeset) and so will not be duplicated and never
require
validation. However, when PBE is disabled, then curently creates or deletes of
instances of the OpensafImm class are accepted. That is a defect that will be
fixed
separately on the supported branches. This ticket is an enhancement and is fixed
only on default(4.5).
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
@@ -446,6 +446,7 @@ static const std::string saImmRepository
static SaImmRepositoryInitModeT immInitMode = SA_IMM_INIT_FROM_FILE;
+static SaUint32T ccbIdLongDnGuard = 0; /* Disallow long DN creates if
longDnsAllowed is being changed in ccb*/
struct AttrFlagIncludes
{
@@ -1010,7 +1011,7 @@ immModel_cleanTheBasement(IMMND_CB *cb,
clearCounter++;
} else {
if(opSearchTime < nextSearch) {
- nextSearch = opSearchTime;
+ nextSearch = opSearchTime;
}
prevSearchOp = &searchOp->next;
searchOp = searchOp->next;
@@ -2532,17 +2533,25 @@ ImmModel::getMaxSyncBatchSize()
}
bool
-ImmModel::getLongDnsAllowed()
+ImmModel::getLongDnsAllowed(ObjectInfo* immObject)
{
TRACE_ENTER();
bool longDnsAllowed = false;
- ObjectMap::iterator oi = sObjectMap.find(immObjectDn);
- if(oi == sObjectMap.end()) {
- TRACE_LEAVE();
+ if(ccbIdLongDnGuard) {
+ /* A ccb is currently mutating longDnsAllowed */
return false;
}
- ObjectInfo* immObject = oi->second;
+ ObjectMap::iterator oi;
+ if(immObject == NULL) {
+ oi = sObjectMap.find(immObjectDn);
+ if(oi == sObjectMap.end()) {
+ TRACE_LEAVE();
+ return false;
+ }
+ immObject = oi->second;
+ }
+
ImmAttrValueMap::iterator avi =
immObject->mAttrValueMap.find(immLongDnsAllowed);
if(avi != immObject->mAttrValueMap.end()) {
@@ -5176,6 +5185,8 @@ ImmModel::ccbCommit(SaUint32T ccbId, Con
}//for
ccb->mMutations.clear();
+
+ if(ccbIdLongDnGuard == ccbId) {ccbIdLongDnGuard= 0;}
//If there are implementers involved then send the final apply callback
//to them and remove the implementers from the Ccb.
@@ -5358,6 +5369,9 @@ ImmModel::ccbAbort(SaUint32T ccbId, Conn
TRACE_5("Ccb abort upcall for ccb %u for local PBE ", ccbId);
}
}
+
+ if(ccbIdLongDnGuard == ccbId) {ccbIdLongDnGuard= 0;}
+
return true;
}
@@ -7913,7 +7927,7 @@ ImmModel::ccbObjectModify(const ImmsvOmC
oMut->mAfterImage = afim;
}
- // Prepare for call on object implementor
+ // Prepare for call on object implementer
// and add implementer to ccb.
bool hasImpl = object->mImplementer && object->mImplementer->mNodeId;
@@ -7925,6 +7939,61 @@ ImmModel::ccbObjectModify(const ImmsvOmC
LOG_IN("Skipping OI upcall for modify on %s since OI is same "
"as the originator of the modify (OI augmented ccb)",
objectName.c_str());
+ } else if(objectName == immObjectDn) {
+ ignoreImpl = true;
+ /* Ignore implemepter also for the implementer of the OpenSAF IMM
service object,
+ which is actually the PBE. The PBE is the OI for the OpenSAF
IMM service object
+ mainly to have the PBE receive and handle admin-operations
directed at the
+ that object. But the OpenSAF IMM service object also has some
config attributes
+ and we then dont want the PBE to receive redundant ccb-related
callbacks.
+ The PBE gets such ccb related callbacks for *all* persistent
objects anyway.
+ So we discard the "normal" OI callback in this case since the
PBE will get
+ the callback as PBE.
+ */
+ LOG_IN("Skipping OI callback for modify on %s since OI is same as
PBE",
+ objectName.c_str());
+
+ /* 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.
+ For longDnsAllowed we must check for interference and if
setting to 0,
+ i.e. not allowed, then verify that no long DNs *exis*t in the
IMM DB.
+ For opensafImmSyncBatchSize we accept anything.
+ */
+
+ bool longDnsAllowedBefore = getLongDnsAllowed();
+ bool longDnsAllowedAfter = getLongDnsAllowed(afim);
+
+ /* Check if *this* ccb is attempting to alter longDnsAllowed.*/
+ if(longDnsAllowedBefore != 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",
+ ccbIdLongDnGuard, immLongDnsAllowed.c_str());
+ LOG_IN("ERR_BUSY: Other Ccb (%u) already using %s",
+ ccbIdLongDnGuard, immLongDnsAllowed.c_str());
+ err = SA_AIS_ERR_BUSY;
+ } else {
+ if(!longDnsAllowedAfter) {
+ /* Check that NO LONG DNS EXIST! */
+ ObjectMap::iterator omi = sObjectMap.begin();
+ while(omi != sObjectMap.end()) {
+ if(omi->first.length() > 255) {
+ LOG_WA("Setting attr %s to 0 in %s not allowed
when long DN exists: '%s'",
+
immLongDnsAllowed.c_str(),immObjectDn.c_str(), omi->first.c_str());
+ err = SA_AIS_ERR_BAD_OPERATION;
+ goto bypass_impl;
+ }
+ ++omi;
+ }
+ }
+
+ ccbIdLongDnGuard = ccbId;
+ }
+ }
+ }
+
+ if(ignoreImpl) {
goto bypass_impl;
} else if(hasImpl && ccb->mAugCcbParent) {
TRACE("impl found & not ignored Node %u %u ImpllId: %u %u",
@@ -8583,7 +8652,7 @@ ImmModel::setCcbErrorString(CcbInfo *ccb
va_end(vl);
osafassert(len >= 0);
- len++; /* Reserve one byte for null-terminated sign '\0' */
+ len++; /* Reserve one byte for null-terminated sign '\0' */
if(len > errLen) {
fmtError = (char *)realloc(fmtError, len);
va_start(vl, errorString);
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
@@ -483,7 +483,7 @@ public:
SaImmRepositoryInitModeT getRepositoryInitMode();
unsigned int getMaxSyncBatchSize();
- bool getLongDnsAllowed();
+ bool getLongDnsAllowed(ObjectInfo* immObject = NULL);
void prepareForLoading();
bool readyForLoading();
void prepareForSync(bool isJoining);
diff --git a/osaf/services/saf/immsv/immpbed/immpbe_daemon.cc
b/osaf/services/saf/immsv/immpbed/immpbe_daemon.cc
--- a/osaf/services/saf/immsv/immpbed/immpbe_daemon.cc
+++ b/osaf/services/saf/immsv/immpbed/immpbe_daemon.cc
@@ -1098,17 +1098,8 @@ static SaAisErrorT saImmOiCcbObjectModif
numOps = (SaUint64T) ccbUtilCcbData->userData;
- if(strncmp((char *) objectName->value, (char *) OPENSAF_IMM_OBJECT_DN,
objectName->length) ==0) {
- char buf[sBufsize];
- snprintf(buf, sBufsize,
- "PBE will not allow modifications to object %s", (char
*) OPENSAF_IMM_OBJECT_DN);
- LOG_NO("%s", buf);
- saImmOiCcbSetErrorString(immOiHandle, ccbId, buf);
- rc = SA_AIS_ERR_BAD_OPERATION;
- /* We will actually get invoked twice on this object, both as
normal implementer and as PBE
- the response on the modify upcall from PBE is discarded, but
not for the regular implemener.
- */
- goto done;
+ if(strncmp((char *) objectName->value, (char *) OPENSAF_IMM_OBJECT_DN,
objectName->length) ==0) {
+ LOG_NO("PBE allowing modification to object %s", (char *)
OPENSAF_IMM_OBJECT_DN);
}
/* memorize the modification request */
------------------------------------------------------------------------------
Open source business process management suite built on Java and Eclipse
Turn processes into business applications with Bonita BPM Community Edition
Quickly connect people, data, and systems into organized workflows
Winner of BOSSIE, CODIE, OW2 and Gartner awards
http://p.sf.net/sfu/Bonitasoft
_______________________________________________
Opensaf-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensaf-devel