In a large cluster size, it is impossible to adjust MDS wait time for all
clients in cluster by change IMMA_SYNC_TIMEOUT environment variable.
Because technique environment variable needs to restart to apply the changed
variable and it is a time-consuming.

This ticket introduce a configurable attribute `saImmSyncrTimeout`
to `SaImmMngt` class, that distribute the new timeout to all IMM clients
and force them to use the new timeout. If user deletes value of attribute
`saImmSyncrTimeout`, it will go back to default value (0). And it is will
keep backward compatible with IMMA_SYNC_TIMEOUT technique.
In default, this feature is disabled.

Correct value of variable environment IMMA_SYNCR_TIMEOUT when set a value
less than 10 will only be interpreted as the value 10.
---
 src/imm/agent/imma.h             |  2 ++
 src/imm/agent/imma_init.cc       | 14 ++++++++
 src/imm/agent/imma_oi_api.cc     | 18 +++++-----
 src/imm/agent/imma_om_api.cc     | 19 +++++-----
 src/imm/agent/imma_proc.cc       | 35 ++++++++++++++++++
 src/imm/common/immsv_evt.h       |  3 ++
 src/imm/common/immsv_evt_model.h |  5 +++
 src/imm/config/immsv_classes.xml |  8 +++++
 src/imm/immnd/ImmAttrValue.cc    | 22 ++++++++++++
 src/imm/immnd/ImmAttrValue.h     |  2 ++
 src/imm/immnd/ImmModel.cc        | 62 +++++++++++++++++++++++++++++---
 src/imm/immnd/ImmModel.h         |  4 ++-
 src/imm/immnd/immnd_cb.h         |  1 +
 src/imm/immnd/immnd_evt.c        | 50 ++++++++++++++++++++++++++
 src/imm/immnd/immnd_init.h       |  1 +
 15 files changed, 222 insertions(+), 24 deletions(-)

diff --git a/src/imm/agent/imma.h b/src/imm/agent/imma.h
index c13e51203..5803b5237 100644
--- a/src/imm/agent/imma.h
+++ b/src/imm/agent/imma.h
@@ -56,4 +56,6 @@ SaAisErrorT imma_evt_fake_evs(IMMA_CB *cb, IMMSV_EVT *i_evt, 
IMMSV_EVT **o_evt,
 SaAisErrorT imma_proc_check_stale(IMMA_CB *cb, SaImmHandleT immHandle,
                                   SaAisErrorT defaultEr);
 
+SaTimeT imma_getEnvSyncrTimeout();
+
 #endif  // IMM_AGENT_IMMA_H_
diff --git a/src/imm/agent/imma_init.cc b/src/imm/agent/imma_init.cc
index bde657158..3a056a1c6 100644
--- a/src/imm/agent/imma_init.cc
+++ b/src/imm/agent/imma_init.cc
@@ -602,3 +602,17 @@ SaImmAttrValueT imma_copyAttrValue3(const SaImmValueTypeT 
attrValueType,
   }
   return retVal;
 }
+
+SaTimeT imma_getEnvSyncrTimeout() {
+  SaTimeT syncr_timeout = IMMSV_WAIT_TIME;
+  char *timeout_env_value = NULL;
+
+  if ((timeout_env_value = getenv("IMMA_SYNCR_TIMEOUT"))) {
+    syncr_timeout = atoll(timeout_env_value);
+    if (syncr_timeout < NCS_SAF_MIN_ACCEPT_TIME) {
+      LOG_WA("Invalid IMMA_SYNCR_TIMEOUT environment variable");
+      syncr_timeout = NCS_SAF_MIN_ACCEPT_TIME;
+    }
+  }
+  return syncr_timeout;
+}
diff --git a/src/imm/agent/imma_oi_api.cc b/src/imm/agent/imma_oi_api.cc
index c79d0e315..9fff8f83d 100644
--- a/src/imm/agent/imma_oi_api.cc
+++ b/src/imm/agent/imma_oi_api.cc
@@ -187,15 +187,9 @@ SaAisErrorT initialize_common(SaImmOiHandleT *immOiHandle,
     }
   }
 
-  if ((timeout_env_value = getenv("IMMA_SYNCR_TIMEOUT")) != NULL) {
-    cl_node->syncr_timeout = atoi(timeout_env_value);
-    TRACE_2("IMMA library syncronous timeout set to:%lld",
-            cl_node->syncr_timeout);
-  }
-
-  if (cl_node->syncr_timeout < NCS_SAF_MIN_ACCEPT_TIME) {
-    cl_node->syncr_timeout = IMMSV_WAIT_TIME; /* Default */
-  }
+  cl_node->syncr_timeout = imma_getEnvSyncrTimeout();
+  TRACE_2("IMMA library syncronous timeout set to:%lld",
+          cl_node->syncr_timeout);
 
   if (cl_node->isImmA2e &&
       (timeout_env_value = getenv("IMMA_OI_CALLBACK_TIMEOUT")) != NULL) {
@@ -309,6 +303,12 @@ SaAisErrorT initialize_common(SaImmOiHandleT *immOiHandle,
     }
 
     cl_node->handle = out_evt->info.imma.info.initRsp.immHandle;
+    SaTimeT timeout = out_evt->info.imma.info.initRsp.syncrTimeout;
+    if (timeout >= NCS_SAF_MIN_ACCEPT_TIME) {
+      cl_node->syncr_timeout = timeout;
+      TRACE_2("IMMA library syncronous timeout set to:%lld",
+              cl_node->syncr_timeout);
+    }
 
     TRACE_1("Trying to add OI client id:%u node:%x handle:%llx",
             m_IMMSV_UNPACK_HANDLE_HIGH(cl_node->handle),
diff --git a/src/imm/agent/imma_om_api.cc b/src/imm/agent/imma_om_api.cc
index f34e7645c..847616dfb 100644
--- a/src/imm/agent/imma_om_api.cc
+++ b/src/imm/agent/imma_om_api.cc
@@ -238,7 +238,6 @@ static SaAisErrorT initialize_common(SaImmHandleT 
*immHandle,
   IMMSV_EVT init_evt;
   IMMSV_EVT *out_evt = NULL;
   bool locked = true;
-  char *timeout_env_value = NULL;
   char *value;
   TRACE_ENTER();
   osafassert(immHandle && cl_node);
@@ -262,15 +261,9 @@ static SaAisErrorT initialize_common(SaImmHandleT 
*immHandle,
     goto clm_left;
   }
 
-  if ((timeout_env_value = getenv("IMMA_SYNCR_TIMEOUT")) != NULL) {
-    cl_node->syncr_timeout = atoi(timeout_env_value);
-    TRACE_2("IMMA library syncronous timeout set to:%lld",
-            cl_node->syncr_timeout);
-  }
-
-  if (cl_node->syncr_timeout < NCS_SAF_MIN_ACCEPT_TIME) {
-    cl_node->syncr_timeout = IMMSV_WAIT_TIME; /* Default */
-  }
+  cl_node->syncr_timeout = imma_getEnvSyncrTimeout();
+  TRACE_2("IMMA library syncronous timeout set to:%lld",
+          cl_node->syncr_timeout);
 
   *immHandle = 0;
 
@@ -362,6 +355,12 @@ static SaAisErrorT initialize_common(SaImmHandleT 
*immHandle,
 
     cl_node->handle = out_evt->info.imma.info.initRsp.immHandle;
     cl_node->isOm = true;
+    SaTimeT timeout = out_evt->info.imma.info.initRsp.syncrTimeout;
+    if (timeout >= NCS_SAF_MIN_ACCEPT_TIME) {
+      cl_node->syncr_timeout = timeout;
+      TRACE_2("IMMA library syncronous timeout set to:%lld",
+              cl_node->syncr_timeout);
+    }
 
     cl_node->maxSearchHandles = 100;
     if ((value = getenv("IMMA_MAX_OPEN_SEARCHES_PER_HANDLE"))) {
diff --git a/src/imm/agent/imma_proc.cc b/src/imm/agent/imma_proc.cc
index 723550904..5833b69fe 100644
--- a/src/imm/agent/imma_proc.cc
+++ b/src/imm/agent/imma_proc.cc
@@ -1404,6 +1404,9 @@ void imma_proc_free_pointers(IMMA_CB *cb, IMMA_EVT *evt) {
     case IMMA_EVT_ND2A_PROC_STALE_CLIENTS:
       break;
 
+    case IMMA_EVT_ND2A_IMM_SYNCR_TIMEOUT:
+      break;
+
     default:
       TRACE_4("Unknown event type %u", evt->type);
       break;
@@ -1435,6 +1438,34 @@ static void imma_proc_clm_status_changed(IMMA_CB *cb, 
IMMA_EVT *evt) {
   m_NCS_UNLOCK(&cb->cb_lock, NCS_LOCK_WRITE);
 }
 
+static void imma_proc_syncr_timeout_update(IMMA_CB *cb, IMMA_EVT *evt) {
+  TRACE_ENTER();
+  IMMA_CLIENT_NODE *cl_node = NULL;
+  SaImmHandleT impl_handle = evt->info.immaTimeoutUpdate.immHandle;
+
+  /* get the CB Lock */
+  if (m_NCS_LOCK(&cb->cb_lock, NCS_LOCK_WRITE) != NCSCC_RC_SUCCESS) {
+    TRACE_3("Lock failure");
+    return;
+  }
+
+  /* Get the Client info */
+  imma_client_node_get(&cb->client_tree, &impl_handle, &cl_node);
+  if (cl_node == NULL) {
+    m_NCS_UNLOCK(&cb->cb_lock, NCS_LOCK_WRITE);
+    TRACE_3("Could not find client node impl_handle: %llx", impl_handle);
+    return;
+  }
+  cl_node->syncr_timeout = evt->info.immaTimeoutUpdate.syncrTimeout;
+  if (cl_node->syncr_timeout == 0) {
+    cl_node->syncr_timeout = imma_getEnvSyncrTimeout();
+  }
+  TRACE_3("IMMA library syncronous timeout set to:%lld",
+          cl_node->syncr_timeout);
+  m_NCS_UNLOCK(&cb->cb_lock, NCS_LOCK_WRITE);
+  TRACE_LEAVE();
+}
+
 /****************************************************************************
   Name          : imma_process_evt
   Description   : This routine will process the callback event received from
@@ -1507,6 +1538,10 @@ void imma_process_evt(IMMA_CB *cb, IMMSV_EVT *evt) {
       imma_proc_clm_status_changed(cb, &evt->info.imma);
       break;
 
+    case IMMA_EVT_ND2A_IMM_SYNCR_TIMEOUT:
+      imma_proc_syncr_timeout_update(cb, &evt->info.imma);
+      break;
+
     default:
       TRACE_4("Unknown event type %u", evt->info.imma.type);
       break;
diff --git a/src/imm/common/immsv_evt.h b/src/imm/common/immsv_evt.h
index d8f7c0b82..d1f2a3b99 100644
--- a/src/imm/common/immsv_evt.h
+++ b/src/imm/common/immsv_evt.h
@@ -105,6 +105,7 @@ typedef enum imma_evt_type {
       34, /* when clm-lock/clm-node left the cluster */
   IMMA_EVT_ND2A_IMM_CLM_NODE_JOINED =
       35, /* when clm-lock/clm-node join the cluster */
+  IMMA_EVT_ND2A_IMM_SYNCR_TIMEOUT = 36,
 
   IMMA_EVT_MAX
 } IMMA_EVT_TYPE;
@@ -397,6 +398,7 @@ typedef struct immsv_oi_search_remote_rsp {
 typedef struct immsv_nd2a_init_rsp {
   SaImmHandleT immHandle;
   SaAisErrorT error;
+  SaTimeT syncrTimeout;
 } IMMSV_ND2A_INIT_RSP;
 
 /* AdminOwnerInit Response */
@@ -557,6 +559,7 @@ typedef struct imma_evt {
     IMMSV_OM_CLASS_DESCR classDescr;
     IMMSV_ND2A_IMPLSET_RSP implSetRsp;
     IMMA_TMR_INFO tmr_info;
+    IMMA_SYNCR_TIMEOUT_UPDATE immaTimeoutUpdate;
   } info;
 
 } IMMA_EVT;
diff --git a/src/imm/common/immsv_evt_model.h b/src/imm/common/immsv_evt_model.h
index 655459844..3d30bde4e 100644
--- a/src/imm/common/immsv_evt_model.h
+++ b/src/imm/common/immsv_evt_model.h
@@ -297,6 +297,11 @@ typedef struct ImmsvSyncFevsBase {
   SaImmHandleT client_hdl;  // odd to put client_hdl here..
 } IMMSV_SYNC_FEVS_BASE;
 
+typedef struct ImmaSyncrTimeoutUpdate {
+  SaUint64T immHandle;
+  SaTimeT syncrTimeout;
+} IMMA_SYNCR_TIMEOUT_UPDATE;
+
 /* Macros to pack and unpack imm handles */
 #define m_IMMSV_PACK_HANDLE(high, low) \
   ((((SaUint64T)high) << 32) | ((SaUint32T)low))
diff --git a/src/imm/config/immsv_classes.xml b/src/imm/config/immsv_classes.xml
index 193ccd2e2..958da26e8 100644
--- a/src/imm/config/immsv_classes.xml
+++ b/src/imm/config/immsv_classes.xml
@@ -52,5 +52,13 @@
                        <category>SA_RUNTIME</category>
                        <flag>SA_CACHED</flag>
                </attr>
+               <attr>
+                       <name>saImmSyncrTimeout</name>
+                       <type>SA_TIME_T</type>
+                       <category>SA_CONFIG</category>
+                       <flag>SA_WRITABLE</flag>
+                       <flag>SA_STRONG_DEFAULT</flag>
+                       <default-value>0</default-value>
+               </attr>
        </class>
 </imm:IMM-contents>
diff --git a/src/imm/immnd/ImmAttrValue.cc b/src/imm/immnd/ImmAttrValue.cc
index 3fb5eddf9..694d55664 100644
--- a/src/imm/immnd/ImmAttrValue.cc
+++ b/src/imm/immnd/ImmAttrValue.cc
@@ -102,6 +102,28 @@ int ImmAttrValue::getValue_int() const {
   return *((int*)mValue);
 }
 
+void ImmAttrValue::setValue_satimet(SaTimeT i) {
+  if (mValue && mValueSize != sizeof(SaTimeT)) {
+    delete[] mValue;
+    mValue = 0;
+    mValueSize = 0;
+  }
+
+  if (!mValue) {
+    mValueSize = sizeof(SaTimeT);
+    mValue = new char[mValueSize];
+  }
+  *(reinterpret_cast<SaTimeT*>(mValue)) = i;
+}
+
+SaTimeT ImmAttrValue::getValue_satimet() const {
+  if (mValueSize != sizeof(SaTimeT)) {
+    return 0;
+  }
+
+  return *(reinterpret_cast<SaTimeT*>(mValue));
+}
+
 void ImmAttrValue::setValueC_str(const char* str) {
   if (mValue) {
     if (str) {
diff --git a/src/imm/immnd/ImmAttrValue.h b/src/imm/immnd/ImmAttrValue.h
index d922c7fe6..e0002fc3b 100644
--- a/src/imm/immnd/ImmAttrValue.h
+++ b/src/imm/immnd/ImmAttrValue.h
@@ -47,6 +47,8 @@ class ImmAttrValue {
 
   void setValue_int(int i);
   int getValue_int() const;
+  void setValue_satimet(SaTimeT i);
+  SaTimeT getValue_satimet() const;
   void setValueC_str(const char* str);
   const char* getValueC_str() const;
   void setValue(const IMMSV_OCTET_STRING& in);
diff --git a/src/imm/immnd/ImmModel.cc b/src/imm/immnd/ImmModel.cc
index 8631dc21f..e10335ae1 100644
--- a/src/imm/immnd/ImmModel.cc
+++ b/src/imm/immnd/ImmModel.cc
@@ -28,6 +28,7 @@
 #include "immnd.h"
 #include "base/osaf_unicode.h"
 #include "base/osaf_extended_name.h"
+#include "base/saf_def.h"
 
 // Local types
 #define DEFAULT_TIMEOUT_SEC 6  /* Should be saImmOiTimeout in SaImmMngt */
@@ -596,6 +597,7 @@ static const std::string immManagementDn(
 static const std::string saImmRepositoryInit("saImmRepositoryInit");
 static const std::string saImmOiTimeout("saImmOiTimeout");
 static const std::string saImmFileSystemStatus("saImmFileSystemStatus");
+static const std::string saImmSyncrTimeout("saImmSyncrTimeout");
 static SaImmRepositoryInitModeT immInitMode = SA_IMM_INIT_FROM_FILE;
 static bool sRegenerateDb = false;
 
@@ -947,11 +949,12 @@ SaAisErrorT immModel_ccbObjectModify(
   std::string objectName;
   bool pbeFile = (cb->mPbeFile != NULL);
   bool changeRim = false;
+  bool changeSyncr = false;
   SaAisErrorT err =
       ImmModel::instance(&cb->immModel)
           ->ccbObjectModify(req, implConn, implNodeId, continuationId, pbeConn,
                             pbeNodeId, objectName, hasLongDns, pbeFile,
-                            &changeRim);
+                            &changeRim, &changeSyncr);
 
   if (err == SA_AIS_OK) {
     osaf_extended_name_alloc(objectName.c_str(), objName);
@@ -962,6 +965,11 @@ SaAisErrorT immModel_ccbObjectModify(
     TRACE("The mPbeDisableCcbId is set to ccbid:%u", cb->mPbeDisableCcbId);
   }
 
+  if (err == SA_AIS_OK && changeSyncr) {
+    cb->mSyncrTimeout = true;
+    TRACE("Syncr Timeout is changed");
+  }
+
   return err;
 }
 
@@ -2069,6 +2077,10 @@ SaImmRepositoryInitModeT 
immModel_getRepositoryInitMode(IMMND_CB* cb) {
       ->getRepositoryInitMode();
 }
 
+SaTimeT immModel_getSyncrTimeout(IMMND_CB* cb) {
+  return ImmModel::instance(&cb->immModel)->getSyncrTimeout();
+}
+
 unsigned int immModel_getMaxSyncBatchSize(IMMND_CB* cb) {
   return ImmModel::instance(&cb->immModel)->getMaxSyncBatchSize();
 }
@@ -2964,6 +2976,22 @@ SaImmRepositoryInitModeT 
ImmModel::getRepositoryInitMode() {
   return SA_IMM_INIT_FROM_FILE;
 }
 
+SaTimeT ImmModel::getSyncrTimeout() {
+  ImmAttrValueMap::iterator avi;
+  ObjectInfo* immMgObject = NULL;
+  ObjectMap::iterator oi = sObjectMap.find(immManagementDn);
+  if (oi != sObjectMap.end()) {
+    immMgObject = oi->second;
+    avi = immMgObject->mAttrValueMap.find(saImmSyncrTimeout);
+
+    if (avi != immMgObject->mAttrValueMap.end()) {
+      osafassert(!avi->second->isMultiValued());
+      return avi->second->getValue_satimet();
+    }
+  }
+  return 0;
+}
+
 unsigned int ImmModel::getMaxSyncBatchSize() {
   TRACE_ENTER();
   unsigned int mbSize = 0;
@@ -9179,7 +9207,7 @@ SaAisErrorT ImmModel::ccbObjectModify(
     const ImmsvOmCcbObjectModify* req, SaUint32T* implConn,
     unsigned int* implNodeId, SaUint32T* continuationId, SaUint32T* pbeConnPtr,
     unsigned int* pbeNodeIdPtr, std::string& objectName, bool* hasLongDns,
-    bool pbeFile, bool* changeRim) {
+    bool pbeFile, bool* changeRim, bool* changeSyncr) {
   TRACE_ENTER();
   osafassert(hasLongDns);
   *hasLongDns = false;
@@ -9213,7 +9241,6 @@ SaAisErrorT ImmModel::ccbObjectModify(
   ObjectMutationMap::iterator omuti;
   ObjectMutation* oMut = 0;
   bool chainedOp = false;
-  immsv_attr_mods_list* p = req->attrMods;
   bool modifiedNotifyAttr = false;
   bool longDnsPermitted = getLongDnsAllowed();
 
@@ -9445,7 +9472,7 @@ SaAisErrorT ImmModel::ccbObjectModify(
     collectNoDanglingRefs(afim, afimPreOpNDRefs);
   }
 
-  for (p = req->attrMods; p; p = p->next) {
+  for (immsv_attr_mods_list* p = req->attrMods; p; p = p->next) {
     sz = strnlen((char*)p->attrValue.attrName.buf,
                  (size_t)p->attrValue.attrName.size);
     std::string attrName((const char*)p->attrValue.attrName.buf, sz);
@@ -9628,6 +9655,16 @@ SaAisErrorT ImmModel::ccbObjectModify(
                 attrName.c_str());
             osafassert(!attr->mDefaultValue.empty());
             (*attrValue) = attr->mDefaultValue;
+            if (modifiedImmMngt && (attrName == saImmSyncrTimeout)) {
+              SaTimeT oldSyncr = getSyncrTimeout();
+              SaTimeT newSyncr = attr->mDefaultValue.getValue_satimet();
+              if (oldSyncr != newSyncr) {
+                *changeSyncr = true;
+              } else {
+                LOG_NO("Skip update. Syncr timeout does not changed: %lld",
+                       newSyncr);
+              }
+            }
 
             TRACE("Canonicalizing attr-mod for attribute '%s'",
                   attrName.c_str());
@@ -9721,6 +9758,23 @@ SaAisErrorT ImmModel::ccbObjectModify(
           }
         }
 
+        if (modifiedImmMngt && (attrName == saImmSyncrTimeout)) {
+          SaTimeT oldSyncr = getSyncrTimeout();
+          SaTimeT newSyncr = attrValue->getValue_satimet();
+          if (newSyncr < NCS_SAF_MIN_ACCEPT_TIME && newSyncr != 0) {
+            LOG_WA("Invalid value (%lld) for param %s [10 - INT64_MAX]",
+                   newSyncr, saImmSyncrTimeout.c_str());
+            err = SA_AIS_ERR_BAD_OPERATION;
+            break;
+          }
+          if (oldSyncr != newSyncr) {
+            *changeSyncr = true;
+          } else {
+            LOG_NO("Skip update. Syncr timeout does not changed: %lld",
+                   newSyncr);
+          }
+        }
+
         if (p->attrValue.attrValuesNumber > 1) {
           if (!(attr->mFlags & SA_IMM_ATTR_MULTI_VALUE)) {
             LOG_NO(
diff --git a/src/imm/immnd/ImmModel.h b/src/imm/immnd/ImmModel.h
index 0b54bfa1d..44da47038 100644
--- a/src/imm/immnd/ImmModel.h
+++ b/src/imm/immnd/ImmModel.h
@@ -206,7 +206,8 @@ class ImmModel {
                               SaUint32T* implConn, unsigned int* implNodeId,
                               SaUint32T* continuationId, SaUint32T* pbeConn,
                               unsigned int* pbeNodeId, std::string& objectName,
-                              bool* hasLongDns, bool pbeFile, bool* changeRim);
+                              bool* hasLongDns, bool pbeFile, bool* changeRim,
+                              bool* changeSyncr);
 
   SaAisErrorT ccbObjectDelete(const ImmsvOmCcbObjectDelete* req,
                               SaUint32T reqConn,
@@ -377,6 +378,7 @@ class ImmModel {
   void setRegenerateDbFlag(bool value);
   SaImmRepositoryInitModeT getRepositoryInitMode();
   unsigned int getMaxSyncBatchSize();
+  SaTimeT getSyncrTimeout();
   bool getLongDnsAllowed(ObjectInfo* immObject = NULL);
   void prepareForLoading();
   bool readyForLoading();
diff --git a/src/imm/immnd/immnd_cb.h b/src/imm/immnd/immnd_cb.h
index bc2d75b05..057d6fa5b 100644
--- a/src/imm/immnd/immnd_cb.h
+++ b/src/imm/immnd/immnd_cb.h
@@ -210,6 +210,7 @@ typedef struct immnd_cb_tag {
   tmr_t splitbrain_tmr;
   bool splitbrain_tmr_run;
   uint8_t mFevsMaxPending; /* Max pending fevs messages towards director */
+  bool mSyncrTimeout;
 } IMMND_CB;
 
 /* CB prototypes */
diff --git a/src/imm/immnd/immnd_evt.c b/src/imm/immnd/immnd_evt.c
index 64c5223c4..af8ffae81 100644
--- a/src/imm/immnd/immnd_evt.c
+++ b/src/imm/immnd/immnd_evt.c
@@ -288,6 +288,8 @@ static uint32_t immnd_evt_proc_reset(IMMND_CB *cb, 
IMMND_EVT *evt,
 
 static uint32_t immnd_evt_impl_delete(IMMND_CB *cb, IMMND_EVT *evt);
 
+static uint32_t immnd_syncr_timeout_update_all(SaTimeT syncrTimeout);
+
 #if 0 /* Only for debug */
 static void printImmValue(SaImmValueTypeT t, IMMSV_EDU_ATTR_VAL *v)
 {
@@ -1030,6 +1032,8 @@ static uint32_t immnd_evt_proc_imm_init(IMMND_CB *cb, 
IMMND_EVT *evt,
        }
 
        send_evt.info.imma.info.initRsp.immHandle = cl_node->imm_app_hdl;
+       send_evt.info.imma.info.initRsp.syncrTimeout =
+           immModel_getSyncrTimeout(cb);
        error = SA_AIS_OK;
 
 clm_left:
@@ -4789,6 +4793,19 @@ static void immnd_evt_proc_ccb_compl_rsp(IMMND_CB *cb, 
IMMND_EVT *evt,
                                }
                        }
 
+                       if (cb->mSyncrTimeout) {
+                               cb->mSyncrTimeout = false;
+                               SaTimeT newSyncr = immModel_getSyncrTimeout(cb);
+                               uint32_t rc = 
immnd_syncr_timeout_update_all(newSyncr);
+                               if (rc == NCSCC_RC_SUCCESS) {
+                                       LOG_NO("Update Syncr timeout(%lld) 
successful", newSyncr);
+                               }
+                               else {
+                                       LOG_NO("Update Syncr timeout(%lld) 
failure. rc:%u",
+                                              newSyncr, rc);
+                               }
+                       }
+
                        if (arrSize) {
                                int ix;
                                memset(&send_evt, '\0', sizeof(IMMSV_EVT));
@@ -12521,3 +12538,36 @@ static uint32_t immnd_evt_impl_delete(IMMND_CB *cb, 
IMMND_EVT *evt)
 failed:
        return rc;
 }
+
+uint32_t immnd_syncr_timeout_update_all(SaTimeT syncr_timeout)
+{
+       IMMSV_EVT send_evt;
+       TRACE_ENTER();
+       uint32_t rc = NCSCC_RC_SUCCESS;
+
+       SaImmHandleT client_handle = 0;
+       IMMND_IMM_CLIENT_NODE *client_node = NULL;
+
+       memset(&send_evt, '\0', sizeof(IMMSV_EVT));
+       send_evt.type = IMMSV_EVT_TYPE_IMMA;
+       send_evt.info.imma.type = IMMA_EVT_ND2A_IMM_SYNCR_TIMEOUT;
+       send_evt.info.imma.info.immaTimeoutUpdate.syncrTimeout = syncr_timeout;
+
+       immnd_client_node_getnext(immnd_cb, 0, &client_node);
+       while (client_node) {
+               client_handle = client_node->imm_app_hdl;
+               send_evt.info.imma.info.immaTimeoutUpdate.immHandle =
+                   client_handle;
+               if (immnd_mds_msg_send(immnd_cb, client_node->sv_id,
+                                      client_node->agent_mds_dest,
+                                      &send_evt) != NCSCC_RC_SUCCESS) {
+                       LOG_ER("Sending syncr timeout update to client id %llx 
failed",
+                              client_handle);
+                       rc = NCSCC_RC_FAILURE;
+               }
+               immnd_client_node_getnext(immnd_cb, client_handle,
+                                         &client_node);
+       }
+       TRACE_LEAVE();
+       return rc;
+}
diff --git a/src/imm/immnd/immnd_init.h b/src/imm/immnd/immnd_init.h
index b5e279417..704ea3ba9 100644
--- a/src/imm/immnd/immnd_init.h
+++ b/src/imm/immnd/immnd_init.h
@@ -425,6 +425,7 @@ bool immModel_pbeIsInSync(IMMND_CB *cb, bool 
checkCriticalCcbs);
 SaImmRepositoryInitModeT immModel_getRepositoryInitMode(IMMND_CB *cb);
 
 unsigned int immModel_getMaxSyncBatchSize(IMMND_CB *cb);
+SaTimeT immModel_getSyncrTimeout(IMMND_CB *cb);
 
 SaAisErrorT immModel_rtObjectCreate(IMMND_CB *cb,
                                     struct ImmsvOmCcbObjectCreate *req,
-- 
2.25.1



_______________________________________________
Opensaf-devel mailing list
Opensaf-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/opensaf-devel

Reply via email to