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[] = {¶m, 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
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensaf-devel