osaf/services/saf/immsv/immnd/ImmModel.cc | 98 +++++++++++++++++++++++++----
osaf/services/saf/immsv/immnd/ImmModel.hh | 6 +-
osaf/services/saf/immsv/immnd/immnd_evt.c | 33 +++++++++-
osaf/services/saf/immsv/immnd/immnd_init.h | 6 +-
osaf/services/saf/immsv/immnd/immnd_proc.c | 2 +-
5 files changed, 124 insertions(+), 21 deletions(-)
when implementer is disconnected (case where the OI application died or
restarted (#1105)), then if there are Non-critical CCBs associated with this
implementer. Then those CCBs may be aborted in IMM, Because the final outcome
of these CCBs will be aborted.
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
@@ -1204,12 +1204,14 @@ void
immModel_discardNode(IMMND_CB *cb,
SaUint32T nodeId,
SaUint32T* arrSize,
- SaUint32T** ccbIdArr)
-{
- ConnVector cv;
- ConnVector::iterator cvi;
+ SaUint32T** ccbIdArr,
+ SaUint32T* globArrSize,
+ SaUint32T** globccbIdArr)
+{
+ ConnVector cv, gv;
+ ConnVector::iterator cvi, gvi;
unsigned int ix=0;
- ImmModel::instance(&cb->immModel)->discardNode(nodeId, cv);
+ ImmModel::instance(&cb->immModel)->discardNode(nodeId, cv, gv,
cb->mIsCoord);
*arrSize = (SaUint32T) cv.size();
if(*arrSize) {
*ccbIdArr = (SaUint32T *) malloc((*arrSize)* sizeof(SaUint32T));
@@ -1218,6 +1220,16 @@ immModel_discardNode(IMMND_CB *cb,
}
}
osafassert(ix==(*arrSize));
+
+ *globArrSize = (SaUint32T) gv.size();
+ ix=0;
+ if(*globArrSize) {
+ *globccbIdArr = (SaUint32T *) malloc((*globArrSize)*
sizeof(SaUint32T));
+ for(gvi = gv.begin(); gvi!=gv.end(); ++gvi, ++ix) {
+ (*globccbIdArr)[ix] = (*gvi);
+ }
+ }
+ osafassert(ix==(*globArrSize));
}
void
@@ -1599,9 +1611,26 @@ immModel_getImplementerId(IMMND_CB* cb,
void
immModel_discardImplementer(IMMND_CB* cb, SaUint32T implId,
- SaBoolT reallyDiscard)
-{
- ImmModel::instance(&cb->immModel)->discardImplementer(implId,
reallyDiscard);
+ SaBoolT reallyDiscard, SaUint32T* globArrSize, SaUint32T** globccbIdArr)
+{
+ ConnVector gv;
+ ConnVector::iterator gvi;
+ unsigned int ix=0;
+ ImmModel::instance(&cb->immModel)->discardImplementer(implId,
reallyDiscard,
+ gv, cb->mIsCoord);
+
+ if (globArrSize && globccbIdArr) {
+ *globArrSize = (SaUint32T) gv.size();
+ ix=0;
+ if(*globArrSize) {
+ *globccbIdArr = (SaUint32T *) malloc((*globArrSize)*
sizeof(SaUint32T));
+ for(gvi = gv.begin(); gvi!=gv.end(); ++gvi, ++ix) {
+ (*globccbIdArr)[ix] = (*gvi);
+ }
+ }
+ osafassert(ix==(*globArrSize));
+ }
+
}
SaAisErrorT
@@ -11913,11 +11942,13 @@ ImmModel::getImplementerId(SaUint32T loc
}
void
-ImmModel::discardNode(unsigned int deadNode, IdVector& cv)
+ImmModel::discardNode(unsigned int deadNode, IdVector& cv, IdVector& gv, bool
isAtCoord )
{
ImplementerVector::iterator i;
AdminOwnerVector::iterator i2;
CcbVector::iterator i3;
+ ConnVector implv;
+ ConnVector::iterator i4;
TRACE_ENTER();
if(sImmNodeState == IMM_NODE_W_AVAILABLE) {
@@ -11958,6 +11989,12 @@ ImmModel::discardNode(unsigned int deadN
ci2->second.mTimeout = 1; /* one second is minimum
timeout. */
}
}
+
+ if(isAtCoord){
+ // pushing to implv to find the ccbIds with implemeter id
which are going to be disconnected.
+ // Later abort the CcbId. This is done only at co-ordinator.
+ implv.push_back(info->mId);
+ }
//discardImplementer(info->mId);
//Doing it directly here for efficiency.
//But watch out for changes in discardImplementer
@@ -11986,6 +12023,23 @@ ImmModel::discardNode(unsigned int deadN
//implementer.
}
}
+ /*
+ Fethes CcbIds which are non-critcal and Ccbs has implementer which are
+ going to be disconnected, because of node down. This is done only at
co-ordinator.
+
+ */
+ if(isAtCoord && (implv.size()>0)){
+ CcbImplementerMap::iterator isi;
+ for(i4 = implv.begin(); i4!=implv.end(); ++i4) {
+ for(i3=sCcbVector.begin(); i3!=sCcbVector.end(); ++i3) {
+ isi = ((*i3)->mImplementers.find(*i4));
+ if(isi != ((*i3)->mImplementers.end()) && ((*i3)->mState <
IMM_CCB_CRITICAL)) {
+ gv.push_back((*i3)->mId);
+ }
+ }
+ }
+ }
+
//Discard AdminOwners
i2 = sOwnerVector.begin();
@@ -12014,11 +12068,14 @@ ImmModel::discardNode(unsigned int deadN
}
void
-ImmModel::discardImplementer(unsigned int implHandle, bool reallyDiscard)
+ImmModel::discardImplementer(unsigned int implHandle, bool reallyDiscard,
IdVector& gv, bool isAtCoord)
{
//Note: If this function is altered, then you may need to make
//changes in ImmModel::discardNode, since that function also deletes
//implementers.
+ CcbVector::iterator i1;
+ SaUint32T mid;
+
TRACE_ENTER();
ImplementerInfo* info = findImplementer(implHandle);
if(info) {
@@ -12030,6 +12087,18 @@ ImmModel::discardImplementer(unsigned in
//Note the time of death and id of the demised implementer.
sImplDetachTime[info] = ContinuationInfo2(info->mId,
DEFAULT_TIMEOUT_SEC);
+ if(isAtCoord){
+ // Find the Non-critical ccbs with implemeter id which are
going to be Disconnected.
+ // Later abort the CCBId. This is done only at co-ordinator.
+ mid = info->mId;
+ CcbImplementerMap::iterator isi;
+ for(i1=sCcbVector.begin(); i1!=sCcbVector.end(); ++i1) {
+ isi = (*i1)->mImplementers.find(mid);
+ if(isi != ((*i1)->mImplementers.end()) && ((*i1)->mState <
IMM_CCB_CRITICAL)) {
+ gv.push_back((*i1)->mId);
+ }
+ }
+ }
info->mId = 0;
info->mConn = 0;
@@ -13931,6 +14000,7 @@ ImmModel::implementerClear(const struct
unsigned int nodeId)
{
SaAisErrorT err = SA_AIS_OK;
+ ConnVector gv;
TRACE_ENTER();
ImplementerInfo* info = findImplementer(req->impl_id);
@@ -13939,7 +14009,7 @@ ImmModel::implementerClear(const struct
/* Sync is ongoing and we are a sync client.
Remember the death of the implementer.
*/
- discardImplementer(req->impl_id, true);
+ discardImplementer(req->impl_id, true, gv, false);
goto done;
}
LOG_NO("ERR_BAD_HANDLE: Not a correct implementer handle? %llu id:%u",
@@ -13952,7 +14022,7 @@ ImmModel::implementerClear(const struct
conn, nodeId);
err = SA_AIS_ERR_BAD_HANDLE;
} else {
- discardImplementer(req->impl_id, true);
+ discardImplementer(req->impl_id, true, gv, false);
}
}
@@ -17301,9 +17371,9 @@ ImmModel::finalizeSync(ImmsvOmFinalizeSy
if(!sNodesDeadDuringSync.empty()) {
IdVector::iterator ivi = sNodesDeadDuringSync.begin();
for(;ivi != sNodesDeadDuringSync.end(); ++ivi) {
- ConnVector cv;
+ ConnVector cv, gv;
LOG_NO("Sync client re-executing discardNode for node %x",
(*ivi));
- this->discardNode((*ivi), cv);
+ this->discardNode((*ivi), cv, gv, false);
if(!(cv.empty())) {
LOG_ER("Sync can not discard node with active ccbs");
err = SA_AIS_ERR_FAILED_OPERATION;
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
@@ -533,9 +533,11 @@ public:
SaUint32T getImplementerId(SaUint32T localConn);
void discardImplementer(
unsigned int implHandle,
- bool reallyDiscard);
+ bool reallyDiscard,
+ IdVector& gv,
+ bool isAtCoord);
void discardContinuations(SaUint32T dead);
- void discardNode(unsigned int nodeId, IdVector& cv);
+ void discardNode(unsigned int nodeId, IdVector& cv, IdVector&
gv, bool isAtCoord);
void getCcbIdsForOrigCon(SaUint32T dead, IdVector& cv);
void getAdminOwnerIdsForCon(SaUint32T dead, IdVector& cv);
bool ccbCommit(SaUint32T ccbId, ConnVector& connVector);
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
@@ -8781,10 +8781,24 @@ static void immnd_evt_proc_discard_impl(
IMMND_EVT *evt,
SaBoolT originatedAtThisNd,
SaImmHandleT clnt_hdl, MDS_DEST reply_dest)
{
+ SaUint32T *globIdArr = NULL;
+ SaUint32T globArrSize = 0;
TRACE_ENTER();
osafassert(evt);
TRACE_2("Global discard implementer for id:%u",
evt->info.implSet.impl_id);
- immModel_discardImplementer(cb, evt->info.implSet.impl_id, SA_TRUE);
+ immModel_discardImplementer(cb, evt->info.implSet.impl_id, SA_TRUE,
&globArrSize, &globIdArr);
+ if(globArrSize) {
+ SaUint32T ix;
+ for (ix = 0; ix < globArrSize; ++ix) {
+ LOG_WA("Discard implementer for id %u, abort
Non-critical ccbId %u which has "
+ "discarded implementer",
evt->info.implSet.impl_id, globIdArr[ix]);
+ immnd_proc_global_abort_ccb(cb, globIdArr[ix]);
+ }
+ free(globIdArr);
+ globIdArr = NULL;
+ globArrSize = 0;
+ }
+
TRACE_LEAVE();
}
@@ -8809,6 +8823,9 @@ static void immnd_evt_proc_discard_node(
{
SaUint32T *idArr = NULL;
SaUint32T arrSize = 0;
+ SaUint32T *globIdArr = NULL;
+ SaUint32T globArrSize = 0;
+
TRACE_ENTER();
osafassert(evt);
if(evt->info.ctrl.nodeId == cb->node_id) {
@@ -8822,7 +8839,19 @@ static void immnd_evt_proc_discard_node(
causing a newly reattached node being discarded.
*/
cb->mLostNodes++;
- immModel_discardNode(cb, evt->info.ctrl.nodeId, &arrSize, &idArr);
+ immModel_discardNode(cb, evt->info.ctrl.nodeId, &arrSize, &idArr,
&globArrSize, &globIdArr);
+ if(globArrSize) {
+ SaUint32T ix;
+ for (ix = 0; ix < globArrSize; ++ix) {
+ LOG_WA("Detected crash at node %x, abort Non-critical
ccbId %u which has implementer "
+ "on the crashed node ", evt->info.ctrl.nodeId,
globIdArr[ix]);
+ immnd_proc_global_abort_ccb(cb, globIdArr[ix]);
+ }
+ free(globIdArr);
+ globIdArr = NULL;
+ globArrSize = 0;
+ }
+
if (arrSize) {
SaAisErrorT err = SA_AIS_OK;
SaUint32T ix;
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
@@ -150,7 +150,8 @@ extern "C" {
void immModel_getCcbIdsForOrigCon(IMMND_CB *cb, SaUint32T origConn,
SaUint32T *arrSize, SaUint32T **ccbIdArr);
- void immModel_discardNode(IMMND_CB *cb, SaUint32T nodeId, SaUint32T
*arrSize, SaUint32T **ccbIdArr);
+ void immModel_discardNode(IMMND_CB *cb, SaUint32T nodeId, SaUint32T
*arrSize, SaUint32T **ccbIdArr,
+ SaUint32T* globArrSize, SaUint32T** globccbIdArr);
SaAisErrorT
immModel_ccbObjectDelete(IMMND_CB *cb,
@@ -254,7 +255,8 @@ extern "C" {
SaUint32T implConn, SaUint32T
implNodeId);
SaUint32T immModel_getImplementerId(IMMND_CB *cb, SaUint32T implConn);
- void immModel_discardImplementer(IMMND_CB *cb, SaUint32T implId,
SaBoolT reallyDiscard);
+ void immModel_discardImplementer(IMMND_CB *cb, SaUint32T implId,
SaBoolT reallyDiscard,
+ SaUint32T* globArrSize,
SaUint32T** globccbIdArr);
void immModel_fetchAdmOpContinuations(IMMND_CB *cb, SaInvocationT inv,
SaBoolT local, SaUint32T
*implConn,
diff --git a/osaf/services/saf/immsv/immnd/immnd_proc.c
b/osaf/services/saf/immsv/immnd/immnd_proc.c
--- a/osaf/services/saf/immsv/immnd/immnd_proc.c
+++ b/osaf/services/saf/immsv/immnd/immnd_proc.c
@@ -142,7 +142,7 @@ uint32_t immnd_proc_imma_discard_connect
/*Discard the local implementer directly and redundantly to
avoid
race conditions using this implementer (ccb's causing abort
upcalls).
*/
- immModel_discardImplementer(cb, implId, SA_FALSE);
+ immModel_discardImplementer(cb, implId, SA_FALSE, NULL, NULL);
}
if (cl_node->mIsStale) {
------------------------------------------------------------------------------
_______________________________________________
Opensaf-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensaf-devel