After split-brain recovery, there is possibility of having inconsistencies
between IMM data model in memory held by IMMND and one in the back-end
database (sqlite).

That could happen as we might have 02 active IMMDs, 02 IMMND coordinators
and more than one PBE processes accessing a shared pbe database.
Change to such database from one therefore might not get noticed by the other.

By using this admin operation ID and targeting to IMM, IMM will regenerate the
back-end database from one in memory to keep them both consistent.

immadm -o 303 safRdn=immManagement,safApp=safImmService
---
 src/imm/README             | 18 ++++++++++++++++++
 src/imm/common/immsv_api.h |  4 +++-
 src/imm/immnd/ImmModel.cc  | 22 +++++++++++++++++++++-
 src/imm/immnd/ImmModel.h   |  3 ++-
 src/imm/immnd/immnd_init.h |  2 ++
 src/imm/immnd/immnd_proc.c |  8 ++++++--
 6 files changed, 52 insertions(+), 5 deletions(-)

diff --git a/src/imm/README b/src/imm/README
index 750d811a5..71e5c4fe3 100644
--- a/src/imm/README
+++ b/src/imm/README
@@ -3033,6 +3033,24 @@ expires.
 To be possible to use this new feature, bit 10 must be set in
 opensafImmNostdFlags attribute in IMM object.
 
+
+Provide an admin-operation for re-generating backend database from one in RAM
+=============================================================================
+https://sourceforge.net/p/opensaf/tickets/2940/
+
+After split-brain recovery, there is possibility of having inconsistencies
+between IMM data model in memory held by IMMND and one in the back-end
+database (sqlite).
+
+That could happen as we might have 02 active IMMDs, 02 IMMND coordinators
+and more than one PBE processes accessing a shared pbe database.
+Change to such database from one therefore might not get noticed by the other.
+
+By using this admin operation ID and targeting to IMM, IMM will regenerate the
+back-end database from one in memory to keep them both consistent.
+
+immadm -o 303 safRdn=immManagement,safApp=safImmService
+
 ----------------------------------------
 DEPENDENCIES
 ============
diff --git a/src/imm/common/immsv_api.h b/src/imm/common/immsv_api.h
index 32fc5738e..e6d613705 100644
--- a/src/imm/common/immsv_api.h
+++ b/src/imm/common/immsv_api.h
@@ -157,7 +157,9 @@ typedef enum {
 typedef enum {
   SA_IMM_ADMIN_EXPORT = 1, /* Defined in A.02.01 declared in  A.03.01 */
   SA_IMM_ADMIN_INIT_FROM_FILE = 100, /* Non standard, force PBE disable. */
-  SA_IMM_ADMIN_ABORT_CCBS = 202 /* Non standard, abort non critical CCBs. */
+  SA_IMM_ADMIN_ABORT_CCBS = 202, /* Non standard, abort non critical CCBs. */
+  /* Non standard, regenerate pbe database from RAM */
+  SA_IMM_ADMIN_REGENERATE_PBE_DB = 303
 } SaImmMngtAdminOperationT;
 
 /*
diff --git a/src/imm/immnd/ImmModel.cc b/src/imm/immnd/ImmModel.cc
index 21f48ab59..8e3f338dc 100644
--- a/src/imm/immnd/ImmModel.cc
+++ b/src/imm/immnd/ImmModel.cc
@@ -596,6 +596,7 @@ static const std::string 
saImmRepositoryInit("saImmRepositoryInit");
 static const std::string saImmOiTimeout("saImmOiTimeout");
 
 static SaImmRepositoryInitModeT immInitMode = SA_IMM_INIT_FROM_FILE;
+static bool sRegenerateDb = false;
 
 static SaUint32T sCcbIdLongDnGuard =
     0; /* Disallow long DN additions if longDnsAllowed is being changed in 
ccb*/
@@ -2003,6 +2004,14 @@ void immModel_setLoader(IMMND_CB* cb, SaInt32T 
loaderPid) {
   ImmModel::instance(&cb->immModel)->setLoader(loaderPid);
 }
 
+void immModel_setRegenerateDbFlag(IMMND_CB* cb, bool value) {
+  ImmModel::instance(&cb->immModel)->setRegenerateDbFlag(value);
+}
+
+bool immModel_getRegenerateDbFlag(IMMND_CB* cb) {
+  return ImmModel::instance(&cb->immModel)->getRegenerateDbFlag();
+}
+
 void immModel_recognizedIsolated(IMMND_CB* cb) {
   ImmModel::instance(&cb->immModel)->recognizedIsolated();
 }
@@ -2901,6 +2910,14 @@ int ImmModel::adjustEpoch(int suggestedEpoch, SaUint32T* 
continuationIdPtr,
   return suggestedEpoch;
 }
 
+bool ImmModel::getRegenerateDbFlag() {
+  return sRegenerateDb;
+}
+
+void ImmModel::setRegenerateDbFlag(bool value) {
+  sRegenerateDb = value;
+}
+
 /**
  * Fetches the SaImmRepositoryInitT value of the attribute
  * 'saImmRepositoryInit' in the object immManagementDn.
@@ -13808,6 +13825,9 @@ SaAisErrorT ImmModel::admoImmMngtObject(const 
ImmsvOmAdminOperationInvoke* req,
       LOG_IN("sAbortNonCriticalCcbs = true;");
       sAbortNonCriticalCcbs = true;
     }
+  } else if (req->operationId == SA_IMM_ADMIN_REGENERATE_PBE_DB) {
+    LOG_NO("Re-generate the pbe database from one in memory.");
+    sRegenerateDb = true;
   } else {
     LOG_NO("Invalid operation ID %llu, for operation on %s",
            (SaUint64T)req->operationId, immManagementDn.c_str());
@@ -14976,7 +14996,7 @@ SaAisErrorT ImmModel::implementerSet(const 
IMMSV_OCTET_STRING* implementerName,
         implName.c_str());
     /* If we find any, then surgically replace the implId of the implAssoc with
         the new implId of the newly reincarnated PBE implementer.*/
-
+    sRegenerateDb = false;
     for (i = sCcbVector.begin(); i != sCcbVector.end(); ++i) {
       CcbInfo* ccb = (*i);
       if (ccb->mState == IMM_CCB_CRITICAL) {
diff --git a/src/imm/immnd/ImmModel.h b/src/imm/immnd/ImmModel.h
index c8b0f4eea..65e20d305 100644
--- a/src/imm/immnd/ImmModel.h
+++ b/src/imm/immnd/ImmModel.h
@@ -372,7 +372,8 @@ class ImmModel {
   int adjustEpoch(int suggestedEpoch, SaUint32T* continuationId,
                   SaUint32T* pbeConnPtr, unsigned int* pbeNodeIdPtr,
                   bool increment);
-
+  bool getRegenerateDbFlag();
+  void setRegenerateDbFlag(bool value);
   SaImmRepositoryInitModeT getRepositoryInitMode();
   unsigned int getMaxSyncBatchSize();
   bool getLongDnsAllowed(ObjectInfo* immObject = NULL);
diff --git a/src/imm/immnd/immnd_init.h b/src/imm/immnd/immnd_init.h
index 1d0126ec5..58ed48329 100644
--- a/src/imm/immnd/immnd_init.h
+++ b/src/imm/immnd/immnd_init.h
@@ -309,6 +309,8 @@ bool immModel_readyForLoading(IMMND_CB *cb);
 SaInt32T immModel_getLoader(IMMND_CB *cb);
 
 void immModel_setLoader(IMMND_CB *cb, SaInt32T loaderPid);
+void immModel_setRegenerateDbFlag(IMMND_CB *cb, bool value);
+bool immModel_getRegenerateDbFlag(IMMND_CB *cb);
 
 unsigned int immModel_pbeOiExists(IMMND_CB *cb);
 unsigned int immModel_pbeBSlaveExists(IMMND_CB *cb);
diff --git a/src/imm/immnd/immnd_proc.c b/src/imm/immnd/immnd_proc.c
index 015932a4b..b03063882 100644
--- a/src/imm/immnd/immnd_proc.c
+++ b/src/imm/immnd/immnd_proc.c
@@ -1935,6 +1935,7 @@ static int immnd_forkPbe(IMMND_CB *cb)
        LOG_NO("pbe-db-file-path:%s VETERAN:%u B:%u", dbFilePath,
               cb->mPbeVeteran, cb->mPbeVeteranB);
 
+       bool regenerate_db = immModel_getRegenerateDbFlag(cb);
        if ((cb->mPbeVeteran || cb->mPbeVeteranB) &&
            !immModel_pbeIsInSync(cb, false)) {
                /* Currently we can not recover results for PRTO
@@ -1961,7 +1962,7 @@ static int immnd_forkPbe(IMMND_CB *cb)
                bool veteran = (cb->mIsCoord) ? (cb->mPbeVeteran)
                                              : (cb->m2Pbe && cb->mPbeVeteranB);
                pbeArgs[0] = (char *)execPath;
-               if (veteran) {
+               if (veteran && !regenerate_db) {
                        pbeArgs[1] = "--recover";
                        pbeArgs[2] = (cb->m2Pbe) ? ((cb->mIsCoord) ? "--pbe2A"
                                                                   : "--pbe2B")
@@ -1983,6 +1984,8 @@ static int immnd_forkPbe(IMMND_CB *cb)
        }
        TRACE_5("Parent %s, successfully forked %s, pid:%d", base, dbFilePath,
                pid);
+
+       immModel_setRegenerateDbFlag(cb, false);
        cb->mPbeKills = 0; /* Rest kill count when we just created a new PBE. */
        if (cb->mIsCoord && cb->mPbeVeteran) {
                cb->mPbeVeteran = false;
@@ -2701,7 +2704,8 @@ uint32_t immnd_proc_server(uint32_t *timeout)
                                } else { /* Pbe is running. */
                                        osafassert(cb->pbePid > 0);
                                        if (cb->mRim == SA_IMM_INIT_FROM_FILE ||
-                                           cb->mBlockPbeEnable) {
+                                           cb->mBlockPbeEnable ||
+                                           immModel_getRegenerateDbFlag(cb)) {
                                                /* Pbe should NOT run.*/
                                                if ((cb->mPbeKills++) ==
                                                    0) { /* Send SIGTERM only
-- 
2.18.0



_______________________________________________
Opensaf-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensaf-devel

Reply via email to