When underlying file system is unresponsive to pbe write request, all IMM
requests that required to be persistent such as creating an IMM object or
creating an IMM class likely gets SA_AIS_ERR_TIMEOUT.

This changeset introduces two administrative operations which are provided to
let user inform IMM if the file system is unavailable or not. If the file
system is not available, IMM will return SA_AIS_ERR_TRY_AGAIN earlier to the
caller instead of SA_AIS_ERR_TIMEOUT.

Besides, a new IMM attribute, saImmFileSystemStatus, is added to
SaImmMngt class; the value shows the current status of the file system
according to IMM view.
---
 src/imm/README                                |  49 ++++++-
 .../management/test_saImmOmClassCreate_2.c    | 136 ++++++++++++++++++
 src/imm/common/immsv_api.h                    |   5 +-
 src/imm/config/immsv_classes.xml              |   7 +
 src/imm/immnd/ImmModel.cc                     |  91 ++++++++++--
 src/imm/immnd/ImmModel.h                      |   1 +
 src/imm/immnd/immnd_evt.c                     |  11 +-
 src/imm/immnd/immnd_init.h                    |   1 +
 8 files changed, 288 insertions(+), 13 deletions(-)

diff --git a/src/imm/README b/src/imm/README
index 132ee0ac0..8e91b534c 100644
--- a/src/imm/README
+++ b/src/imm/README
@@ -2969,7 +2969,7 @@ attribute in the object:
 
 The following is the shell command:
 
-        immadm -o 1 -p opensafImmNostdFlags:SA_UINT32_T:1024 \
+        immadm -o 1 -p opensafImmNostdFlags:SA_UINT32_T:512 \
            opensafImm=opensafImm,safApp=safImmService
 
 This will set bit 10 of the 'opensafImmNostdFlags' runtime attribute inside 
the immsv.
@@ -3027,7 +3027,6 @@ 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/
@@ -3046,6 +3045,52 @@ back-end database from one in memory to keep them both 
consistent.
 
 immadm -o 303 safRdn=immManagement,safApp=safImmService
 
+Return try-again on write requests while file system is unavailable
+===================================================================
+https://sourceforge.net/p/opensaf/tickets/3019
+
+When underlying file system is unresponsive to pbe write request, all IMM
+requests that required to be persistent such as creating an IMM object or
+creating an IMM class likely gets SA_AIS_ERR_TIMEOUT.
+
+Since OpenSAF version 5.19.06, IMM introduces two new administrative operations
+which are used to inform IMM if the file system is unavailable or not. If the
+file system is not available for write, IMM will return SA_AIS_ERR_TRY_AGAIN
+earlier to the caller instead of SA_AIS_ERR_TIMEOUT.
+
+Operation ID 400 is used to inform the file system is unavailable:
+ immadm -o 400 safRdn=immManagement,safApp=safImmService
+
+and operation ID 401 is used to inform the file system is back:
+ immadm -o 401 safRdn=immManagement,safApp=safImmService
+
+Besides, a new runtime IMM attribute, saImmFileSystemStatus, is added to
+SaImmMngt class; the value shows the current status of the file system:
+saImmFileSystemStatus = 0 means the file system is unavailable and
+saImmFileSystemStatus = 1 means the file system is fine for write.
+
+Fetching the value of that attribute, other services or applications that
+have activities to read/write data from/to the file system may benefit as well.
+
+Note that, to use this new feature, bit 11 must be set in opensafImmNostdFlags.
+
+The following is the shell command to set the 11st bit:
+ immadm -o 1 -p opensafImmNostdFlags:SA_UINT32_T:1024 \
+               opensafImm=opensafImm,safApp=safImmService
+
+In summary:
+ Bit 1 controls schema (imm class) changes allowed or not (normally off/0).
+ Bit 2 controls OpenSAF4.1 protocols allowed or not (normally on/1).
+ Bit 3 controls OpenSAF4.3 protocols allowed or not (normally on/1).
+ Bit 4 controls 2PBE oneSafe2PBE, see 2PBE feature in OpenSAF4.4 above 
(normally off/0).
+ Bit 5 controls OpenSAF4.5 protocols allowed or not (normally on/1).
+ Bit 6 controls OpenSAF4.6 protocols allowed or not (normally on/1).
+ Bit 7 controls OpenSAF4.7 protocols allowed or not (normally on/1).
+ Bit 8 controls OpenSAF5.0 protocols allowed or not (normally on/1).
+ Bit 9 controls OpenSAF5.1 protocols allowed or not (normally on/1).
+ Bit 10 controls OpenSAF5.17.11 protocols allowed or not (normally on/1).
+ Bit 11 controls OpenSAF5.19.06 protocols allowed or not (normally on/1).
+
 ----------------------------------------
 DEPENDENCIES
 ============
diff --git a/src/imm/apitest/management/test_saImmOmClassCreate_2.c 
b/src/imm/apitest/management/test_saImmOmClassCreate_2.c
index f43884e1b..9e12f4f61 100644
--- a/src/imm/apitest/management/test_saImmOmClassCreate_2.c
+++ b/src/imm/apitest/management/test_saImmOmClassCreate_2.c
@@ -16,6 +16,7 @@
  */
 
 #include "imm/apitest/immtest.h"
+#include "imm/common/immsv_api.h"
 
 void saImmOmClassCreate_2_01(void)
 {
@@ -709,6 +710,7 @@ void saImmOmClassCreate_SchemaChange_2_02(void)
        /*
         * [CONFIG_CLASS] Add default value to default-removed attribute
         */
+
        int schemaChangeEnabled = enableSchemaChange();
        safassert(immutil_saImmOmInitialize(&immOmHandle, &immOmCallbacks, 
&immVersion),
                  SA_AIS_OK);
@@ -1534,6 +1536,133 @@ void saImmOmClassCreate_SchemaChange_2_18(void)
                disableSchemaChange();
 }
 
+/* Here are test cases to verify:
+   1) SA_AIS_ERR_TRY_AGAIN is returned on IMM class creation request if file
+   system is unavailable which is informed to IMM via admop id 400, and also
+   ensure saImmFileSystemStatus attribute of SaImmMgnt class must be zero.
+   Note that, the test is only valid if PBE is enabled, otherwise we expect
+   getting SA_AIS_OK instead.
+
+   2) SA_AIS_OK is returned on IMM class creation request if the file system
+   is back which is informed to IMM via admop id 401, and also ensure that
+   saImmFileSystemStatus attribute of SaImmMgnt class must be equal to one.
+*/
+const char mgmt_object[] = "safRdn=immManagement,safApp=safImmService";
+static void updateFileSystemStatus(uint64_t operation_id)
+{
+       SaImmHandleT myOmHandle;
+       SaImmAdminOwnerHandleT ownerHandle;
+       const SaImmAdminOwnerNameT adminOwnerName = "imm_test";
+       SaNameT objectName;
+       const SaNameT *objectNames[] = {&objectName, NULL};
+       const SaImmAdminOperationParamsT_2 *params[] = {NULL};
+       SaAisErrorT operation_return_value;
+
+       objectName.length = strlen(mgmt_object);
+       strncpy((char *)objectName.value, mgmt_object,
+               objectName.length);
+
+       safassert(immutil_saImmOmInitialize(&myOmHandle, NULL, &immVersion),
+                 SA_AIS_OK);
+       safassert(immutil_saImmOmAdminOwnerInitialize(myOmHandle,
+                                                     adminOwnerName,
+                                                     SA_TRUE, &ownerHandle),
+                 SA_AIS_OK);
+       safassert(immutil_saImmOmAdminOwnerSet(ownerHandle, objectNames,
+                                              SA_IMM_ONE),
+                 SA_AIS_OK);
+       safassert(immutil_saImmOmAdminOperationInvoke_2(
+                     ownerHandle, &objectName, 0, operation_id,
+                     params, &operation_return_value, SA_TIME_ONE_MINUTE),
+                 SA_AIS_OK);
+       safassert(immutil_saImmOmFinalize(myOmHandle), SA_AIS_OK);
+}
+
+uint32_t fetchAttributeValue(const char* attribute_name)
+{
+       SaImmHandleT myOmHandle;
+       SaImmAccessorHandleT accessorHandle;
+       SaImmAttrValuesT_2 **attributes;
+       SaImmAttrNameT attributeNames[] = {
+               (SaImmAttrNameT)attribute_name,
+               NULL
+       };
+       SaNameT objectName;
+       objectName.length = strlen(mgmt_object);
+       strncpy((char *)objectName.value, mgmt_object,
+               objectName.length);
+
+       safassert(immutil_saImmOmInitialize(&myOmHandle, NULL,
+                                           &immVersion),
+                 SA_AIS_OK);
+       safassert(immutil_saImmOmAccessorInitialize(myOmHandle,
+                                                   &accessorHandle),
+                 SA_AIS_OK);
+       safassert(immutil_saImmOmAccessorGet_2(accessorHandle, &objectName,
+                                              attributeNames, &attributes),
+                 SA_AIS_OK);
+
+       uint32_t attribute_value = *(uint32_t *)(attributes[0]->attrValues[0]);
+       safassert(immutil_saImmOmFinalize(myOmHandle), SA_AIS_OK);
+       return attribute_value;
+}
+
+bool pbeEnabled(void)
+{
+       return fetchAttributeValue("saImmRepositoryInit") == 1;
+}
+
+void saImmOmClassCreate_with_fs_unavailable(void)
+{
+       const SaImmClassNameT className = (SaImmClassNameT) "TestClass";
+       SaImmAttrDefinitionT_2 attr1 = {
+               "rdn", SA_IMM_ATTR_SANAMET,
+               SA_IMM_ATTR_RUNTIME | SA_IMM_ATTR_RDN | SA_IMM_ATTR_CACHED,
+               NULL};
+       const SaImmAttrDefinitionT_2 *attrDefinitions[] = {&attr1, NULL};
+
+       updateFileSystemStatus(SA_IMM_ADMIN_FS_UNAVAILABLE);
+       safassert(fetchAttributeValue("saImmFileSystemStatus"), 0);
+
+       safassert(immutil_saImmOmInitialize(&immOmHandle, NULL, &immVersion),
+                 SA_AIS_OK);
+       rc = saImmOmClassCreate_2(immOmHandle, className, SA_IMM_CLASS_RUNTIME,
+                                 attrDefinitions);
+       if (pbeEnabled()) {
+               test_validate(rc, SA_AIS_ERR_TRY_AGAIN);
+       } else {
+               test_validate(rc, SA_AIS_OK);
+               safassert(immutil_saImmOmClassDelete(immOmHandle, className),
+                         SA_AIS_OK);
+       }
+       safassert(immutil_saImmOmFinalize(immOmHandle), SA_AIS_OK);
+       updateFileSystemStatus(SA_IMM_ADMIN_FS_AVAILABLE);
+       safassert(fetchAttributeValue("saImmFileSystemStatus"), 1);
+}
+
+void saImmOmClassCreate_with_fs_available(void)
+{
+       const SaImmClassNameT className = (SaImmClassNameT) "TestClass";
+       SaImmAttrDefinitionT_2 attr1 = {
+               "rdn", SA_IMM_ATTR_SANAMET,
+               SA_IMM_ATTR_RUNTIME | SA_IMM_ATTR_RDN | SA_IMM_ATTR_CACHED,
+               NULL};
+       const SaImmAttrDefinitionT_2 *attrDefinitions[] = {&attr1, NULL};
+
+       updateFileSystemStatus(SA_IMM_ADMIN_FS_AVAILABLE);
+       safassert(fetchAttributeValue("saImmFileSystemStatus"), 1);
+
+       safassert(immutil_saImmOmInitialize(&immOmHandle, &immOmCallbacks,
+                                           &immVersion),
+                 SA_AIS_OK);
+       rc = immutil_saImmOmClassCreate_2(immOmHandle, className,
+                                         SA_IMM_CLASS_RUNTIME,
+                                         attrDefinitions);
+       test_validate(rc, SA_AIS_OK);
+       safassert(immutil_saImmOmClassDelete(immOmHandle, className), 
SA_AIS_OK);
+       safassert(immutil_saImmOmFinalize(immOmHandle), SA_AIS_OK);
+}
+
 extern void saImmOmClassDescriptionGet_2_01(void);
 extern void saImmOmClassDescriptionGet_2_02(void);
 extern void saImmOmClassDescriptionGet_2_03(void);
@@ -1724,4 +1853,11 @@ __attribute__((constructor)) static void 
saImmOmInitialize_constructor(void)
        test_case_add(
            2, saImmOmClassCreate_SchemaChange_2_18,
            "SchemaChange - SA_AIS_OK, Remove STRONG_DEFAULT flag from an 
attribute");
+       test_case_add(
+               2, saImmOmClassCreate_with_fs_unavailable,
+               "FileSystemUnavailable - SA_AIS_ERR_TRY_AGAIN, create class 
while FS is unavailable");
+       test_case_add(
+               2, saImmOmClassCreate_with_fs_available,
+               "FileSystemAvailable - SA_AIS_OK, create class while FS is 
available");
+
 }
diff --git a/src/imm/common/immsv_api.h b/src/imm/common/immsv_api.h
index e6d613705..3ab3892d1 100644
--- a/src/imm/common/immsv_api.h
+++ b/src/imm/common/immsv_api.h
@@ -151,6 +151,7 @@ typedef enum {
 #define OPENSAF_IMM_FLAG_PRT50_ALLOW 0x00000080
 #define OPENSAF_IMM_FLAG_PRT51_ALLOW 0x00000100
 #define OPENSAF_IMM_FLAG_PRT51710_ALLOW 0x00000200
+#define OPENSAF_IMM_FLAG_PRT51906_ALLOW 0x00000800
 
 #define OPENSAF_IMM_SERVICE_NAME "safImmService"
 
@@ -159,7 +160,9 @@ typedef enum {
   SA_IMM_ADMIN_INIT_FROM_FILE = 100, /* Non standard, force PBE disable. */
   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
+  SA_IMM_ADMIN_REGENERATE_PBE_DB = 303,
+  SA_IMM_ADMIN_FS_UNAVAILABLE = 400,
+  SA_IMM_ADMIN_FS_AVAILABLE = 401,
 } SaImmMngtAdminOperationT;
 
 /*
diff --git a/src/imm/config/immsv_classes.xml b/src/imm/config/immsv_classes.xml
index 6c20fecda..c6f448e82 100644
--- a/src/imm/config/immsv_classes.xml
+++ b/src/imm/config/immsv_classes.xml
@@ -46,5 +46,12 @@
                        <category>SA_CONFIG</category>
                        <flag>SA_WRITABLE</flag>
                </attr>
+               <attr>
+                       <name>saImmFileSystemStatus</name>
+                       <type>SA_UINT32_T</type>
+                       <category>SA_RUNTIME</category>
+                       <category>SA_RUNTIME</category>
+                       <flag>SA_CACHED</flag>
+               </attr>
        </class>
 </imm:IMM-contents>
diff --git a/src/imm/immnd/ImmModel.cc b/src/imm/immnd/ImmModel.cc
index 4bc3b8522..2cf2649cf 100644
--- a/src/imm/immnd/ImmModel.cc
+++ b/src/imm/immnd/ImmModel.cc
@@ -594,7 +594,7 @@ static const std::string immManagementDn(
     "safRdn=immManagement,safApp=safImmService");
 static const std::string saImmRepositoryInit("saImmRepositoryInit");
 static const std::string saImmOiTimeout("saImmOiTimeout");
-
+static const std::string saImmFileSystemStatus("saImmFileSystemStatus");
 static SaImmRepositoryInitModeT immInitMode = SA_IMM_INIT_FROM_FILE;
 static bool sRegenerateDb = false;
 
@@ -609,6 +609,8 @@ static bool sAbortNonCriticalCcbs =
 static SaUint32T sTerminatedCcbcount = 0; /* Terminated ccbs count. calculated
                                              at cleanTheBasement  for every
                                              second*/
+// Show the status of underlying file system.
+static bool sFileSystemAvailable = true;
 
 struct AttrFlagIncludes {
   explicit AttrFlagIncludes(SaImmAttrFlagsT attrFlag) : mFlag(attrFlag) {}
@@ -1125,6 +1127,10 @@ bool immModel_protocol51710Allowed(IMMND_CB* cb) {
   return ImmModel::instance(&cb->immModel)->protocol51710Allowed();
 }
 
+bool immModel_protocol51906Allowed(IMMND_CB* cb) {
+  return ImmModel::instance(&cb->immModel)->protocol51906Allowed();
+}
+
 OsafImmAccessControlModeT immModel_accessControlMode(IMMND_CB* cb) {
   return ImmModel::instance(&cb->immModel)->accessControlMode();
 }
@@ -2360,6 +2366,7 @@ bool ImmModel::immNotWritable() {
 bool ImmModel::immNotPbeWritable(bool isPrtoClient) {
   SaUint32T dummyCon;
   unsigned int dummyNode;
+
   /* Not writable => Not persitent writable. */
   if (immNotWritable() || is_sync_aborting()) {
     return true;
@@ -2379,7 +2386,7 @@ bool ImmModel::immNotPbeWritable(bool isPrtoClient) {
   /* immInitMode == SA_IMM_KEEP_REPOSITORY */
   /* Check if PBE OI is available and making progress. */
 
-  if (!getPbeOi(&dummyCon, &dummyNode)) {
+  if (!getPbeOi(&dummyCon, &dummyNode) || !sFileSystemAvailable) {
     /* Pbe SHOULD be present but is NOT */
     return true;
   }
@@ -4023,6 +4030,27 @@ bool ImmModel::protocol51710Allowed() {
   return noStdFlags & OPENSAF_IMM_FLAG_PRT51710_ALLOW;
 }
 
+bool ImmModel::protocol51906Allowed() {
+  /* Assume that all nodes are running the same version when loading */
+  if (sImmNodeState == IMM_NODE_LOADING) {
+    return true;
+  }
+  ObjectMap::iterator oi = sObjectMap.find(immObjectDn);
+  if (oi == sObjectMap.end()) {
+    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();
+
+  return noStdFlags & OPENSAF_IMM_FLAG_PRT51906_ALLOW;
+}
+
 bool ImmModel::protocol41Allowed() {
   // TRACE_ENTER();
   ObjectMap::iterator oi = sObjectMap.find(immObjectDn);
@@ -5085,6 +5113,8 @@ SaAisErrorT ImmModel::adminOwnerDelete(SaUint32T ownerId, 
bool hard,
              flags when cluster is started/loaded or restarted/reloaded.
           */
           ObjectMap::iterator oi = sObjectMap.find(immObjectDn);
+          auto oi2 = sObjectMap.find(immManagementDn);
+
           if (oi == sObjectMap.end()) {
             LOG_ER("Failed to find object %s - loading failed",
                    immObjectDn.c_str());
@@ -5093,6 +5123,16 @@ SaAisErrorT ImmModel::adminOwnerDelete(SaUint32T 
ownerId, bool hard,
             err = SA_AIS_ERR_NOT_READY;
             goto done;
           }
+
+          if (oi2 == sObjectMap.end()) {
+            LOG_ER("Failed to find object %s - loading failed",
+                   immManagementDn.c_str());
+            /* Return special error up to immnd_evt so that NackToNid can be
+               sent before aborting. */
+            err = SA_AIS_ERR_NOT_READY;
+            goto done;
+          }
+
           ObjectInfo* immObject = oi->second;
           ImmAttrValueMap::iterator avi =
               immObject->mAttrValueMap.find(immAttrNostFlags);
@@ -5108,6 +5148,9 @@ SaAisErrorT ImmModel::adminOwnerDelete(SaUint32T ownerId, 
bool hard,
               immObject->mAttrValueMap.find(immMaxCcbs);
           ImmAttrValueMap::iterator avi5 =
               immObject->mAttrValueMap.find(immMinApplierTimeout);
+          auto mgnt_object = oi2->second;
+          auto fs_attr_it =
+              mgnt_object->mAttrValueMap.find(saImmFileSystemStatus);
 
           ImmAttrValue* valuep = (ImmAttrValue*)avi->second;
           unsigned int noStdFlags = valuep->getValue_int();
@@ -5134,6 +5177,14 @@ SaAisErrorT ImmModel::adminOwnerDelete(SaUint32T 
ownerId, bool hard,
           } else {
             noStdFlags |= OPENSAF_IMM_FLAG_PRT51710_ALLOW;
           }
+
+          if (fs_attr_it == immObject->mAttrValueMap.end()) {
+            LOG_NO("protocol51906 is not set for opensafImmNostdFlags because "
+                   "the new OpenSAF 5.19.06 attribute is not added to "
+                   "SaImmMngt class");
+          } else {
+            noStdFlags |= OPENSAF_IMM_FLAG_PRT51906_ALLOW;
+          }
           valuep->setValue_int(noStdFlags);
           LOG_NO("%s changed to: 0x%x", immAttrNostFlags.c_str(), noStdFlags);
           /* END Temporary code. */
@@ -12272,6 +12323,11 @@ SaAisErrorT ImmModel::accessorGet(const 
ImmsvOmSearchInit* req,
           // The attribute is cached and the OI is transiently detached
           op.addAttrValue(*j->second);
           checkAttribute = true;
+        } else if ((k->second->mFlags & SA_IMM_ATTR_CACHED) &&
+                    (objectName == immManagementDn) &&
+                    !(j->second->empty())) {
+          op.addAttrValue(*j->second);
+          checkAttribute = true;
         } else {
           checkAttribute = false;
         }
@@ -12844,6 +12900,11 @@ SaAisErrorT 
ImmModel::searchInitialize(ImmsvOmSearchInit* req,
                     // detached
                     op.addAttrValue(*j->second);
                     checkAttribute = true;
+                  } else if ((k->second->mFlags & SA_IMM_ATTR_CACHED) &&
+                             (objectName == immManagementDn) &&
+                             !(j->second->empty())) {
+                    op.addAttrValue(*j->second);
+                    checkAttribute = true;
                   } else {
                     checkAttribute = false;
                   }
@@ -13798,8 +13859,11 @@ SaAisErrorT ImmModel::admoImmMngtObject(const 
ImmsvOmAdminOperationInvoke* req,
   TRACE_ENTER();
   ObjectMap::iterator oi = sObjectMap.find(immManagementDn);
   if (oi == sObjectMap.end()) {
-    err = SA_AIS_ERR_NOT_EXIST;
-    goto done;
+    return SA_AIS_ERR_NOT_EXIST;
+  }
+
+  if (req->params != NULL) {
+    return SA_AIS_ERR_INVALID_PARAM;
   }
 
   immObject = oi->second;
@@ -13808,10 +13872,10 @@ SaAisErrorT ImmModel::admoImmMngtObject(const 
ImmsvOmAdminOperationInvoke* req,
   osafassert(!(avi->second->isMultiValued()));
   valuep = (ImmAttrValue*)avi->second;
 
-  if (req->params != NULL) {
-    err = SA_AIS_ERR_INVALID_PARAM;
-    goto done;
-  }
+  auto fs_attr_iter = immObject->mAttrValueMap.find(saImmFileSystemStatus);
+  osafassert(fs_attr_iter != immObject->mAttrValueMap.end());
+  auto fs_attr_value = fs_attr_iter->second;
+
 
   if (req->operationId == SA_IMM_ADMIN_EXPORT) { /* Standard */
     err = SA_AIS_ERR_NOT_SUPPORTED;
@@ -13833,13 +13897,22 @@ SaAisErrorT ImmModel::admoImmMngtObject(const 
ImmsvOmAdminOperationInvoke* req,
   } else if (req->operationId == SA_IMM_ADMIN_REGENERATE_PBE_DB) {
     LOG_NO("Re-generate the pbe database from one in memory.");
     sRegenerateDb = true;
+  } else if (req->operationId == SA_IMM_ADMIN_FS_AVAILABLE) {
+    LOG_NO("Received: immadm -o %u safRdn=immManagement,safApp=safImmService",
+           SA_IMM_ADMIN_FS_AVAILABLE);
+    sFileSystemAvailable = true;
+    fs_attr_value->setValue_int(1);
+  } else if (req->operationId == SA_IMM_ADMIN_FS_UNAVAILABLE) {
+    LOG_NO("Received: immadm -o %u safRdn=immManagement,safApp=safImmService",
+           SA_IMM_ADMIN_FS_UNAVAILABLE);
+    sFileSystemAvailable = false;
+    fs_attr_value->setValue_int(0);
   } else {
     LOG_NO("Invalid operation ID %llu, for operation on %s",
            (SaUint64T)req->operationId, immManagementDn.c_str());
     err = SA_AIS_ERR_INVALID_PARAM;
   }
 
-done:
   TRACE_LEAVE();
   return err;
 }
diff --git a/src/imm/immnd/ImmModel.h b/src/imm/immnd/ImmModel.h
index 65e20d305..0b54bfa1d 100644
--- a/src/imm/immnd/ImmModel.h
+++ b/src/imm/immnd/ImmModel.h
@@ -114,6 +114,7 @@ class ImmModel {
   bool protocol50Allowed();
   bool protocol51Allowed();
   bool protocol51710Allowed();
+  bool protocol51906Allowed();
   bool oneSafe2PBEAllowed();
   bool purgeSyncRequest(SaUint32T clientId);
   bool verifySchemaChange(const std::string& className, ClassInfo* oldClass,
diff --git a/src/imm/immnd/immnd_evt.c b/src/imm/immnd/immnd_evt.c
index 0415ebedf..adae1e15a 100644
--- a/src/imm/immnd/immnd_evt.c
+++ b/src/imm/immnd/immnd_evt.c
@@ -3822,8 +3822,17 @@ static SaAisErrorT immnd_fevs_local_checks(IMMND_CB *cb, 
IMMSV_FEVS *fevsReq,
 
        case IMMND_EVT_A2ND_IMM_ADMOP:
        case IMMND_EVT_A2ND_IMM_ADMOP_ASYNC:
-               /* No restrictions at cluster level. */
+       {
+               IMMSV_OM_ADMIN_OP_INVOKE *adm = 
&frwrd_evt.info.immnd.info.admOpReq;
+               bool fs_op = (adm->operationId == SA_IMM_ADMIN_FS_AVAILABLE ||
+                             adm->operationId == SA_IMM_ADMIN_FS_UNAVAILABLE);
+               if (!immModel_protocol51906Allowed(cb) && fs_op &&
+                   strcmp(adm->objectName.buf,
+                       "safRdn=immManagement,safApp=safImmService") == 0) {
+                       error = SA_AIS_ERR_TRY_AGAIN;
+               }
                break;
+       }
 
        case IMMND_EVT_A2ND_CLASS_CREATE:
                if (fevsReq->sender_count != 0x1) {
diff --git a/src/imm/immnd/immnd_init.h b/src/imm/immnd/immnd_init.h
index 58ed48329..9a3f70072 100644
--- a/src/imm/immnd/immnd_init.h
+++ b/src/imm/immnd/immnd_init.h
@@ -345,6 +345,7 @@ bool immModel_protocol45Allowed(IMMND_CB *cb);
 bool immModel_protocol46Allowed(IMMND_CB *cb);
 bool immModel_protocol47Allowed(IMMND_CB *cb);
 bool immModel_protocol50Allowed(IMMND_CB *cb);
+bool immModel_protocol51906Allowed(IMMND_CB *cb);
 bool immModel_oneSafe2PBEAllowed(IMMND_CB *cb);
 OsafImmAccessControlModeT immModel_accessControlMode(IMMND_CB *cb);
 const char *immModel_authorizedGroup(IMMND_CB *cb);
-- 
2.19.2



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

Reply via email to