osaf/services/saf/immsv/immnd/ImmModel.cc  |  86 +++++++++++++++++++++++++++++-
 osaf/services/saf/immsv/immnd/ImmModel.hh  |   2 +
 osaf/services/saf/immsv/immnd/immnd_init.h |   4 +
 osaf/services/saf/immsv/immnd/immnd_proc.c |  43 +++++++++++---
 4 files changed, 123 insertions(+), 12 deletions(-)


When discarding a client, there are chances that IMMND fails to send 
impl/admo/ccb discard messages or IMMD can't receive those messages.
In that case, we have to make sure that those messages are re-sent.
If not, we will have admo/ccb resource leak or implementers marked as dying 
forever.
DEFAULT_TIMEOUT_SEC (6sec) is used as retry interval.

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
@@ -534,6 +534,8 @@ static IdVector         sImplsDeadDuring
                                               // but before it arrives over 
fevs. 
                                               // This to avoid apparent 
implementor
                                               // re-create by finalizeSync (at 
non coord). 
+static ContinuationMap2 sDiscardingClientMap; /* Make sure that impl/ccb/admo 
associated with
+                                                the client are discarded 
successfully */
 
 static DeferredObjUpdatesMap sDeferredObjUpdatesMap;
 
@@ -1170,6 +1172,8 @@ immModel_cleanTheBasement(IMMND_CB *cb,
     SaUint32T* searchReqArrSize,
     SaUint32T** ccbIdArr,
     SaUint32T* ccbIdArrSize,
+    SaUint32T** clientIdArr,
+    SaUint32T* clientIdArrSize,
     SaUint32T** pbePrtoReqArr,
     SaUint32T* pbePrtoReqArrSize,
     SaBoolT iAmCoordNow)
@@ -1178,6 +1182,7 @@ immModel_cleanTheBasement(IMMND_CB *cb,
     InvocVector searchReqs;
     InvocVector::iterator ix1;
     IdVector ccbs;
+    IdVector clients;
     IdVector pbePrtoReqs;
     IdVector::iterator ix2;
     unsigned int ix;
@@ -1187,6 +1192,7 @@ immModel_cleanTheBasement(IMMND_CB *cb,
         admReqs, 
         searchReqs, 
         ccbs,
+        clients,
         pbePrtoReqs,
         iAmCoordNow);
 
@@ -1226,6 +1232,16 @@ immModel_cleanTheBasement(IMMND_CB *cb,
         osafassert(ix==(*ccbIdArrSize));
     }
 
+    *clientIdArrSize = (SaUint32T) clients.size();
+    if (*clientIdArrSize) {
+        *clientIdArr = (SaUint32T *) malloc((*clientIdArrSize) * 
sizeof(SaUint32T));
+
+        for (ix2 = clients.begin(), ix = 0; ix2 != clients.end(); ++ix2, ++ix) 
{
+            (*clientIdArr)[ix] = (*ix2);
+        }
+        osafassert(ix == (*clientIdArrSize));
+    }
+
     *pbePrtoReqArrSize = (SaUint32T) pbePrtoReqs.size();
     if(*pbePrtoReqArrSize) {
         *pbePrtoReqArr = (SaUint32T *) 
@@ -2146,6 +2162,11 @@ immModel_prepareForSync(IMMND_CB *cb, Sa
     ImmModel::instance(&cb->immModel)->prepareForSync(isJoining);
 }
 
+void immModel_addDiscardingClient(IMMND_CB *cb, SaUint32T clientId)
+{
+    ImmModel::instance(&cb->immModel)->addDiscardingClient(clientId);
+}
+
 void
 immModel_discardContinuations(IMMND_CB *cb, SaUint32T deadConn)
 {
@@ -13375,6 +13396,26 @@ ImmModel::discardImplementer(unsigned in
 }
 
 void
+ImmModel::addDiscardingClient(SaUint32T clientId)
+{
+    TRACE_ENTER();
+
+    ContinuationMap2::iterator ci = sDiscardingClientMap.find(clientId);
+    if (ci == sDiscardingClientMap.end()) {
+        TRACE("Add discarding client %u", clientId);
+        sDiscardingClientMap[clientId] = ContinuationInfo2(0 /*Unused*/, 
DEFAULT_TIMEOUT_SEC);
+    } else {
+        /* Update the create-time */
+        TRACE("Update time for discarding client %u", clientId);
+        osaf_clock_gettime_sec(CLOCK_MONOTONIC, &(ci->second.mCreateTime));
+        osafassert(ci->second.mCreateTime >= ((time_t) 0));
+    }
+
+    TRACE_LEAVE();
+    return;
+}
+
+void
 ImmModel::discardContinuations(SaUint32T dead)
 {
     TRACE_ENTER();
@@ -13730,7 +13771,7 @@ ImmModel::purgeSyncRequest(SaUint32T cli
 
 SaUint32T
 ImmModel::cleanTheBasement(InvocVector& admReqs,
-    InvocVector& searchReqs, IdVector& ccbs, IdVector& pbePrtoReqs,
+    InvocVector& searchReqs, IdVector& ccbs, IdVector& clients, IdVector& 
pbePrtoReqs,
     bool iAmCoord)
 {
     time_t now;
@@ -13875,6 +13916,49 @@ ImmModel::cleanTheBasement(InvocVector& 
         delete (ccb);
     }
 
+    ci2 = sDiscardingClientMap.begin();
+    while (ci2 != sDiscardingClientMap.end()) {
+        SaUint32T implId;
+        ConnVector cv;
+
+        /* Check if there's still implementer associated with the client */
+        implId = getImplementerId(ci2->first);
+        if (implId) {
+            TRACE("client %llu is not completely discarded", ci2->first);
+            if (now - ci2->second.mCreateTime >= (DEFAULT_TIMEOUT_SEC)) {
+                clients.push_back(ci2->first);
+            }
+            ++ci2;
+            continue;
+        }
+
+        /* Check if there're still CCBs associated with the client */
+        getCcbIdsForOrigCon(ci2->first, cv);
+        if (cv.size()) {
+            TRACE("client %llu is not completely discarded", ci2->first);
+            if (now - ci2->second.mCreateTime >= (DEFAULT_TIMEOUT_SEC)) {
+                clients.push_back(ci2->first);
+            }
+            ++ci2;
+            continue;
+        }
+
+        /* Check if there're still admos associated with the client */
+        cv.clear();
+        getAdminOwnerIdsForCon(ci2->first, cv);
+        if (cv.size()) {
+            TRACE("client %llu is not completely discarded", ci2->first);
+            if (now - ci2->second.mCreateTime >= (DEFAULT_TIMEOUT_SEC)) {
+                clients.push_back(ci2->first);
+            }
+            ++ci2;
+            continue;
+        }
+
+        TRACE("client %llu is completely discarded, remove it", ci2->first);
+        ci2 = sDiscardingClientMap.erase(ci2); /* C++11 */
+    }
+
     ci2=sPbeRtReqContinuationMap.begin(); 
     while(ci2!=sPbeRtReqContinuationMap.end()) {
         //Timeout on PRT request continuation is hardwired but long.
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
@@ -557,6 +557,7 @@ public:
                                          bool reallyDiscard,
                                         IdVector& gv, 
                                         bool isAtCoord);
+    void              addDiscardingClient(SaUint32T clientId);
     void              discardContinuations(SaUint32T dead);
     void              discardNode(unsigned int nodeId, IdVector& cv, IdVector& 
gv, bool isAtCoord, bool scAbsence);
     void              getCcbIdsForOrigCon(SaUint32T dead, IdVector& cv);
@@ -572,6 +573,7 @@ public:
                                        InvocVector& admReqs,
                                        InvocVector& searchReqs,
                                        IdVector& ccbs,
+                                       IdVector& clients,
                                        IdVector& pbePrtoReqs,
                                        bool iAmCoord);
     
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
@@ -133,6 +133,8 @@ extern "C" {
                SaUint32T *searchReqArrSize,
                SaUint32T **ccbIdArr,
                SaUint32T *ccbIdArrSize, 
+               SaUint32T **clientIdArr,
+               SaUint32T *clientIdArrSize,
                SaUint32T **pbePrtoReqIdArr,
                SaUint32T *pbePrtoReqArrSize, 
                SaBoolT iAmCoordNow);
@@ -379,6 +381,8 @@ extern "C" {
                                               SaUint32T ccbId,
                                               SaUint32T invocation, 
SaAisErrorT error, SaUint32T *reqConn);
 
+       void immModel_addDiscardingClient(IMMND_CB *cb, SaUint32T clientId);
+
        void immModel_discardContinuations(IMMND_CB *cb, SaUint32T deadConn);
 
        SaBoolT immModel_immNotWritable(IMMND_CB *cb);
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
@@ -133,13 +133,13 @@ uint32_t immnd_proc_imma_discard_connect
 
                if (!scAbsence && immnd_mds_msg_send(cb, NCSMDS_SVC_ID_IMMD, 
cb->immd_mdest_id, &send_evt) != NCSCC_RC_SUCCESS) {
                        if (immnd_is_immd_up(cb)) {
-                               LOG_ER("Discard implementer failed for 
implId:%u "
-                                      "but IMMD is up !? - case not handled. 
Client will be orphanded", implId);
+                               LOG_WA("Discard implementer failed for 
implId:%u "
+                                      "but IMMD is up !? will retry later ", 
implId);
                        } else {
                                LOG_WA("Discard implementer failed for 
implId:%u "
                                       "(immd_down)- will retry later", implId);
+                               cl_node->mIsStale = true;
                        }
-                       cl_node->mIsStale = true;
                }
                /*Discard the local implementer directly and redundantly to 
avoid 
                   race conditions using this implementer (ccb's causing abort 
upcalls).
@@ -171,14 +171,13 @@ uint32_t immnd_proc_imma_discard_connect
                        if (immnd_mds_msg_send(cb, NCSMDS_SVC_ID_IMMD, 
cb->immd_mdest_id,
                                               &send_evt) != NCSCC_RC_SUCCESS) {
                                if (immnd_is_immd_up(cb)) {
-                                       LOG_ER("Failure to broadcast discard 
Ccb for ccbId:%u "
-                                              "but IMMD is up !? - case not 
handled. Client will "
-                                              "be orphanded", implId);
+                                       LOG_WA("Failure to broadcast discard 
Ccb for ccbId:%u "
+                                              "but IMMD is up !? - will retry 
later", implId);
                                } else {
                                        LOG_WA("Failure to broadcast discard 
Ccb for ccbId:%u "
                                               "(immd down)- will retry later", 
idArr[ix]);
+                                       cl_node->mIsStale = true;
                                }
-                               cl_node->mIsStale = true;
                        }
                }
                free(idArr);
@@ -216,14 +215,13 @@ uint32_t immnd_proc_imma_discard_connect
                                if(immnd_mds_msg_send(cb, NCSMDS_SVC_ID_IMMD, 
cb->immd_mdest_id,
                                               &send_evt) != NCSCC_RC_SUCCESS) {
                                        if (immnd_is_immd_up(cb)) {
-                                               LOG_ER("Failure to broadcast 
discard admo0wner for ccbId:%u "
-                                                       "but IMMD is up !? - 
case not handled. Client will "
-                                                       "be orphanded", implId);
+                                               LOG_WA("Failure to broadcast 
discard admo0wner for ccbId:%u "
+                                                       "but IMMD is up !? - 
will retry later", implId);
                                        } else {
                                                LOG_WA("Failure to broadcast 
discard admowner for id:%u "
                                                        "(immd down)- will 
retry later", idArr[ix]);
+                                               cl_node->mIsStale = true;
                                        }
-                                       cl_node->mIsStale = true;
                                }
                        }
                }
@@ -234,6 +232,12 @@ uint32_t immnd_proc_imma_discard_connect
 
        if (!cl_node->mIsStale) {
                TRACE_5("Discard connection id:%llx succeeded", 
cl_node->imm_app_hdl);
+
+               /* Add the discarding client to continuation map */
+               immModel_addDiscardingClient(cb, client_id);
+
+               /* Don't add stale clients to the map. They will be discarded by
+                * immnd_proc_imma_discard_stales() when IMMD is up again. */
        }
 
        TRACE_LEAVE();
@@ -986,6 +990,8 @@ static void immnd_cleanTheHouse(IMMND_CB
        SaUint32T searchReqArrSize = 0;
        SaUint32T *ccbIdArr = NULL;
        SaUint32T ccbIdArrSize = 0;
+       SaUint32T *clientIdArr = NULL;
+       SaUint32T clientIdArrSize = 0;
        SaUint32T *pbePrtoReqArr = NULL;
        SaUint32T pbePrtoReqArrSize = 0;
 
@@ -1082,6 +1088,8 @@ static void immnd_cleanTheHouse(IMMND_CB
                &searchReqArrSize,
                &ccbIdArr,
                &ccbIdArrSize,
+               &clientIdArr,
+               &clientIdArrSize,
                &pbePrtoReqArr,
                &pbePrtoReqArrSize,
                iAmCoordNow);
@@ -1261,6 +1269,19 @@ static void immnd_cleanTheHouse(IMMND_CB
                free(ccbIdArr);
        }
 
+       if (clientIdArrSize) {
+               for (ix = 0; ix < clientIdArrSize; ++ix) {
+                       /* The client-node is deleted in the first attempt of 
discarding.
+                        * Create a dummy client-node for the client-id */
+                       IMMND_IMM_CLIENT_NODE dummy_node;
+                       memset(&dummy_node, 0, sizeof(IMMND_IMM_CLIENT_NODE));
+                       dummy_node.imm_app_hdl = 
m_IMMSV_PACK_HANDLE(clientIdArr[ix], cb->node_id);
+
+                       immnd_proc_imma_discard_connection(cb, &dummy_node, 
false);
+               }
+               free(clientIdArr);
+       }
+
        if (pbePrtoReqArrSize) {
                IMMSV_EVT reply;
                memset(&reply, 0, sizeof(IMMSV_EVT));

------------------------------------------------------------------------------
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. https://ad.doubleclick.net/ddm/clk/305295220;132659582;e
_______________________________________________
Opensaf-devel mailing list
Opensaf-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/opensaf-devel

Reply via email to