osaf/libs/common/immsv/include/immsv_api.h       |    4 +
 osaf/services/saf/immsv/immloadd/imm_pbe_load.cc |    1 +
 osaf/services/saf/immsv/immnd/ImmModel.cc        |   83 +++++++++++++++--
 osaf/services/saf/immsv/immnd/ImmModel.hh        |    1 +
 osaf/services/saf/immsv/immnd/immnd_cb.h         |    3 +
 osaf/services/saf/immsv/immnd/immnd_evt.c        |  104 ++++++++++++++++++++++-
 osaf/services/saf/immsv/immnd/immnd_init.h       |    4 +
 osaf/services/saf/immsv/immnd/immnd_proc.c       |   25 ++++-
 osaf/services/saf/immsv/immpbed/immpbe_daemon.cc |  100 +++++++++++++++-------
 9 files changed, 278 insertions(+), 47 deletions(-)


This patch contains the 2PBE 1safe2Pbe mechanism. This mechanism
allows an OpenSAF cluster to open up for persistent writes using
only one of the two PBEs - temporarily.

This is only intended to be used as an emergency action when one SC
is long term unavailable, e.g. hardware problems. As soon as the other SC
returns, the IMM has to re-enter normal 2-safe 2PBE and reject persistent
writes until the slave PBE has synced (regenerated its sqlite file) and
rejoined the cluster.

The 1safe2PBE state is entered by the administrative opeation:

  immadm -o 1 -p opensafImmNostdFlags:SA_UINT32_T:8 \
     opensafImm=opensafImm,safApp=safImmService

It is exited either automatically by a rejoined SC or by an
explicit administrative opertion:

  immadm -o 2 -p opensafImmNostdFlags:SA_UINT32_T:8 \
     opensafImm=opensafImm,safApp=safImmService

diff --git a/osaf/libs/common/immsv/include/immsv_api.h 
b/osaf/libs/common/immsv/include/immsv_api.h
--- a/osaf/libs/common/immsv/include/immsv_api.h
+++ b/osaf/libs/common/immsv/include/immsv_api.h
@@ -37,6 +37,7 @@ extern "C" {
 #define OPENSAF_IMM_ATTR_EPOCH "opensafImmEpoch"
 #define OPENSAF_IMM_ATTR_RDN "opensafImm"
 #define OPENSAF_IMM_ATTR_NOSTD_FLAGS "opensafImmNostdFlags"
+#define OPENSAF_IMM_ATTR_OTHER_SC_UP "mIsOtherScUp"
 #define OPENSAF_IMM_OBJECT_DN "opensafImm=opensafImm,safApp=safImmService"
 #define OPENSAF_IMM_OBJECT_RDN "opensafImm=opensafImm"
 #define OPENSAF_IMM_OBJECT_PARENT "safApp=safImmService"
@@ -98,14 +99,17 @@ extern "C" {
 #define OPENSAF_IMM_PBE_UPDATE_EPOCH 0x30000000
 #define OPENSAF_IMM_2PBE_PRELOAD_STAT 0x40000000
 #define OPENSAF_IMM_PBE_CCB_PREPARE 0x50000000
+#define OPENSAF_IMM_BAD_OP_BOUNCE 0x60000000
 
 /* Public operation ids on OpenSafImmPBE */
 #define OPENSAF_IMM_NOST_FLAG_ON     0x00000001
 #define OPENSAF_IMM_NOST_FLAG_OFF    0x00000002
 
+/* Flag values for nostdflags. */
 #define OPENSAF_IMM_FLAG_SCHCH_ALLOW 0x00000001
 #define OPENSAF_IMM_FLAG_PRT41_ALLOW 0x00000002
 #define OPENSAF_IMM_FLAG_PRT43_ALLOW 0x00000004
+#define OPENSAF_IMM_FLAG_2PBE1_ALLOW 0x00000008
 
 
 #define OPENSAF_IMM_SERVICE_NAME "safImmService"
diff --git a/osaf/services/saf/immsv/immloadd/imm_pbe_load.cc 
b/osaf/services/saf/immsv/immloadd/imm_pbe_load.cc
--- a/osaf/services/saf/immsv/immloadd/imm_pbe_load.cc
+++ b/osaf/services/saf/immsv/immloadd/imm_pbe_load.cc
@@ -978,6 +978,7 @@ int loadImmFromPbe(void* pbeHandle, bool
 
  done:
        sqlite3_close(dbHandle);
+       if(preload) {exit(0);} /* dont delay termination of preloader.*/
        saImmOmAdminOwnerFinalize(ownerHandle);
        saImmOmFinalize(immHandle);
        TRACE_LEAVE();
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
@@ -360,7 +360,6 @@ struct AdminOwnerInfo
 };
 typedef std::vector<AdminOwnerInfo*> AdminOwnerVector;
 
-
 typedef enum {
     IMM_NODE_UNKNOWN = 0,      //Initial state
     IMM_NODE_LOADING = 1,      //We are participating in a cluster restart.
@@ -826,6 +825,13 @@ immModel_protocol43Allowed(IMMND_CB *cb)
 }
 
 SaBoolT
+immModel_oneSafe2PBEAllowed(IMMND_CB *cb)
+{
+    return (ImmModel::instance(&cb->immModel)->oneSafe2PBEAllowed()) ?
+        SA_TRUE : SA_FALSE;
+}
+
+SaBoolT
 immModel_purgeSyncRequest(IMMND_CB *cb, SaUint32T clientId)
 {
     return (ImmModel::instance(&cb->immModel)->purgeSyncRequest(clientId)) ?
@@ -1054,6 +1060,34 @@ immModel_adminOperationInvoke(IMMND_CB *
         implConn, implNodeId, pbeExpected);
 }
 
+SaUint32T  /* Returns admo-id for object if object exists and active admo 
exists, otherwise zero. */
+immModel_getAdmoIdForObj(IMMND_CB *cb, const char* opensafImmObj)
+{
+    TRACE_ENTER();
+    SaUint32T admoId=0;
+    std::string objectName(opensafImmObj);
+    std::string admOwner;
+
+    AdminOwnerVector::iterator i = sOwnerVector.begin();
+    ObjectMap::iterator oi = sObjectMap.find(objectName);
+    if(oi == sObjectMap.end()) {
+        TRACE("immModel_getAdmoIdForObj: Could not find %s", opensafImmObj);
+        goto done;
+    }
+
+    oi->second->getAdminOwnerName(&admOwner);
+    for(; i!=sOwnerVector.end(); ++i) {
+        if(!(*i)->mDying && (*i)->mAdminOwnerName == admOwner) {
+            admoId = (*i)->mId;
+            break;
+        }
+    }
+
+ done:
+    TRACE_LEAVE();
+    return admoId;
+}
+
 SaUint32T 
 immModel_findConnForImplementerOfObject(IMMND_CB *cb, 
     IMMSV_OCTET_STRING* objectName)
@@ -1813,17 +1847,15 @@ ImmModel::immNotPbeWritable(bool isPrtoC
         return true; 
     }
 
-    /* ABT TODO need a solution for enable/disable 2-safe/1-safe 2PBE 
-       This has to be runtime data, can not be config data. 
-       There is a dilema with persistent config talking about degre of
-       persistent redundancy.
-       Catch this after loading, look up opensaf object and add an RTA
-       to reflect 2PBE status. 
-    */
-
     if(pbeBSlaveHasExisted() && !getPbeBSlave(&dummyCon, &dummyNode)) {
-        /* Pbe slave SHOULD be present but is NOT. This is 2PBE 1-safe. */
-        return true; 
+        /* Pbe slave SHOULD be present but is NOT. Normally this
+          means immNotPbeWritable() returns true. But if oneSafe2PBEAllowed()
+          is true, (indicating SC repair or similar) then the unavailability
+          of the slave is accepted, otherwise not. By default 
+          oneSafePBEAllowed() is false. So normally we will exit with
+          reject (true) here. 
+        */
+           if(!oneSafe2PBEAllowed()) {return true;}
     }
 
     /* Pbe is present but Check also for backlog. */
@@ -3002,6 +3034,28 @@ ImmModel::migrateObj(ObjectInfo* object,
 }
 
 bool
+ImmModel::oneSafe2PBEAllowed()
+{
+    //TRACE_ENTER();
+    ObjectMap::iterator oi = sObjectMap.find(immObjectDn);
+    if(oi == sObjectMap.end()) {
+        TRACE_LEAVE();
+        return false;
+    }
+
+    ObjectInfo* immObject =  oi->second;
+    ImmAttrValueMap::iterator avi = 
+        immObject->mAttrValueMap.find(immAttrNostFlags);
+    osafassert(avi != immObject->mAttrValueMap.end());
+    osafassert(!(avi->second->isMultiValued()));
+    ImmAttrValue* valuep = avi->second;
+    unsigned int noStdFlags = valuep->getValue_int();
+
+    //TRACE_LEAVE();
+    return noStdFlags & OPENSAF_IMM_FLAG_2PBE1_ALLOW;
+}
+
+bool
 ImmModel::protocol43Allowed()
 {
     //TRACE_ENTER();
@@ -9265,6 +9319,13 @@ ImmModel::updateImmObject2(const ImmsvOm
 
     if(req->operationId == OPENSAF_IMM_NOST_FLAG_ON) {
         SaUint32T flagsToSet = req->params->paramBuffer.val.sauint32;
+        /* Reject 1safe2pbe, only allowed to set when primary PBE is present. 
*/
+        if(flagsToSet == OPENSAF_IMM_FLAG_2PBE1_ALLOW) {
+            LOG_NO("Imm %s: Rejecting toggling ON flag 0x%x when primary PBE 
is not attached",
+                immAttrNostFlags.c_str(),  OPENSAF_IMM_FLAG_2PBE1_ALLOW);
+            err = SA_AIS_ERR_BAD_OPERATION;
+            goto done;
+        }
         TRACE_5("Admin op NOST_FLAG_ON, current flags %x on flags %x", 
noStdFlags, flagsToSet);
         noStdFlags |= flagsToSet;
         valuep->setValue_int(noStdFlags);
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
@@ -96,6 +96,7 @@ public:
     bool                schemaChangeAllowed();
     bool                protocol41Allowed();
     bool                protocol43Allowed();
+    bool                oneSafe2PBEAllowed();
     bool                purgeSyncRequest(SaUint32T clientId);
     bool                verifySchemaChange(const std::string& className,
                                             ClassInfo* oldClass,
diff --git a/osaf/services/saf/immsv/immnd/immnd_cb.h 
b/osaf/services/saf/immsv/immnd/immnd_cb.h
--- a/osaf/services/saf/immsv/immnd/immnd_cb.h
+++ b/osaf/services/saf/immsv/immnd/immnd_cb.h
@@ -91,6 +91,7 @@ typedef struct immnd_cb_tag {
        uint32_t immnd_mds_hdl;
        MDS_DEST immnd_mdest_id;
        NCS_NODE_ID node_id;
+       NCS_NODE_ID other_sc_node_id; //Not reliably set, see mIsOtherScUp 
(2pbe).
 
        /*Nr of FEVS messages sent, but not received back at origin.*/
        uint8_t fevs_replies_pending; 
@@ -121,6 +122,8 @@ typedef struct immnd_cb_tag {
        uint8_t mBlockPbeEnable;  //Current PBE has not completed shutdown yet.
        uint8_t mPbeKills;        //If != 0 then immnd has tried to kill Pbe.
        uint8_t m2Pbe;            //If!=0 => 2PBE, 2 => fetch PBE file info.
+       bool mIsOtherScUp; //If set & this is an SC then other SC is up(2pbe).
+                  //False=> *allow* 1safe 2pbe. May err conservatively (true) 
 
        /* Information about the IMMD */
        MDS_DEST immd_mdest_id;
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
@@ -846,6 +846,34 @@ static uint32_t immnd_evt_proc_search_in
                        error = SA_AIS_ERR_TRY_AGAIN;
                        goto agent_rsp;
                }
+
+               if (cb->m2Pbe) {
+                       if(cb->mIsOtherScUp && immModel_oneSafe2PBEAllowed(cb)) 
{
+                               LOG_WA("ERR_NO_RESOURCES: Cannot allow official 
dump/backup "
+                                       "when 1-safe2PBE is allowed!!");
+                               /* This is simply a guard. Only reason it is 
not an assert is
+                                  that this does not signify imm-ram 
inconsistency, but a grave
+                                  risk of causing an inconsistent joining PBE 
in 2PBE.
+                                  We should never end up here. */
+                               error = SA_AIS_ERR_NO_RESOURCES;
+                               goto agent_rsp;
+                       }
+
+                       if((!cb->mIsCoord) && immModel_pbeNotWritable(cb) && 
+                               !immModel_ccbsTerminated(cb)) {
+                               LOG_WA("ERR_NO_RESOURCES: Active Ccbs still 
exist in the system");
+                               /*Not sure this is a problem though. These ccbs 
are dommed. 
+                                 They will not be allowed to apply untill we 
are 2-safe.
+                                 And any ccbs that created ops before w-safe 
will fail in the apply
+                                 because object count does not match at slave. 
+                                 May need a way to get out of this state, such 
as starting a sync
+                                 despite that we dont really need a sync. 
+                               */
+                               error = SA_AIS_ERR_NO_RESOURCES;
+                               goto agent_rsp;
+                       }
+
+               }
        }
 
        if(isSync) {
@@ -4615,6 +4643,23 @@ static void immnd_evt_proc_admop(IMMND_C
                        LOG_ER("IMMND - Client %llu went down so no response", 
implHandle);
                        error = SA_AIS_ERR_NOT_EXIST;
                } else {
+                       if(cb->mIsOtherScUp && (evt->info.admOpReq.operationId 
==  OPENSAF_IMM_NOST_FLAG_ON) &&
+                               (evt->info.admOpReq.params!=NULL) && 
(evt->info.admOpReq.params->paramType == SA_IMM_ATTR_SAUINT32T) &&
+                               
(evt->info.admOpReq.params->paramBuffer.val.sauint32 == 
OPENSAF_IMM_FLAG_2PBE1_ALLOW) &&
+                               (strcmp(evt->info.admOpReq.objectName.buf, 
OPENSAF_IMM_OBJECT_DN)==0) &&
+                               
(strcmp(evt->info.admOpReq.params->paramName.buf, 
OPENSAF_IMM_ATTR_NOSTD_FLAGS)==0))
+                       {
+                               /* Caught the special case of attempt to togle 
ON noStdFlags value 0x8 (OPENSAF_IMM_FLAG_2PBE1_ALLOW).
+                                  This is not allowed as long as the other SC 
is up, regardless of whether the slave PBE is up.
+                                  We "know" that >>here<< we are on the SC 
running the IMMND coord and thus the primary PBE,
+                                  because this is the code branch for invoking 
callback on the implementer (implCon) for the admin-op
+                                  and the implementer for 
OPENSAF_IMM_OBJECT_DN (if it exists) must be the PBE. 
+                               */
+                               LOG_WA("Rejecting attempt to togle *ON* value 
x%x for %s in %s when both SCs are up",
+                                       OPENSAF_IMM_FLAG_2PBE1_ALLOW, 
OPENSAF_IMM_ATTR_NOSTD_FLAGS, OPENSAF_IMM_OBJECT_DN);
+                               evt->info.admOpReq.operationId = 
OPENSAF_IMM_BAD_OP_BOUNCE;
+                       }
+
                        memset(&send_evt, '\0', sizeof(IMMSV_EVT));
                        send_evt.type = IMMSV_EVT_TYPE_IMMA;
                        send_evt.info.imma.type = IMMA_EVT_ND2A_IMM_ADMOP;
@@ -4743,7 +4788,7 @@ static void immnd_evt_proc_admop(IMMND_C
                                if((cb->mState  == IMM_SERVER_CLUSTER_WAITING) 
&& (cb->m2Pbe == 2) &&
                                        (evt->info.admOpReq.operationId == 
OPENSAF_IMM_2PBE_PRELOAD_STAT)) {
                                        LOG_IN("2PBE Preload case: sending 
persistency stats to IMMD");
-                                       /* ABT process the params structure in 
the incoming message.*/
+                                       /* process the params structure in the 
incoming message.*/
                                        immnd_extract_preload_params(cb, 
&(evt->info.admOpReq));
                                }
                        }
@@ -7981,6 +8026,7 @@ static uint32_t immnd_evt_proc_loading_o
                        cb->mJobStart = time(NULL);
                        osafassert(cb->mJobStart > ((time_t) 0));
                        cb->mAccepted = true;
+                       if(cb->mCanBeCoord) {cb->mIsOtherScUp = true;}
                }
        } else if (cb->mState == IMM_SERVER_LOADING_SERVER) {
                osafassert(cb->mMyEpoch == cb->mRulingEpoch);
@@ -8130,6 +8176,57 @@ static uint32_t immnd_evt_proc_intro_rsp
                if (cb->mRulingEpoch) {
                        TRACE_2("Ruling Epoch:%u", cb->mRulingEpoch);
                }
+       } else {
+               /* Received intro for some other node. We should be an SC and 
the intro
+                  should be for the other SC. That should also mean we are 
coord. 
+                  If oneSAfe2PBEAllowed is true, then we now must turn it off.
+                  This is done by sending an admin-op to PBE turning off the 
oneSafe2PBEAllwed flag.
+                  This comes back to the cluster as an RTA update, turning off 
the flag also in imm-ram.
+                  The flag must be turned off to allow the rejoining slave PBE 
to take a fresh dump of
+                  from imm-ram to the sqlite file. No Ccbs can be allowed to 
start untill the slave PBE
+                  has rejoined establishing 2-safe 2PBE. See
+                  
+               */
+               if(cb->mCanBeCoord && evt->info.ctrl.canBeCoord) {
+                       LOG_IN("Other SC node (%x) has been introduced", 
evt->info.ctrl.nodeId);
+                       cb->mIsOtherScUp = true; /* Prevents oneSafe2PBEAllowed 
from being turned on */
+                       cb->other_sc_node_id = evt->info.ctrl.nodeId;
+                       
+                       if(cb->mIsCoord && immModel_oneSafe2PBEAllowed(cb)) {
+                               /* oneSafe2PBE currently ON => turn it OFF. */
+                               IMMSV_EVT fake_evt;
+                               memset(&fake_evt, '\0', sizeof(IMMSV_EVT));
+                               IMMSV_ADMIN_OPERATION_PARAM param;
+                               char* opensafImmObj=OPENSAF_IMM_OBJECT_DN;
+                               char* nostParam=OPENSAF_IMM_ATTR_NOSTD_FLAGS;
+                               memset(&param, '\0', 
sizeof(IMMSV_ADMIN_OPERATION_PARAM));
+                               LOG_NO("Internally generating 'admin-op' for 
toggling OFF: "
+                                       "1-safe2PBE(0x%x) in %s",       
OPENSAF_IMM_FLAG_2PBE1_ALLOW,
+                                       OPENSAF_IMM_ATTR_NOSTD_FLAGS);
+
+                               memset(&fake_evt, '\0', sizeof(IMMSV_EVT));
+                               fake_evt.type = IMMSV_EVT_TYPE_IMMND;
+                               fake_evt.info.immnd.type = 
IMMND_EVT_A2ND_IMM_ADMOP;
+
+                               fake_evt.info.immnd.info.admOpReq.adminOwnerId 
= 
+                                       immModel_getAdmoIdForObj(cb, 
opensafImmObj);
+                                       
+                               fake_evt.info.immnd.info.admOpReq.operationId = 
OPENSAF_IMM_NOST_FLAG_OFF;
+                               
fake_evt.info.immnd.info.admOpReq.continuationId = 0;
+                               
fake_evt.info.immnd.info.admOpReq.objectName.buf = opensafImmObj;
+                               
fake_evt.info.immnd.info.admOpReq.objectName.size = strlen(opensafImmObj)+1;
+                               fake_evt.info.immnd.info.admOpReq.params = 
&param;
+                               
fake_evt.info.immnd.info.admOpReq.params->paramName.buf = nostParam;
+                               
fake_evt.info.immnd.info.admOpReq.params->paramName.size = strlen(nostParam);
+                               
fake_evt.info.immnd.info.admOpReq.params->paramType = SA_IMM_ATTR_SAUINT32T;
+                               
fake_evt.info.immnd.info.admOpReq.params->paramBuffer.val.sauint32 = 
+                                       OPENSAF_IMM_FLAG_2PBE1_ALLOW;
+
+                               /* A *fake* fake-evs. */
+                               LOG_NO("****Normalizing from 1-safe 2PBE to 
2-safe 2PBE****");
+                               immnd_evt_proc_admop(cb, 
&(fake_evt.info.immnd), SA_FALSE, 0LL, 0LL);
+                       }
+               }
        }
        return NCSCC_RC_SUCCESS;
 }
@@ -8331,6 +8428,11 @@ static void immnd_evt_proc_discard_node(
                arrSize = 0;
        }
 
+       if(cb->other_sc_node_id == evt->info.ctrl.nodeId) {
+               /* Open up for *allowing* 1-safe 2pbe */
+               cb->mIsOtherScUp=false;
+       }
+
        TRACE_LEAVE();
 }
 
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
@@ -89,6 +89,9 @@ extern "C" {
                               SaUint32T ccbFlags,
                               SaUint32T ccbId, unsigned int originatingNode, 
SaUint32T originatingConn);
 
+       SaUint32T
+       immModel_getAdmoIdForObj(IMMND_CB *cb, const char* objNameBuf);
+
        SaAisErrorT
            immModel_adminOperationInvoke(IMMND_CB *cb,
                                          const struct 
ImmsvOmAdminOperationInvoke *req,
@@ -288,6 +291,7 @@ extern "C" {
 
        SaBoolT immModel_protocol41Allowed(IMMND_CB *cb);
        SaBoolT immModel_protocol43Allowed(IMMND_CB *cb);
+       SaBoolT immModel_oneSafe2PBEAllowed(IMMND_CB *cb);
 
        SaBoolT immModel_purgeSyncRequest(IMMND_CB *cb, SaUint32T clientId);
 
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
@@ -968,6 +968,14 @@ static void immnd_cleanTheHouse(IMMND_CB
                                LOG_NO("PBE-OI established on %s SC. Dumping 
incrementally "
                                        "to file %s", 
(cb->mIsCoord)?"this":"other", 
                                        cb->mPbeFile);
+                               if(!(cb->mIsCoord)) {
+                                       cb->other_sc_node_id = pbeNodeId;
+                                       if(!(cb->mIsOtherScUp)) {
+                                               LOG_ER("Late detection of other 
SC up");
+                                               
osafassert(!immModel_oneSafe2PBEAllowed(cb));
+                                               cb->mIsOtherScUp = true;
+                                       }
+                               }
                        }
                }
 
@@ -995,6 +1003,14 @@ static void immnd_cleanTheHouse(IMMND_CB
                                                "Dumping incrementally to file 
%s", 
                                                (cb->mIsCoord)?"other":"this",  
cb->mPbeFile);
                                        cb->mPbeOldVeteranB = SA_TRUE;
+                                       if(cb->mIsCoord) {
+                                               cb->other_sc_node_id = 
pbeSlaveNodeId;
+                                               if(!(cb->mIsOtherScUp)) {
+                                                       LOG_ER("Late detection 
of other SC up");
+                                                       
osafassert(!immModel_oneSafe2PBEAllowed(cb));
+                                                       cb->mIsOtherScUp = true;
+                                               }
+                                       }
                                }
                        }
                }
@@ -1606,10 +1622,11 @@ uint32_t immnd_proc_server(uint32_t *tim
        /*TRACE_ENTER(); */
 
        if ((cb->mStep % printFrq) == 0) {
-               TRACE_5("tmout:%u ste:%u ME:%u RE:%u crd:%u rim:%s 4.3A:%u 
2Pbe:%u VetA/B: %u/%u",
+               TRACE_5("tmout:%u ste:%u ME:%u RE:%u crd:%u rim:%s 4.3A:%u 
2Pbe:%u VetA/B: %u/%u othsc:%u/%x",
                        *timeout, cb->mState, cb->mMyEpoch, cb->mRulingEpoch, 
cb->mIsCoord,
-                       
(cb->mRim==SA_IMM_KEEP_REPOSITORY)?"KEEP_REPO":"FROM_FILE", 
-                       immModel_protocol43Allowed(cb), cb->m2Pbe, 
cb->mPbeVeteran, cb->mPbeVeteranB);
+                       
(cb->mRim==SA_IMM_KEEP_REPOSITORY)?"KEEP_REPO":"FROM_FILE",
+                       immModel_protocol43Allowed(cb), cb->m2Pbe, 
cb->mPbeVeteran, cb->mPbeVeteranB,
+                       cb->mIsOtherScUp, cb->other_sc_node_id);
        }
 
        if (cb->mState < IMM_SERVER_DUMP) {
@@ -1747,6 +1764,7 @@ uint32_t immnd_proc_server(uint32_t *tim
                                cb->mState = IMM_SERVER_LOADING_CLIENT;
                                cb->mStep = 0;
                                cb->mJobStart = now;
+                               if(cb->mCanBeCoord) {cb->mIsOtherScUp = true;}
                        }
                }
                break;
@@ -1758,6 +1776,7 @@ uint32_t immnd_proc_server(uint32_t *tim
                        cb->mJobStart = now;
                        LOG_NO("SERVER STATE: IMM_SERVER_SYNC_PENDING --> 
IMM_SERVER_SYNC_CLIENT");
                        cb->mState = IMM_SERVER_SYNC_CLIENT;
+                       if(cb->mCanBeCoord) {cb->mIsOtherScUp = true;}
                } else {
                        /* Sync has not started yet. */
                        /* Sync client timeout removed. Any timeout handled by 
nid. */
diff --git a/osaf/services/saf/immsv/immpbed/immpbe_daemon.cc 
b/osaf/services/saf/immsv/immpbed/immpbe_daemon.cc
--- a/osaf/services/saf/immsv/immpbed/immpbe_daemon.cc
+++ b/osaf/services/saf/immsv/immpbed/immpbe_daemon.cc
@@ -249,7 +249,12 @@ static bool pbe2_start_prepare_ccb_A_to_
        } while (((rc2B == SA_AIS_ERR_TRY_AGAIN) || (slavePbeRtReply == 
SA_AIS_ERR_TRY_AGAIN)) && (msecs_waited < 3000));
 
        if(rc2B != SA_AIS_OK) {
-               LOG_WA("Start prepare for ccb: %llx/%llu towards slave PBE 
returned: '%u' from Immsv", ccbId, ccbId, rc2B);
+               if((rc2B == SA_AIS_ERR_NOT_EXIST) && (sNoStdFlags & 
OPENSAF_IMM_FLAG_2PBE1_ALLOW)) {
+                       LOG_NO("2PBE slave NOT available but NoStFlags 0x8 
set");
+                       retval=true;
+               } else {
+                       LOG_WA("Start prepare for ccb: %llx/%llu towards slave 
PBE returned: '%u' from Immsv", ccbId, ccbId, rc2B);
+               }
        } else if(slavePbeRtReply != SA_AIS_OK) {
                LOG_WA("Start prepare for ccb: %llx/%llu towards slave PBE 
returned: '%u' from sttandby PBE", ccbId, ccbId, slavePbeRtReply);
        } else {
@@ -836,7 +841,7 @@ static void saImmOiAdminOperationCallbac
                
                if(!param || (param->paramType != SA_IMM_ATTR_SAUINT32T) || 
                        strcmp(param->paramName, (char *) 
OPENSAF_IMM_ATTR_NOSTD_FLAGS)) {
-                       LOG_IN("Incorrect parameter to NostdFlags-ON, should be 
'flags:SA_UINT32_T:nnnn");
+                       LOG_IN("Incorrect parameter to NostdFlags-ON, should be 
'opensafImmNostdFlags:SA_UINT32_T:nnnn'");
                        rc = immutil_saImmOiAdminOperationResult(immOiHandle, 
invocation, SA_AIS_ERR_INVALID_PARAM);
                        goto fail;
                }
@@ -844,7 +849,7 @@ static void saImmOiAdminOperationCallbac
                SaUint32T flagsToSet = (*((SaUint32T *) param->paramBuffer));
 
                if(sPbe2 && !sPbe2B) {
-                       /* Forward nost flag off to slave PBE. */
+                       /* Forward nost flag ON to slave PBE. */
                        SaAisErrorT rc2B = SA_AIS_OK;
                        SaNameT slavePbeRtObjName = 
{sizeof(OPENSAF_IMM_PBE_RT_OBJECT_DN_B), OPENSAF_IMM_PBE_RT_OBJECT_DN_B};
                        SaAisErrorT slavePbeRtReply = SA_AIS_OK;
@@ -853,30 +858,46 @@ static void saImmOiAdminOperationCallbac
                        if(rc2B != SA_AIS_OK) {
                                if(rc2B == SA_AIS_ERR_NOT_EXIST) {
                                        LOG_IN("Got ERR_NOT_EXIST on atempt to 
set nostFlags towards slave PBE - ignoring");
+                                       rc = rc2B = SA_AIS_OK;
                                } else {
-                                       LOG_WA("Failed to update nostFlags 
towards slave PBE. Rc:%u - ignoring", rc2B);
+                                       LOG_NO("Failed to update nostFlags 
towards slave PBE. Rc:%u", rc2B);
+                                       rc = rc2B;
                                }
-                               rc2B = SA_AIS_OK;
                        } else if(slavePbeRtReply == SA_AIS_OK) {
                                LOG_IN("Slave PBE replied with OK on attempt to 
set nostFlags");
                        } else {
-                               LOG_WA("Slave PBE replied with error '%u' on 
attempt to set nostFlags", slavePbeRtReply);
+                               LOG_WA("Slave PBE replied with error %u on 
attempt to set nostFlags", slavePbeRtReply);
+                               rc = slavePbeRtReply;
                        }
                }
-               
+
+               if(sPbe2B && (flagsToSet == OPENSAF_IMM_FLAG_2PBE1_ALLOW)) {
+                       LOG_WA("Attempt to togle *ON* value x%x in nostdFlags 
not allowed when PBE slave is running.",
+                               OPENSAF_IMM_FLAG_2PBE1_ALLOW);
+                       rc = SA_AIS_ERR_BAD_OPERATION;
+               }
+
+
                if(rc == SA_AIS_OK) {
                        sNoStdFlags |= flagsToSet;
-                       LOG_NO("NOSTD FLAGS switched on result:%u", 
sNoStdFlags);
-               }
+                       LOG_NO("NOSTD FLAGS value 0x%x switched ON 
result:0x%x", flagsToSet, sNoStdFlags);
+                       if(!sPbe2B) { /* Only primary PBE updates the cached 
RTA. */
+                               rc = saImmOiRtObjectUpdate_2(immOiHandle, 
&myObj, attrMods);
+                               if(rc != SA_AIS_OK) { 
+                                       /* Should never get TRY_AGAIN here. RTA 
update is always accepted,
+                                          Except if local IMMND goes down, but 
then this PBE will go down also.
+                                        */
+                                       sNoStdFlags &= ~flagsToSet; /* restore 
the flag value */
+                                       LOG_WA("Update of cached attr %s in %s 
failed, rc=%u",
+                                               attMod.modAttr.attrName, (char 
*) myObj.value, rc);
+                                       /* ABT shoot down or undo for slave ?
+                                          The flags value in the slave is not 
really used.
+                                          Slave only "becomes" primary by 
process restart,
+                                          which will get noStdFlags from imm 
cached RTA.
+                                        */
+                               }
+                       }
 
-               if(rc == SA_AIS_OK && !sPbe2B) { /* Only primary PBE updates 
the cached RTA. */
-                       rc = saImmOiRtObjectUpdate_2(immOiHandle, &myObj, 
attrMods);
-                       if(rc != SA_AIS_OK) {
-                               sNoStdFlags &= ~flagsToSet; /* restore the flag 
value */
-                               LOG_ER("Update of cached attr %s in %s failed, 
rc=%u",
-                                       attMod.modAttr.attrName, (char *) 
myObj.value, rc);
-                               /* ABT need to shoot down or undo for slave! */
-                       }
                }
 
                rc = immutil_saImmOiAdminOperationResult(immOiHandle, 
invocation, rc);
@@ -892,7 +913,7 @@ static void saImmOiAdminOperationCallbac
                
                if(!param || (param->paramType != SA_IMM_ATTR_SAUINT32T) ||
                        strcmp(param->paramName, (char *) 
OPENSAF_IMM_ATTR_NOSTD_FLAGS)) {
-                       LOG_IN("Incorrect parameter to NostdFlags-OFF, should 
be 'flags:SA_UINT32_T:nnnn");
+                       LOG_IN("Incorrect parameter to NostdFlags-OFF, should 
be 'opensafImmNostdFlags:SA_UINT32_T:nnnn'");
                        rc = immutil_saImmOiAdminOperationResult(immOiHandle, 
invocation, SA_AIS_ERR_INVALID_PARAM);
                        goto fail;
                }
@@ -900,7 +921,7 @@ static void saImmOiAdminOperationCallbac
                SaUint32T flagsToUnSet = (*((SaUint32T *) param->paramBuffer));
 
                if(sPbe2 && !sPbe2B) {
-                       /* Forward nost flag off to slave PBE. */
+                       /* Forward nost flag OFF to slave PBE. */
                        SaAisErrorT rc2B = SA_AIS_OK;
                        SaNameT slavePbeRtObjName = 
{sizeof(OPENSAF_IMM_PBE_RT_OBJECT_DN_B), OPENSAF_IMM_PBE_RT_OBJECT_DN_B};
                        SaAisErrorT slavePbeRtReply = SA_AIS_OK;
@@ -908,30 +929,42 @@ static void saImmOiAdminOperationCallbac
                                params, &slavePbeRtReply, SA_TIME_ONE_SECOND * 
10);
                        if(rc2B != SA_AIS_OK) {
                                if(rc2B == SA_AIS_ERR_NOT_EXIST) {
-                                       LOG_IN("Got ERR_NOT_EXIST on atempt to 
un-set nostFlags towards slave PBE");
+                                       LOG_IN("Got ERR_NOT_EXIST on atempt to 
un-set nostFlags towards slave PBE - ignoring");
+                                       rc = rc2B = SA_AIS_OK;
                                } else {
-                                       LOG_WA("Failed to update nostFlags 
towards slave PBE. Rc:%u", rc2B);
+                                       if(flagsToUnSet == 
OPENSAF_IMM_FLAG_2PBE1_ALLOW) {
+                                               LOG_NO("Failed to un-set flag 
2PBE1_ALLOW towards slave PBE. Rc:%u - overriding",
+                                                       rc2B);
+                                               rc = rc2B = SA_AIS_OK;
+                                       } else {
+                                               LOG_WA("Failed to update 
nostFlags towards slave PBE. Rc:%u", rc2B);
+                                               rc = rc2B;
+                                       }
                                }
                                rc2B = SA_AIS_OK;
                        } else if(slavePbeRtReply == SA_AIS_OK) {
                                LOG_IN("Slave PBE replied with OK on attempt to 
un-set nostFlags");
                        } else {
                                LOG_WA("Slave PBE replied with error '%u' on 
attempt to un-set nostFlags", slavePbeRtReply);
+                               rc = slavePbeRtReply;
                        }
                }
 
                if(rc == SA_AIS_OK) {
                        sNoStdFlags &= ~flagsToUnSet;
-                       LOG_NO("NOSTD FLAGS switched off result:%u", 
sNoStdFlags);
-               }
-
-               if(rc == SA_AIS_OK && !sPbe2B) { /* Only primary PBE updates 
the cached RTA. */
-                       rc = saImmOiRtObjectUpdate_2(immOiHandle, &myObj, 
attrMods);
-                       if(rc != SA_AIS_OK) {
-                               sNoStdFlags |= flagsToUnSet; /* restore the 
flag value */
-                               LOG_WA("Update of cached attribute attr %s in 
%s failed, rc=%u",
-                                       attMod.modAttr.attrName, (char *) 
myObj.value, rc);
-                               /* ABT need to shoot down or undo! slave*/
+                       LOG_NO("NOSTD FLAGS value 0x%x switched OFF 
result:0x%x", flagsToUnSet, sNoStdFlags);
+                       if(!sPbe2B) { /* Only primary PBE updates the cached 
RTA. */
+                               rc = saImmOiRtObjectUpdate_2(immOiHandle, 
&myObj, attrMods);
+                               if(rc != SA_AIS_OK) {
+                                       sNoStdFlags |= flagsToUnSet; /* restore 
the flag value */
+                                       LOG_WA("Update of cached attribute attr 
%s in %s failed, rc=%u",
+                                               attMod.modAttr.attrName, (char 
*) myObj.value, rc);
+                                       /* ABT shoot down or undo for slave ?
+                                          The flags value in the slave is not 
really used.
+                                          Slave only "becomes" primary by 
process restart,
+                                          which will get noStdFlags from imm 
cached RTA.
+                                        */
+                               }
                        }
                }
 
@@ -1015,6 +1048,9 @@ static void saImmOiAdminOperationCallbac
                        rc = sqlite_prepare_ccb(immOiHandle, ccbId, 
ccbUtilOperationData);
                }
                //if(rc == SA_AIS_OK && ccbId == 4) exit(1); /* Fault inject. */
+       } else  if(opId == OPENSAF_IMM_BAD_OP_BOUNCE) {
+               LOG_WA("ERR_BAD_OPERATION: bounced in PBE");
+               rc = immutil_saImmOiAdminOperationResult(immOiHandle, 
invocation, SA_AIS_ERR_BAD_OPERATION);
        } else {
                LOG_WA("Invalid operation ID %llu", (SaUint64T) opId);
                rc = immutil_saImmOiAdminOperationResult(immOiHandle, 
invocation, SA_AIS_ERR_INVALID_PARAM);
@@ -1727,7 +1763,7 @@ SaAisErrorT pbe_daemon_imm_init(SaImmHan
        SaNameT pbeRtObjNameA = 
{sizeof(OPENSAF_IMM_PBE_RT_OBJECT_DN_A),OPENSAF_IMM_PBE_RT_OBJECT_DN_A};
        SaNameT pbeRtObjNameB = 
{sizeof(OPENSAF_IMM_PBE_RT_OBJECT_DN_B),OPENSAF_IMM_PBE_RT_OBJECT_DN_B};
 
-       const SaNameT* admOwnNames[] = 
{(sPbe2B)?(&pbeRtObjNameB):(&pbeRtObjNameA), NULL};
+       const SaNameT* admOwnNames[] = 
{(sPbe2B)?(&pbeRtObjNameB):(&pbeRtObjNameA), &myParent, NULL};
 
        TRACE_ENTER();
 

------------------------------------------------------------------------------
November Webinars for C, C++, Fortran Developers
Accelerate application performance with scalable programming models. Explore
techniques for threading, error checking, porting, and tuning. Get the most 
from the latest Intel processors and coprocessors. See abstracts and register
http://pubads.g.doubleclick.net/gampad/clk?id=60136231&iu=/4140/ostg.clktrk
_______________________________________________
Opensaf-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensaf-devel

Reply via email to