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.
---
src/imm/agent/imma_oi_api.cc | 6 +++
src/imm/agent/imma_om_api.cc | 6 +++
src/imm/agent/imma_proc.cc | 39 ++++++++++++++++++++
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 | 63 ++++++++++++++++++++++++++++++--
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 +
13 files changed, 205 insertions(+), 5 deletions(-)
diff --git a/src/imm/agent/imma_oi_api.cc b/src/imm/agent/imma_oi_api.cc
index c79d0e315..1df5336b2 100644
--- a/src/imm/agent/imma_oi_api.cc
+++ b/src/imm/agent/imma_oi_api.cc
@@ -309,6 +309,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..f0771a8c1 100644
--- a/src/imm/agent/imma_om_api.cc
+++ b/src/imm/agent/imma_om_api.cc
@@ -362,6 +362,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..1351e61f4 100644
--- a/src/imm/agent/imma_proc.cc
+++ b/src/imm/agent/imma_proc.cc
@@ -1435,6 +1435,41 @@ 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) {
+ char *timeout_env_value = NULL;
+ if ((timeout_env_value = getenv("IMMA_SYNCR_TIMEOUT")) != NULL) {
+ cl_node->syncr_timeout = atoi(timeout_env_value);
+ }
+
+ if (cl_node->syncr_timeout < NCS_SAF_MIN_ACCEPT_TIME) {
+ cl_node->syncr_timeout = IMMSV_WAIT_TIME; /* Default */
+ }
+ }
+ 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 +1542,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..c53d818fe 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,15 @@ 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("skipping update syncr timeout. As old == new");
+ }
+ }
TRACE("Canonicalizing attr-mod for attribute '%s'",
attrName.c_str());
@@ -9721,6 +9757,25 @@ SaAisErrorT ImmModel::ccbObjectModify(
}
}
+ if (modifiedImmMngt && (attrName == saImmSyncrTimeout)) {
+ SaTimeT oldSyncr = getSyncrTimeout();
+ SaTimeT newSyncr = attrValue->getValue_satimet();
+ if (newSyncr > INT64_MAX ||
+ (newSyncr < NCS_SAF_MIN_ACCEPT_TIME && newSyncr != 0)) {
+ LOG_WA(
+ "Invalid value (%lld) for param %s "
+ "(NCS_SAF_MIN_ACCEPT_TIME(10) to INT64_MAX)",
+ newSyncr, saImmSyncrTimeout.c_str());
+ err = SA_AIS_ERR_BAD_OPERATION;
+ break;
+ }
+ if (oldSyncr != newSyncr) {
+ *changeSyncr = true;
+ } else {
+ LOG_NO("skipping update syncr timeout. As old == new");
+ }
+ }
+
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..674e4746c 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);
+ LOG_NO("Trying to update Syncr Timeout: %lld",
newSyncr);
+ uint32_t rc =
immnd_syncr_timeout_update_all(newSyncr);
+ if (rc == NCSCC_RC_SUCCESS) {
+ LOG_NO("Update Syncr timeout
successful");
+ }
+ else {
+ LOG_NO("Update Syncr timeout failure.
rc:%u", 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
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensaf-devel