osaf/libs/agents/saf/imma/imma_oi_api.c              |   6 -
 osaf/services/saf/immsv/README                       |  84 +++++++++++++++++++-
 osaf/services/saf/immsv/immnd/ImmModel.cc            |  14 +++
 osaf/tools/safimm/immadm/imm_admin.c                 |   7 +-
 tests/immsv/implementer/test_SaImmOiAdminOperation.c |  34 ++++++-
 5 files changed, 131 insertions(+), 14 deletions(-)


This enhancement (#799) extends the scope of the existing OpenSAF API
for administrative-operations such that it supports the direct invocation
of admin-operations on an implementer or applier.
See the included patch of: osaf/services/saf/immsv/README for details.

diff --git a/osaf/libs/agents/saf/imma/imma_oi_api.c 
b/osaf/libs/agents/saf/imma/imma_oi_api.c
--- a/osaf/libs/agents/saf/imma/imma_oi_api.c
+++ b/osaf/libs/agents/saf/imma/imma_oi_api.c
@@ -901,12 +901,6 @@ static SaAisErrorT admin_op_result_commo
                TRACE_1("Reactive ressurect of handle %llx succeeded", 
immOiHandle);
        }
 
-       if (cl_node->isApplier) {
-               rc = SA_AIS_ERR_BAD_HANDLE;
-               TRACE_2("ERR_BAD_HANDLE: The SaImmOiHandleT is associated with 
an >>applier<< name");
-               goto stale_handle;
-       }
-
        if(isA2bCall && !(cl_node->isImmA2b)) {
                rc = SA_AIS_ERR_VERSION;
                TRACE_2("ERR_VERSION: saImmOmAdminOperationInvoke_o2 only 
supported for "
diff --git a/osaf/services/saf/immsv/README b/osaf/services/saf/immsv/README
--- a/osaf/services/saf/immsv/README
+++ b/osaf/services/saf/immsv/README
@@ -1758,16 +1758,96 @@ incremental validation. This can be achi
 it then replaying the same operations (that validated), followed by adding
 more operations. Replay is necessary because the OIs ccb-protocol can only
 cope with one invocation of validation (completed callback) for any given
-ccb-id. Another possible us is in integrating IMM transaction commit
+ccb-id. Another possible use is in integrating IMM transaction commit
 with the commit of some other transaction handling system. By validating
 without committing, the risk is significantly reduced that a final
 commit/apply will fail. The invocation of saImmOmCcbApply after a 
-successfull invocation of saImmOmCcbValidate can still fail/abort
+successfull invocation of saImmOmCcbValidate can still fail/abort,
 but only due to resource problems (such as server crash or filesystem
 unavailability). 
 
 This is a blocking syncronous call.
 
+
+Allow admin-operations directly targeting an implementer or applier (4.5)
+======================================================================
+https://sourceforge.net/p/opensaf/tickets/799/
+
+
+The existing IMM admin-operation API in OpenSAF:
+
+    saImmOmAdminOperationInvoke_2()
+    saImmOmAdminOperationInvoke_o2()
+    saImmOmAdminOperationInvokeAsync_2()
+    SaImmOmAdminOperationInvokeCallbackT()
+    aImmOmAdminOperationInvokeCallbackT_o2()
+
+    SaImmOiAdminOperationCallbackT_2()
+    saImmOiAdminOPerationResult()
+    saImmOiAdminOperationResult_o2()
+
+allows OM clients to invoke procedural requests directed at an imm object.
+The OM client needs to have an admin-owner handle associated with an 
admin-owner
+name that matches the admin-owner for the object. The actual target/receiver of
+the admin-operation is really the implementer/OI registered for the object or
+class. The object that anchors the request is effectively a parameter in the
+request to the OI.
+
+This enhancement (#799) does not add any new API. It extends the allowed scope
+for the existing admin-operation API to cover the case where the target is an 
OI
+directly. Instead of supplying the DN of an object as the address/target, an
+implementer-name is provided as the address/target. This allows the OM client 
to
+invoke admin-operations directly and explicitly on an OI. The implementer-name
+is used as a proxy for the object-name in the admin-operation API.
+
+Because the extended scope does not require the addition of any new API, access
+to this extension is not based on the handle version used. But the enhancement
+is introduced in OpenSAF release 4.5 and thus only available in that release or
+later releases. 
+
+The om-side admin-operation-invoke call takes an admin-owner-handle as 
argument.
+The admin-owner handle needs to be an initialized handle and it must set the
+admin-owner-name to be the *same* as the implementer-name. This may seem 
peculiar
+and unnecessary. But it serves both as a confirmation that the OM client has 
not
+made some mistake in using the new extended scope; and as a possible future
+entry point for authorizing admin-operation access directly targeting the OI. 
+
+The main benefit of this extension of scope, is that it allows a simple way for
+applications to set up cluster scoped remote procedure call communication, 
where the
+request arives FEVS-synchronously at the target. FEVS is the cluster 
synchronized
+messaging mechanism used by the Immsv (see earlier in this README).
+
+The receiver process only needs to register as an implementer or applier with 
IMM.
+In many cases the receiving process has done this anyway for other reasons.
+The sender only needs to know the name of the implementer/applier, the 
operation-id
+and expected arguments for the call. For this extended scope usage, the OI 
does not
+necessarily need to be the real implementer/OI for *any* imm object at all.
+
+Another use case is that it allows an om-client to communicate with (or probe) 
an
+OI/applier as such. An OI may be the OI for many objects and classes. In some 
cases,
+requests for information, or requests for adjustments in behavior of the 
OI/applier
+are generic and not associated with any specific object. For exaple, 
statistics or
+resource utilization data, last processed ccb, for the OI or Applier.
+
+Appliers are only listeners/trackers of ccb changes. An applier is never 
reachable
+via any *regular* admin-op invoked via some object. This since the applier 
will never
+be *the* OI for any object. But this enhancement allows an OM client to 
communicate
+directly also with appliers. This can for example be usefull if a main-OI needs
+an applier to read the before-ccb-commit versions of objects being changed in 
a CCB.
+The main OI can achieve this by sending a synchrnous admin-op to that applier 
from
+inside the completed callback for the main OI. Because the main-OI has not 
returned
+from the completed callback, the apply of that CCB is suspended waiting on the 
reply
+on the completed callback. Once the applier has read the before-image data, 
from
+inside the admin-op callback, it replies on the admin-op towards the main OI. 
The
+main OI can then finish the validation and reply to the immsv. Note that the 
main OI
+is in this example using both the OI and the OM API concurrently.
+
+One note of warning. Care needs to be taken when using *synchronous* 
admin-operations 
+not to create deadlock cycles between the involved processes. Any such 
deadlock will
+be resolved by the timeout of the synchronous admin-ops, so the problem would 
be lack
+of progress on some task, not a permanently hung set of processes. 
+
+
 ----------------------------------------
 DEPENDENCIES
 ============
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
@@ -10067,6 +10067,7 @@ SaAisErrorT ImmModel::adminOperationInvo
     
     AdminOwnerInfo* adminOwner = 0;
     ObjectInfo* object = 0;
+    struct ObjectInfo dummyObject; /* Constructor zeroes members of stack 
allocated object */
     
     ImplementerEvtMap::iterator iem;
     AdminOwnerVector::iterator i2;
@@ -10112,6 +10113,18 @@ SaAisErrorT ImmModel::adminOperationInvo
             TRACE_7("Bouncing special preload admin-op");
             err = SA_AIS_ERR_REPAIR_PENDING;
         } else {
+            dummyObject.mImplementer = findImplementer(objectName);
+            if(dummyObject.mImplementer) {
+                 /* Appears to be an admin-op directed at OI. 
+                    Verify that admo-name matches impl-name. */
+                if(objectName == adminOwner->mAdminOwnerName) {
+                    object = &dummyObject;
+                    goto fake_obj;
+                }
+                LOG_NO("ERR_NOT_EXIST: Admin-op on OI rejected. Implementer 
'%s' != adminowner '%s'",
+                       objectName.c_str(), 
adminOwner->mAdminOwnerName.c_str());
+            }
+
             TRACE_7("ERR_NOT_EXIST: object '%s' does not exist", 
objectName.c_str());
             err = SA_AIS_ERR_NOT_EXIST;
         }
@@ -10136,6 +10149,7 @@ SaAisErrorT ImmModel::adminOperationInvo
         }
     }
 
+ fake_obj:
     // Check for call on object implementer
     if(object->mImplementer && object->mImplementer->mNodeId) {
         *implConn = object->mImplementer->mConn;
diff --git a/osaf/tools/safimm/immadm/imm_admin.c 
b/osaf/tools/safimm/immadm/imm_admin.c
--- a/osaf/tools/safimm/immadm/imm_admin.c
+++ b/osaf/tools/safimm/immadm/imm_admin.c
@@ -395,9 +395,14 @@ int main(int argc, char *argv[])
 
                error = immutil_saImmOmAdminOwnerSet(ownerHandle, objectNames, 
SA_IMM_ONE);
                if (error != SA_AIS_OK) {
-                       if (error == SA_AIS_ERR_NOT_EXIST)
+                       if (error == SA_AIS_ERR_NOT_EXIST) {
+                               if(strcmp(adminOwnerName, (const char *) 
objectName.value)==0) {
+                                       fprintf(stderr, "AdminOwnerName == 
ImplementerName (%s) - Could be direct admin-op on OI\n", adminOwnerName);
+                                       goto retry;
+                               }
                                fprintf(stderr, "error - saImmOmAdminOwnerSet - 
object '%s' does not exist\n",
                                        objectName.value);
+                       }
                        else
                                fprintf(stderr, "error - saImmOmAdminOwnerSet 
FAILED: %s\n", saf_error(error));
                        exit(EXIT_FAILURE);
diff --git a/tests/immsv/implementer/test_SaImmOiAdminOperation.c 
b/tests/immsv/implementer/test_SaImmOiAdminOperation.c
--- a/tests/immsv/implementer/test_SaImmOiAdminOperation.c
+++ b/tests/immsv/implementer/test_SaImmOiAdminOperation.c
@@ -31,6 +31,9 @@ static SaAisErrorT immReturnValue;
 static SaAisErrorT operationReturnValue;
 static SaInvocationT userInvocation = 0xdead;
 
+static SaBoolT useImplementerNameAsTarget = SA_FALSE;
+static SaImmOiImplementerNameT implementerName = NULL;;
+
 /* SaImmAdminOperationError */
 static SaStringT adminOperationErrorString = NULL;
 static SaImmAdminOperationParamsT_2 adminOperationErrorParam = {
@@ -179,7 +182,7 @@ static void *objectImplementerThreadMain
 {
     struct pollfd fds[1];
     int ret;
-    const SaImmOiImplementerNameT implementerName = (SaImmOiImplementerNameT) 
__FUNCTION__;
+    implementerName = (SaImmOiImplementerNameT) __FUNCTION__;
     SaSelectionObjectT selObj;
     SaImmHandleT handle;
     const SaNameT *objectName = arg;
@@ -223,23 +226,34 @@ static SaAisErrorT om_admin_exec(SaAisEr
     SaImmHandleT handle;
     SaImmAdminOwnerHandleT ownerHandle;
     const SaNameT *objectNames[] = {objectName, NULL};
+    SaNameT localRdn = rdn;
     SaImmAdminOperationParamsT_2 param = {
         "TEST",
         SA_IMM_ATTR_SAUINT64T,
         &value
     };
     const SaImmAdminOperationParamsT_2 *params[] = {&param, NULL};
+    SaImmAdminOwnerNameT admoName = adminOwnerName;
 
     if (in_rc == SA_AIS_ERR_INVALID_PARAM)
         param.paramType = -1;
 
     TRACE_ENTER();
     safassert(saImmOmInitialize(&handle, NULL, &immVersion), SA_AIS_OK);
-    safassert(saImmOmAdminOwnerInitialize(handle, adminOwnerName, SA_TRUE, 
&ownerHandle), SA_AIS_OK);
-    safassert(saImmOmAdminOwnerSet(ownerHandle, objectNames, SA_IMM_SUBTREE), 
SA_AIS_OK);
+    if(useImplementerNameAsTarget) {
+        localRdn.length = strlen(implementerName);
+        assert(localRdn.length < 256);
+        strcpy((char *) localRdn.value, implementerName);
+        admoName = (char *) implementerName;
+    }
+
+    safassert(saImmOmAdminOwnerInitialize(handle, admoName, SA_TRUE, 
&ownerHandle), SA_AIS_OK);
+    if(!useImplementerNameAsTarget) {
+        safassert(saImmOmAdminOwnerSet(ownerHandle, objectNames, 
SA_IMM_SUBTREE), SA_AIS_OK);
+    }
 
     *imm_rc = saImmOmAdminOperationInvoke_2(
-        ownerHandle, &rdn, 0, operationId,
+        ownerHandle, &localRdn, 0, operationId,
         params, &rc, SA_TIME_ONE_SECOND);
 
     saImmOmAdminOwnerFinalize(ownerHandle); /* Tend to get timeout here with 
PBE */
@@ -306,8 +320,9 @@ void SaImmOiAdminOperation_01(void)
     safassert(saImmOmCcbApply(ccbHandle), SA_AIS_OK);
     safassert(saImmOmCcbFinalize(ccbHandle), SA_AIS_OK);
     safassert(saImmOmFinalize(immOmHandle), SA_AIS_OK);
+    useImplementerNameAsTarget = SA_FALSE;
 
-    assert(imm_rc == SA_AIS_OK);
+    if(imm_rc != SA_AIS_OK) {rc = imm_rc;}
     test_validate(rc, SA_AIS_OK);
     TRACE_LEAVE();
 }
@@ -1033,6 +1048,14 @@ done:
     TRACE_LEAVE();
 }
 
+
+void SaImmOiAdminOperation_13(void)
+{
+       useImplementerNameAsTarget = SA_TRUE;
+       SaImmOiAdminOperation_01();
+}
+
+
 __attribute__ ((constructor)) static void saImmOiInitialize_2_constructor(void)
 {
     test_suite_add(5, "Administrative Operations");
@@ -1048,5 +1071,6 @@ done:
     test_case_add(5, SaImmOiAdminOperation_10, "SaImmOiAdminOperation - 
SA_AIS_ERR_BAD_OPERATION, SaImmAdminOperationName");
     test_case_add(5, SaImmOiAdminOperation_11, "SaImmOiAdminOperation - 
SA_AIS_OK, SaImmAdminOperationName (first param) - async");
     test_case_add(5, SaImmOiAdminOperation_12, "SaImmOiAdminOperation - 
SA_AIS_OK, SaImmAdminOperationName (first param) - sync");
+    test_case_add(5, SaImmOiAdminOperation_13, "SaImmOiAdminOperation - 
SA_AIS_OK, Same as 5 1 but with implementername as target");
 }
 

------------------------------------------------------------------------------
"Accelerate Dev Cycles with Automated Cross-Browser Testing - For FREE
Instantly run your Selenium tests across 300+ browser/OS combos.  Get 
unparalleled scalability from the best Selenium testing platform available.
Simple to use. Nothing to install. Get started now for free."
http://p.sf.net/sfu/SauceLabs
_______________________________________________
Opensaf-devel mailing list
Opensaf-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/opensaf-devel

Reply via email to